AVR / C代码含义

时间:2015-02-17 07:40:24

标签: c microcontroller avr

我的一位同事向我提供了以下C AVR代码:

#include <avr/io.h> 
#include <stdlib.h>

#define byte uint8_t

byte button[8]; 
byte play[8];
byte licz;
byte pind_in;
uint16_t freq[8]= {3822, 3405, 3033, 2863, 2551, 2272, 2024, 1911}; 
uint32_t count[8];

int main (void)
{
  DDRD = 0; 
  PORTD = 0xff; 
  DDRB = 0b00000010; 

  while (1)
  {
    pind_in = PIND; 
    licz += 16;

    for (byte i = 0; i < 8; i++)
    {
      button[i] = !(pind_in&(1<<i));
      if ((button[i]) && (play[i] < 255))
        play[i]++;
      if ((!button[i]) && (!(licz)) && (play[i] > 0))
        play[i]-- ;

      count[i] += freq[i];
      if ((count[i] & (0x4000)) && (play[i]))
        PORTB = 0b00000010;
      else 
        PORTB = 0;
    }
  }
}

我理解它是基于AVR微控制器的声音生成,但是我无法确定为什么licz + = 16在无限循环中使用,以及其余部分背后的算法是什么? 。这里有人能解密吗?

2 个答案:

答案 0 :(得分:2)

我真的不知道你的AVR有什么联系,所以这只是受过教育的 在这里猜。 我们假设输出声音,而PORTB.2 == 1则输出,否则静音。

PORTB位设置为play[i] > 0play[i]时会增加button[i] play已设置,可能是外部按钮或其他内容 类似。释放按钮后,licz再次倒计时到零。 可能这会使声音比按下按钮的时间长一点。

licz变量使得向下计数变慢。每个第16个循环(假设 该字节== 8位),play将再次为零,并且会跳过递减的licz += 16;。例如,如果您将licz += 128;更改为{{1}},则会在每个第二个循环中跳过减少,使按钮释放后声音持续更长时间。

答案 1 :(得分:1)

我这样看:

#include <avr/io.h> 
#include <stdlib.h>
#define byte uint8_t
// frequency table for each used HW button (scaled to main loop timing)
uint16_t freq[8]= {3822,3405,3033,2863,2551,2272,2024,1911}; 
byte button[8];    // HW button state
byte play[8];      // amplitude ... realy there is just single amplitude output but this makes time hysterezis of sound to filter out the glitches
uint32_t count[8]; // counter for frequency generation
byte licz;         // just counter for hysterezis generation amplitude is increasing 16x faster then decreasing
byte pind_in;      // variable for HW buttons/key-press detection

int main(void)
   {
   // probably configuration of IO port of the MCU (was not specified...)
   DDRD= 0; 
   PORTD=0xff; 
   DDRB= 0b00000010; 
   // inf loop of main process
   while(1)
      {
      pind_in=PIND;  // read the HW buttons state
      licz+=16;
      for (byte i=0;i<8;i++) // loop through all buttons/frequencies
         {
         button[i]=!(pind_in&(1<<i));                           // extract button state on/off
         if (( button[i])&&          (play[i]<255)) play[i]++; // if keypressed increase amplitude up to max
         if ((!button[i])&&(!licz)&&(play[i]>  0)) play[i]--; // if not decrease amplitude until zero
         count[i]+=freq[i];                                      // update frequency generator counter
         // alternate the speaker/buzzer
         if ((count[i]&(0x4000))&&(play[i])) PORTB=0b00000010; else PORTB=0;
         }
      }
   }
}

此代码还有很多需要改进的地方

  • 不需要按钮[]
  • 为实际振幅和正弦波生成添加PWM
  • 为特定乐器添加wavetable
  • 通过计时器/计数器更好的计时
  • 以及更多