打印
[Atmel]

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

[复制链接]
833|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
根据频率可得方波周期: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 编译通过的截图:


以下是程序清单:

/*
* GccApplication8.c
*
* Created: 2014-11-3 18:53:36
*  Author: Administrator
*/

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

const uint16_t TONE_FRQ[] = {0,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046};
       
int main()
{
        uint8_t i;
        DDRB = 0x00; PORTB = 0xFF;
        DDRD = 0xFF; PORTD = 0xFF;
        TCCR1A = 0x00;
        TCCR1B = 0x09;
       
        sei();
        while(1)
        {
                while(!K1_DOWN());
                while(K1_DOWN());
                for(i=1;i<16;i++)
                {
                        OCR1A = F_CPU/2/TONE_FRQ[i];
                        TCNT1 = 0;
                        Enable_TIMER1_OCIE();
                        _delay_ms(200);
                        Disable_TIMER1_OCIE();
                        _delay_ms(80);
                          
                }
        }
       
}       

ISR(TIMER1_COMPA_vect)
{
   SPK();       
}


相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2398

主题

6955

帖子

67

粉丝