根据频率可得方波周期: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();
}
|