[实验三]定时器的应用[实验目的]1.结合定时/计数器的应用,更深入的了解AVR中断系统原理,响应过程,以及中断服务程序的编写。
2.掌握定时器的基本应用,了解定时器的各种用途[基本实验内容]:根据需要给出电原理图和程序清单。
1.了解CTC的用途,通过定时器的CTC实现LED的定时闪烁,定时时间1S。
/*****************************************************Chip type : ATmega16Program type : ApplicationClock frequency : 4.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256*****************************************************/#include <mega16.h>bit time_1s_ok=0;int time_counter=0;interrupt [TIM0_COMP] void timer0_comp_isr(void){if(time_counter>=500){time_counter=0;time_1s_ok=1;}}void main(void){PORTC=0x01; // 显示控制I/O口初始化DDRC=0x01;TCCR0=0x0B; //内部时钟,64分频TCNT0=0x00;OCR0=0x7C;//OCR0=0x7c(124),(124+1)/62.5KHz=2msTIMSK=0x01; //允许T/C0比较比配中断#asm("sei")while (1){if(time_1s_ok){time_1s_ok=0;PORTC=~PORTC;}};}2.阅读器件手册,查阅定时器相关寄存器,通过使用定时器改写P188页的例6.7中的点阵LED箭头移动程序。
箭头运动速度保持与原来相同。
/*********************************************Chip type : ATmega16Program type : ApplicationClock frequency : 4.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256*********************************************/#include <mega16.h>#define row 12#define speed 25*8 //移动速度调节flash unsigned char char_7[row]={0x10,0x38,0x7C,0xFE,0x38,0x38,0x38,0x38,0x 00,0x00,0x00,0x00};bit time_1ms_ok;unsigned char dis_buff[8];interrupt [TIM0_COMP] void timer0_comp_isr(void) // 1ms 中断一次{time_1ms_ok = 1;}void display(void){static unsigned char i;PORTC = 0xFF;PORTA = dis_buff[i];PORTC = ~(1<<i);if (++i>= 8 ) i = 0;}void main(void){unsigned char move_speed,i,j;PORTA=0x00;DDRA=0xFF;PORTC=0xFF;DDRC=0xFF;// Timer/Counter 0 initialization// Clock source: System Clock,Clock value: 62.500 kHz// Mode: CTC top=OCR0, OC0 output: DisconnectedTCCR0=0x0B;TCNT0=0x00; OCR0=0x3D;TIMSK=0x02; //允许T/C0 CTC中断#asm("sei") // 开全局中断for (i=0;i<=8;i++) {dis_buff[i] = char_7[i];}j = 8;while (1){if (time_1ms_ok){ time_1ms_ok = 0;display();if (++move_speed>= speed){move_speed = 0;for (i=0;i<=6;i++){dis_buff[i] = dis_buff[i+1];}if (++j>= row) j = 0;dis_buff[7] = char_7[j];}}}p}3.使用定时器的产生特定频率,输出到蜂鸣器上产生不同的音调。
使用定时器产生DO RE MI FA SO LA SI 声音,每个音长1秒。
(假设 do 256 re 288 mi 320 fa 341 so 384 la 426 si 480) hz。
(参考第八章例8.7的硬件电路以及软件设计,利用AVR的16位T/C1的比较匹配功能,发出不同频率的音调。
)/*****************************************************Chip type : ATmega16Program type : ApplicationClock frequency : 4.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256*****************************************************/#include <mega16.h>flash unsigned int t[9] = {0,1953,1736,1562,1466,1302,1173,1041};flash unsigned char d[9] = {0,64,72,80,85,96,107,120};unsigned char note_n;unsigned int int_n;bit play_on;unsigned char time_counter;interrupt [EXT_INT1] void ext_int1_isr(void) //INT1中断服务程序{if (!play_on){ //启动T/C1,播放音乐TCCR1B = 0x09;}}interrupt [TIM1_COMPA] void timer1_compa_isr(void) //T/C1比较匹配中断服务{if (!play_on){note_n = 0;int_n = 1;play_on = 1; //从头播放}else{if (--int_n == 0) //音符未播放完成 {TCCR1B = 0x08; //停止T/C1工作if (note_n < 8) //播放一个音符 {if(++time_counter<=5){OCR1A = t[note_n];int_n = d[note_n];note_n++;int_n = int_n * 8; //计算该音符的节拍值TCCR1B = 0x09;}} //整个音乐播放完成 elseplay_on = 0;}}}void main (void){PORTD=0x08; //PD5匹配输出方式,脉冲输出,发声驱动 DDRD=0x20;TCCR1A=0x40; //PD3按键(INT1)输入口,输入方式TCCR1B=0x08;TCNT1 = 0x00;ICR1H = 0x00; //OCR1A为比较寄存器,OC1A为触发取反方式ICR1L = 0x00;OCR1A = 0x00;OCR1B = 0x00;TIMSK=0x10;GICR|=0x80; //外部中断初始化代码MCUCR=0x08; //允许INT1中断MCUCSR=0x00;GIFR=0x80;#asm("sei") //使能全局中断标志while (1) //主程序{// Place your code here};}[选作实验内容]参考demo_8_6.c,利用T/C1的PWM方式,设计出能产生更精确的、频率为1KHz、幅值为0~5V的正弦波(提示:使用T/C1,选择工作模式10,设置ICR1=250为计数值得上限值)。
/*****************************************************Chip type : ATmega16Program type : ApplicationClock frequency : 4.000000 MHzMemory model : SmallExternal SRAM size : 0Data Stack size : 256*****************************************************/#include <mega16.h>flash unsigned char auc_SinParam[128] = {128,134,140,147,153,159,165,171,177,182,188,193,198,204,208,213,218,222,226,230,233,237,240,242,245,247,249,251,252,253,254,254,254,254,253,252,251,250,248,246,244,241,238,235,232,228,224,220,215,211,206,201,196,191,185,179,174,168,162,156,150,144,137,131,125,119,112,106,100,94,88,82,77,71,65,60,55,50,45,41,36,32,28,24,21,18,15,12,10,8,6,5,4,3,2,2,2,2,3,4,5,7,9,11,14,16,19,23,26,30,34,38,43,48,52,57,63,68,74,79,85,91,97,103,109,116,122,128}; // 128点正弦波样本值unsigned char x_SW = 8,X_LUT = 0;interrupt [TIM1_COMPA] void timer1_compa_isr(void){X_LUT += x_SW; // 新样点指针if (X_LUT > 127){X_LUT -= 128; // 样点指针调整OCR0 = ICR1-auc_SinParam[X_LUT];}OCR0 = auc_SinParam[X_LUT]; // 取样点指针到比较匹配寄存器}void main(void){PORTD=0x08;DDRD=0x00;TCCR1A=0x40; //工作模式10TCNT1=0x00;TCNT1=0x00;TIMSK=0x10;#asm("sei")while (1){};}[实验总结与思考]1.仔细参考书上例程8.3,回答P253页上的5个问题。