实验44:基于TC1的ICP频率计(ATmega16)一、效果图[attach]760[/attach][attach]761[/attach]二、主程序[color=blue]/*******************************************************************************Platform:ATmega16+MAX7219+8位共阴数码管Project:实验44:基于TC1的ICP频率计(ATmega16)ClockF:外部RC:8MSoftware:ICCAVR7.14C+Proteus7.4Author:林夕依然AVRgroup:[/color][url=][color=blue][/color][/url][color=blue]Version:09.06.04Updata:comments:1、外部8M晶体,定时器1取8分频,即每计数一次的时间为1us,便于计算;2、M16的PC0/PC1/PC2控制MAX7219显示,使用第三种算法;3、使用定时器1的ICP1输入捕捉功能;4、最关键的地方,在于中断后取出ICR1的差值,这个值是测量的基础;5、频率和周期的测量均取整数,带小数位的情况需要进行处理,显示函数也较为复杂,此例中未做显示;6、本程序的测量范围尚未计算确定;7、程序显示1S实验日期后,进入频率/周期循环显示状态(间隔2S);8、参考:[/color][url=][color=blue][/color][/url][color=blue]古欣的利用ICP功能测周期频率的程序(ATmega128);*******************************************************************************/[/color]#includemacros.h#includeiom16v.h#defineucharunsignedchar#defineuintunsignedint#defineulongunsignedlong//全局变量定义uintTEN,QIAN,BAI,SHI,GE;ucharflow_flag=0;//用于标记定时器溢出,如果溢出了,只记录到TCNT的值就不对了哦,需要进行处理,应该是TOP*flow_flag+TCNTuinticpnum=0;//记录每次采集的TCNT差值,注意整个过程中不要操作TCNT,以免引入误差uchartimerover_error=0;uintlast_icrvalue=0;//记录上次的ICR值uintvalue;//函数声明voiddelay_ms(uinti);voiddelay_us(uintn);voidinit_max7219(void);voidsend_max7219(ucharadd,uchardata);voidtimer1_init(void);voidinit_devices(void);voidconver16_to10(uintnum);voiddisplay_date(void);voiddisplay_HZ(uinthz);voiddisplay_T(uintt);/*-----------------------------------------------------------------函数名称:voidtimer1_init(void)函数功能:定时器1初始化参数:无返回值:无说明:使能噪声抑制器,上升沿触发,8分频-----------------------------------------------------------------*/voidtimer1_init(void){TCCR1B=0x00;//stopTCNT1H=0x00;TCNT1L=0x00;ICR1H=0x00;ICR1L=0x00;TCCR1A=0x00;TCCR1B|=(1ICNC1)|(1ICES1)|(1CS11);//使能噪声抑制器,上升沿触发,8分频}/*-----------------------------------------------------------------函数名称:voidtimer1_ovf_isr(void)函数功能:定时器1捕捉事件中断参数:无返回值:无说明:ICP1引脚上升沿发生中断,如果需要测占空比,在此中断中按条件更改中断方向。-----------------------------------------------------------------*/#pragmainterrupt_handlertimer1_capt_isr:6voidtimer1_capt_isr(void){CLI();//关全局中断value=ICR1L;//先读取低字节(important)value|=(uint)ICR1H8;//读取高字节并同低字节合并//根据flow_flag的不同,计算真实的ICR差值if(flow_flag==0){icpnum=value-last_icrvalue;}else{if(flow_flag==1){//说明TCNT越过一次TOPflow_flag=0;icpnum=0xFFFF-last_icrvalue+value;}else{//超时(越界两次以上)未检查到信号,错误处理timerover_error=1;/****************************************调试程序时注意,如果进入这里结果已经不准确了****************************************/flow_flag=0;}}last_icrvalue=value;SEI();//开全局中断}/*-----------------------------------------------------------------函数名称:voidtimer1_ovf_isr(void)函数功能:定时器1溢出中断参数:无返回值:无-----------------------------------------------------------------*/#pragmainterrupt_handlertimer1_ovf_isr:9voidtimer1_ovf_isr(void){flow_flag++;}/*-----------------------------------------------------------------函数名称:voidinit_devices(void)函数功能:器件初始化参数:无返回值:无-----------------------------------------------------------------*/voidinit_devices(void){CLI();//关全局中断PORTC=0x00;DDRC=0xFF;DDRD=0x00;PORTD=(1PD6);//ICP1引脚为输入timer1_init();//定时器1初始化TIMSK|=(1TICIE1)|(1TOIE1);//TC1输入捕捉中断使能,溢出中断使能SEI();//开全局中断}/*-----------------------------------------------------------------函数名称:voidconver16_to10(uintnum)函数功能:16进制转10进制函数参数:num返回值:无-----------------------------------------------------------------*/voidconver16_to10(uintnum){TEN=num;QIAN=TEN/0x03e8;TEN%=0x03e8;BAI=TEN/0x64;TEN%=0x64;SHI=TEN/0x0a;TEN%=0x0a;GE=TEN;}/*-----------------------------------------------------------------函数名称:voiddisplay_date(void)函数功能:日期显示函数(2009.06.04)参数:无返回值:无-----------------------------------------------------------------*/voiddisplay_date(void){send_max7219(0x01,0);//1send_max7219(0x02,9);//2send_max7219(0x03,10);//3,显示'-'send_max7219(0x04,0);//4send_max7219(0x05,6);//5send_max7219(0x06,10);//6,显示'-'send_max7219(0x07,0);//7send_max7219(0x08,4);//9}/*-----------------------------------------------------------------函数名称:voiddisplay_HZ(uinthz)函数功能:频率显示函数,单位为HZ参数:hz,处理ICP1测量频率,显示在8位数码管上返回值:无-----------------------------------------------------------------*/voiddisplay_HZ(uinthz){conver16_to10(hz);send_max7219(0x01,10);//1显示'-'send_max7219(0x02,12);//2显示'H',表示频率单位HZsend_max7219(0x03,10);//3显示'-'send_max7219(0x04,15);//4显示空send_max7219(0x05,QIAN);//5显示千位send_max7219(0x06,BAI);//6显示百位send_max7219(0x07,SHI);//7显示十位send_max7219(0x08,GE);//9显示个位}/*-----------------------------------------------------------------函数名称:voiddisplay_T(uintt)函数功能:周期显示函数,单位为us参数:t,处理ICP1测量信号的周期,显示在8位数码管上返回值:无-----------------------------------------------------------------*/voiddisplay_T(uintt){conver16_to10(t);send_max7219(0x01,10);//1显示'-'send_max7219(0x02,5);//2显示'5',等效S,其周期单位ussend_max7219(0x03,10);//3显示'-'send_max7219(0x04,15);//4显示空send_max7219(0x05,QIAN);//5显示千位send_max7219(0x06,BAI);//6显示百位send_max7219(0x07,SHI);//7显示十位send_max7219(0x08,GE);//9显示个位}/*-----------------------------------------------------------------函数名称:voidmain(void)函数功能:主函数参数:无返回值:无------------