基于MSP430F5438A单片机测量频率的程序实例/*****************************************************程序描述:利用Timer_A捕获脉冲宽度利用MSP430单片机定时器A和捕获/比较功能模块结合使用,实现脉冲宽度的测量程序用到了定时器A的CCI1A端口(MSP430F14X的P1.2引脚)作捕获外部输入的脉冲电平跳变,start,end,两个个变量来计算脉冲宽度*****************************************************/#includemsp430x14x.h#includelcd12864.huintstart,end;uintwidth;//==用于存放脉宽==uintperiod;//==用于存放周期==uintfrequency;//==用于存放频率==uintfy[7];//==用于存放频率显示数据==uintpd[7];//==用于存放周期显示数据==uintwh[6];//==用于存放脉宽显示数据==constunsignedcharzhouqi[]={周期为:(us)};constunsignedcharus[]={us};constunsignedcharpinlv[]={频率为:(Hz)};constunsignedcharhz[]={HZ};voidprocess(void);//==函数声明==voiddelay();//==延时函数==voidInitSys();//==初始化时钟==/****************************************************主函数****************************************************/intmain(void){WDTCTL=WDTPW+WDTHOLD;//==关狗==InitSys();//==初始化时钟,SMCLK,MCLK均为8M==P1DIR&=~BIT2;P1SEL=BIT2;//==设置P1.2端口为功能模块使用,即:做捕获源==TACTL=TASSEL_2+ID_3+TACLR+TAIE+MC1;//==定时器A时钟信号选择SMCLK,8分频,同时设置定时器A计数模式为连续增计模式==CCTL1=CM_1+SCS+CAP+CCIE;//==输入上升沿捕获,CCI0A为捕获信号源==_EINT();//==开全局中断允许==Ini_Lcd();//==初始化液晶==Clear_GDRAM();//==清屏==Disp_HZ(0x80,zhouqi,8);Disp_HZ(0x88,pinlv,8);while(1){process();Write_Cmd(0x90);//==写地址==Write_Data(0x30+pd[6]);Write_Data(0x30+pd[5]);Write_Data(0x30+pd[4]);Write_Data(0x30+pd[3]);Write_Data(0x30+pd[2]);Write_Data(0x30+pd[1]);Write_Data(0x30+pd[0]);Write_Cmd(0x98);//==写地址==Write_Data(0x30+fy[6]);Write_Data(0x30+fy[5]);Write_Data(0x30+fy[4]);Write_Data(0x30+fy[3]);Write_Data(0x30+fy[2]);Write_Data(0x30+fy[1]);Write_Data(0x30+fy[0]);delay();}}/*****************************************************初始化时钟*****************************************************/voidInitSys(){unsignedinti;//---使用XT2振荡器---BCSCTL1&=~XT2OFF;//==打开XT2振荡器==do{IFG1&=~OFIFG;//==清除振荡器失效标志==for(i=0xFF;i0;i--);//==延时,等待XT2起振==}while((IFG1&OFIFG)!=0);//==判断XT2是否起振==BCSCTL2=SELM_2+SELS;//==选择MCLK、SMCLK为XT2,8M==}/*****************************************************延时函数*****************************************************/voiddelay(){unsignedinti;unsignedintj=10;for(i=10;i0;i--){while(j--);}}/***************************************************数据处理***************************************************/voidprocess(void){while(endstart);//while(endstart)的话就让其一直等待下去,直到endstartwidth=end-start;//==实际脉冲宽度的计算==period=2*width;frequency=1000000/period;pd[6]=period/1000000;pd[5]=(period-1000000*pd[6])/100000;pd[4]=(period-1000000*pd[6]-100000*pd[5])/10000;pd[3]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4])/1000;pd[2]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4]-1000*pd[3])/100;pd[1]=(period-1000000*pd[6]-100000*pd[5]-10000*pd[4]-1000*pd[3]-100*pd[2])/10;pd[0]=period%10;fy[6]=frequency/1000000;fy[5]=(frequency-1000000*fy[6])/100000;fy[4]=(frequency-1000000*fy[6]-100000*fy[5])/10000;fy[3]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4])/1000;fy[2]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3])/100;fy[1]=(frequency-1000000*fy[6]-100000*fy[5]-10000*fy[4]-1000*fy[3]-100*fy[2])/10;fy[0]=frequency%10;}/***************************************************中断处理函数***************************************************/#pragmavector=TIMERA1_VECTOR//==定时器A中断处理==__interruptvoidtimer_a(void){switch(TAIV)//==向量查询=={case2://==捕获中断==if(CCTL1&CM0)//==捕获到上升沿=={CCTL1=(CCTL1&(~CM0))|CM1;//==更变设置为下降沿触发==start=TAR;//==记录初始时间==}elseif(CCTL1&CM1)//==捕获到下降沿=={CCTL1=(CCTL1&(~CM1))|CM0;//==更变设置为上升沿触发==end=TAR;//==用start,end,overflow计算脉冲宽度==}break;default:break;}}