[Atmel] 用AtmelStudio6.2跑mega16例程(45)音阶发音

[复制链接]
989|0
 楼主| ddllxxrr 发表于 2014-11-3 19:22 | 显示全部楼层 |阅读模式
根据频率可得方波周期:t = 1/频率*1000000 (US)
由于所输出的t(US)周期方波中,高/低电平各占50%,因此定时器定时(计数)长度为Count = t/2,即Count=1000000/2/频率

本例中将TCCR1A与TCCR1B分别设为0x00与0x09它们共周将WGM1[3:0]设为0100,使T/C1工作于CTC模式(即OCR1A/B与TCNT1比较匹配时清零T/C1,TCCR1B = 0x09还将TCNT1计数时钟设为使用1分频的系统时钟.

Proteus仿真结果:


Studio6.2 编译通过的截图:


以下是程序清单:

  1. /*
  2. * GccApplication8.c
  3. *
  4. * Created: 2014-11-3 18:53:36
  5. *  Author: Administrator
  6. */

  7. #define F_CPU 1000000UL
  8. #include <avr/io.h>
  9. #include <avr/interrupt.h>
  10. #include <util/delay.h>
  11. #include <stdint.h>
  12. #define K1_DOWN() ((PINB & _BV(PB0)) == 0x00)
  13. #define SPK() (PORTD^=_BV(PD0))
  14. #define Enable_TIMER1_OCIE() (TIMSK |= _BV(OCIE1A))
  15. #define Disable_TIMER1_OCIE() (TIMSK &=~_BV(OCIE1A))

  16. const uint16_t TONE_FRQ[] = {0,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046};
  17.        
  18. int main()
  19. {
  20.         uint8_t i;
  21.         DDRB = 0x00; PORTB = 0xFF;
  22.         DDRD = 0xFF; PORTD = 0xFF;
  23.         TCCR1A = 0x00;
  24.         TCCR1B = 0x09;
  25.        
  26.         sei();
  27.         while(1)
  28.         {
  29.                 while(!K1_DOWN());
  30.                 while(K1_DOWN());
  31.                 for(i=1;i<16;i++)
  32.                 {
  33.                         OCR1A = F_CPU/2/TONE_FRQ[i];
  34.                         TCNT1 = 0;
  35.                         Enable_TIMER1_OCIE();
  36.                         _delay_ms(200);
  37.                         Disable_TIMER1_OCIE();
  38.                         _delay_ms(80);
  39.                           
  40.                 }
  41.         }
  42.        
  43. }       

  44. ISR(TIMER1_COMPA_vect)
  45. {
  46.    SPK();       
  47. }


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2404

主题

7002

帖子

68

粉丝
快速回复 在线客服 返回列表 返回顶部