基于AVR的单片嵌入式系统原理与实践应用华东师范大学电子科学技术系马潮11-1第11章综合实践(二)本章的综合实践将综合前几章的内容,指导读者完成以下的实践:l如何实现频率测量和简单频率计的设计实现。l使用T/C1的输入捕捉功能实现高精度的频率周期测量l完成一个比较完善的实时时钟的设计和实现。11.1频率测量和简单频率计的设计11.1.1频率测量原理单片机应用系统中,经常要对一个连续的脉冲波频率进行测量。在实际应用中,对于转速,位移、速度、流量等物理量的测量,一般也是由传感器转换成脉冲电信号,采用测量频率的手段实现。使用单片机测量频率或周期,通常是利用单片机的定时计数器来完成的,测量的基本方法和原理有两种:测频法:在限定的时间内(如1秒钟)检测脉冲的个数。测周法:测试限定的脉冲个数之间的时间。这两种方法尽管原理是相同的,但在实际使用时,需要根据待测频率的范围、系统的时钟周期、计数器的长度、以及所要求的测量精度等因素进行全面和具体的考虑,寻找和设计出适合具体要求的测量方法。在具体频率的测量中,需要考虑和注意的因素有以下几点。ü系统的时钟。首先测量频率的系统时钟本身精度要高,因为不管是限定测量时间还是测量限定脉冲个数的周期,其基本的时间基准是系统本身时钟产生的。其次是系统时钟的频率值,因为系统时钟频率越高,能够实现频率测量的精度也越高。因此使用AVR测量频率时,建议使用由外部晶体组成的系统的振荡电路,不使用其内部的RC振荡源,同时尽量使用频率比较高的系统时钟。ü所使用定时计数器的位数。测量频率要使用定时计数器,定时计数器的位数越长,可以产生的限定时间越长,或在限定时间里记录的脉冲个数越多,因此也提高了频率测量的精度。所以对频率测量精度有一定要求时,尽量采用16位的定时计数器。ü被测频率的范围。频率测量需要根据被测频率的范围选择测量的方式。当被测频率的范围比较低时,最好采用测周期的方法测量频率。而被测频率比较高时,使用测频法比较合适。需要注意的是,被测频率的最高值一般不能超过测频MCU系统时钟频率的1/2,因为当被测频率高于MCU时钟1/2后,MCU往往不能正确检测被测脉冲的电平变化了。除了以上三个因素外,还要考虑频率测量的频度(每秒内测量的次数),如何与系统中其它任务处理之间的协调工作等。频率测量精度要求高时,还应该考虑其它中断以及中断响应时间的影响,甚至需要在软件中考虑采用多次测量取平均的算法等。在“AVR-51多功能实验开发板”的K区有一个方波信号源。该区模块使用一个2.048MHz的晶体振荡器,经过CD4060的分频后,提供了占空比为50%,125Hz~128KHz之间10种不同频率的标准方波脉冲信号。下面我们介绍2个基本的频率测量实例,实现对这些不同频率的信号进行测量。第11章实战练习二华东师范大学电子科学技术系马潮11-211.1.2测频法测量频率测频法的基本思想,就是采用在已知限定的时间内对被测信号输入的脉冲个数进行计数的方法来实现对信号频率的测量。当被测信号的频率比较高时,采用这种方法比较适合,因为在一定时间内,频率越高,计数脉冲的个数也越多,测量也越准确。例11.1采用测频法的频率计设计与实现1)硬件电路硬件电路的显示部分与图9-7相同,PA口为8个LED数码管的段输出,PC口控制8个LED数码管的位扫描。使用T/C0对被测信号输入的脉冲个数进行计数,被测频率信号由PB0(T0)输入。2)软件设计我们首先给出系统程序,然后做必要的说明。/*********************************************Filename:demo_11_1.cChiptype:ATmega16Programtype:ApplicationClockfrequency:4.000000MHzMemorymodel:SmallExternalSRAMsize:0DataStacksize:256*********************************************/#includemega16.hflashcharled_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};flashcharposition[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};chardis_buff[8];//显示缓冲区,存放要显示的8个字符的段码值charposit;bittime_1ms_ok,display_ok=0;chartime0_old,time0_new,freq_time;unsignedintfreq;voiddisplay(void)//8位LED数码管动态扫描函数{PORTC=0xff;PORTA=led_7[dis_buff[posit]];if(posit==5)PORTA=PORTA|0x80;PORTC=position[posit];if(++posit=8)posit=0;}//Timer2outputcompareinterruptserviceroutineinterrupt[TIM2_COMP]voidtimer2_comp_isr(void){基于AVR的单片嵌入式系统原理与实践应用华东师范大学电子科学技术系马潮11-3time0_new=TCNT0;//1ms到,记录当前T/C0的计数值time_1ms_ok=1;display_ok=~display_ok;if(display_ok)display();}voidfreq_to_disbuff(void)//将频率值转化为BCD码并送入显示缓冲区{chari,j=7;for(i=0;i=4;i++){dis_buff[j-i]=freq%10;freq=freq/10;}dis_buff[2]=freq;}voidmain(void){chari;DDRA=0xFF;//LED数码管驱动DDRC=0xFF;//T/C0初始化,外部计数方式TCCR0=0x06;//外部T0脚下降沿触发计数,普通模式TCNT0=0x00;OCR0=0x00;//T/C2初始化TCCR2=0x0B;//内部时钟,32分频(4M/32=125KHz),CTC模式TCNT2=0x00;OCR2=0x7C;//OCR2=0x7C(124),(124+1)/125=1msTIMSK=0x80;//允许T/C2比较匹配中断for(i=0;i=7;i++)dis_buff[i]=0;time0_old=0;#asm(sei)//开放全局中断while(1){if(time_1ms_ok){//累计T/C0的计数值if(time0_new=time0_old)freq=freq+(time0_new-time0_old);elsefreq=freq+(256-time0_old+time0_new);第11章实战练习二华东师范大学电子科学技术系马潮11-4time0_old=time0_new;if(++freq_time=100){freq_time=0;//100ms到,freq_to_disbuff();//将100ms内的脉冲计数值送显示freq=0;}time_1ms_ok=0;}};}程序中LED扫描形式函数desplay(),以及脉冲计数值转换成BCD码并送显示缓冲区函数freq_to_disbuff()比较简单,请读者自己分析。在该程序中,使用了两个定时计数器。T/C0工作在计数器方式,对外部T0引脚输入的脉冲信号计数(下降沿触发)。T/C2工作在CTC方式,每隔1ms中断一次,该定时时间即作为LED的显示扫描,同时也是限定时间的基时。每一次T/C2的中断中,都首先记录下T/C0寄存器TCNT0当前的计数值,因此前后两次TCNT0的差值(time0_new–time0_old)或(256-time0_old+time0_new)就是1ms时间内T0脚输入的脉冲个数。为了提高测量精度,程序对100个1ms的脉冲个数进行了累计(在变量freq中),即已知限定的时间为100ms。读者还应该注意频率的连续测量与LED扫描、BCD码转换之间的协调问题。T/C2中断间隔为1ms,因此在1ms时间内,程序必须将脉冲个数进行的累计、BCD码转换和送入显示缓冲区,以及LED的扫描工作完成掉,否则就会影响到下一次中断到来后的处理。在本实例的T/C2中断中,使用了display_ok标志,将LED扫描分配在奇数ms(1、3、5、7、……),而将1ms的TCNT0差值计算、累积和转换等处理放在主程序中完成。另外由于计算量大的BCD码转换是在偶数ms(100ms)处理,所以程序中LED的扫描处理和BCD码转换处理不会同时进行(不会在两次中断间隔的1ms内同时处理LED扫描和BCD码转换),这就保证了在下一次中断到达时,前一次的处理已经全部完成,使频率的连续测量不受影响。该实例程序的性能和指标为(假定系统时钟没有误差=4MHz):ü频率测量绝对误差:±10Hz。由于限定的时间为100ms,而且T/C0的计数值有±1的误差,换算成频率为±10Hz。ü被测最高频率值:255KHz。由于T/C0的长度8位,所以在1ms中,TO输入的脉冲个数应小于255个,大于255后造成T/C0的自动清另,丢失脉冲个数。ü测量频度:10次/秒。限定的时间为100ms,连续测量,所以为10次/秒。ü使用资源:两个定时器,一个中断。3)思考与实践根据上面采用测频法的思路,如何修改程序提高测量精度和被测最高频率?参考提示如下:ü延长限定的时间,如采用1s,可提高频率的测量精度。但测量频度减小,同时注意变量freq应定义为长整型变量。ü将T/C0换成16位的T/C1,可以提高被测最高频率值。注意此时time0_new、time0_old应定义为整型变量。11.1.3测周法测量频率测周法的基本思想,就是测量在限定的脉冲个数之间的时间间隔,然后再换算成频率(需要时)。当被测信号的频率比较低时,采用这种方法比较适合,因为频率越低,在限定的脉基于AVR的单片嵌入式系统原理与实践应用华东师范大学电子科学技术系马潮11-5冲个数之间的时间间隔也也长,因此定时计数的个数也越多,测量也越准确。例11.2采用测周法的频率计设计与实现1)硬件电路硬件电路的显示部分与图9-7相同,PA口为8个LED数码管的段输出,PC口控制8个LED数码管的位扫描。被测频率信号由PB0(T0)输入。2)软件设计我们首先给出系统程序,然后做必要的说明。/*********************************************Filename:demo_11_2.cChiptype:ATmega16Programtype:ApplicationClockfrequency:4.000000MHzMemorymodel:SmallExternalSRAMsize:0DataStacksize:256*********************************************/#includemega16.hflashcharled_7[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};flashcharposition[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};chardis_buff[8];//显示缓冲区,存放要显示的8个字符的段码值charposit;bitfreq_ok=0;chartime2_new;unsignedintfreq;unsignedlongintfreq_temp;voiddisplay(void)//8位LED数码管动态扫描函数{PORTC=0xff;PORTA=led_7[dis_buff[posit]];if(posit==5