原创
利用T/C0定时器还可以同时实现定时中断和PWM功能
2008-5-23 16:38
3000
5
5
分类:
测试测量
利用T/C0定时器还可以同时实现定时中断和PWM功能 数码管的显示等同于OCR0,这只是一个原理性的实验,请大师们评点评点 /************************************************************ ICC-AVR application builder : 2008-4-17 16:11:30 Target : M16 Crystal: 4.0000Mhz 文件:timer_00 设计:raosibin 时间:2008-4-25 版本:ver1.0 功能说明:T/C0中断溢出实验,每4096US中断一次,刷新显示数据; 动态扫描显示方式;每秒更新一次显示数据, T/C0快速PWM模式实验,每X秒更新OCR0的初值;改边PWM波型; 通过PB3间接观察PWM的波型; 硬件说明:PA0~PA3接数玛管的A,B,C,D;PD0~PD6接a,b,c,d,e,f,g;PB3接LED0; **************************************************************/ #include <iom16v.h> #include <macros.h> const unsigned char seg7_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f, 0x6f}; //0,1......9 段码 const unsigned char position_data[]={0xf1,0xf2,0xf4,0xf8}; //0,1,2,3, 位选通 unsigned char timer[4]; // 秒计数单元 unsigned char posit; volatile unsigned int counter; volatile unsigned char flag_1s; volatile unsigned char flag_2ms; void port_init(void) { PORTA = 0x00; DDRA = 0xFF; PORTB = 0x00; DDRB = 0xFF; PORTC = 0x00; //m103 output only DDRC = 0x00; PORTD = 0x00; DDRD = 0xFF; } void display(void) // 4位LED数码管动态扫描函数 { PORTA = 0x00; PORTD = seg7_data[timer[posit]]; PORTA = position_data[posit]; if (++posit >=4 ) posit = 0; } //TIMER0 initialize - prescale:64 // WGM: Normal // desired value: 2mSec // actual value: 2.000mSec (0.0%),已修改了,不是2MS void timer0_init(void) { TCCR0 = 0x00; //stop TCNT0 = 0x00; //set count OCR0 = 0x00; //set compare TCCR0 = 0x7B; //start timer } #pragma interrupt_handler timer0_ovf_isr:10 void timer0_ovf_isr(void) { //TCNT0 = 0x83; //reload counter value flag_2ms=1; if (++counter >=10) //改变10的值可以看到LED0变化的快慢 { ++OCR0; counter=0; flag_1s=1; } } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts port_init(); timer0_init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x01; //timer interrupt sources SEI(); //re-enable interrupts //all peripherals are now initialized } void main(void) { timer[0]=0; timer[1]=0; timer[2]=0; timer[3]=0; init_devices(); /*计数数值调整,显示的范围为99.99S*/ while(1) { if (flag_1s==1) { flag_1s=0; if (++timer[0]>=10) { timer[0]=0; if (++timer[1]>=10) { timer[1]=0; if (++timer[2]>=10) { timer[2]=0; if (++timer[3]>=10) { timer[3]=0; } } } } } if (flag_2ms==1) { flag_2ms=0; display(); } } } PS:已调试通过,T/C0还可以这样用
文章评论(0条评论)
登录后参与讨论