1、51单片机频率计设计LCD显示1 /单片机89C51的数字频率计C程序:#include #include #include #include float f; /频率float p; /周期float sj;float mk; /脉宽 char idata buff20;char xs=0; /设置闸门时间结束后是否显示结果的标志位unsigned char m=0,n=0,yichu=0,fenpin; /m定时中断次数 n计数中断次数 yichu判断是定时器还是sbit B153=P24;sbit A153=P23;sbit P35=P35;unsigned char LCD_Wait(
2、void);void LCD_Write(bit style, unsigned char input);void LCD_SetDisplay(unsigned char DisplayMode);void LCD_SetInput(unsigned char InputMode);void LCD_Initial();void GotoXY(unsigned char x, unsigned char y);void Print(unsigned char *str);void C51_Initial();void Delay(unsigned int t);void display(fl
3、oat f);void cepin();void panduan();void Mkdisplay(float mk);void ccpin();/* 模块名称: LCD1602显示程序 * */*端口定义 */sbit LcdRs= P20;sbit LcdRw= P21;sbit LcdEn= P22;sfr DBPort= 0x80; /P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口/*内部等待函数*/unsigned char LCD_Wait(void) LcdRs=0; /寄存器选择输入端 1:数据 0:指令 LcdRw=1; _nop_(); /RW:为
4、0:写状态;为1:读状态; LcdEn=1; _nop_(); /使能输入端,读状态,高电平有效;写状态,下降沿有效 LcdEn=0; return DBPort; /*向LCD写入命令或数据*/#define LCD_COMMAND 0 / Command#define LCD_DATA 1 / Data#define LCD_CLEAR_SCREEN 0x01 / 清屏#define LCD_HOMING 0x02 / 光标返回原点void LCD_Write(bit style, unsigned char input) LcdEn=0; LcdRs=style; LcdRw=0; _n
5、op_(); DBPort=input; _nop_();/注意顺序 LcdEn=1; _nop_();/注意顺序 LcdEn=0; _nop_(); LCD_Wait(); /*设置显示模式*/#define LCD_SHOW 0x04 /显示开#define LCD_HIDE 0x00 /显示关 #define LCD_CURSOR 0x02 /显示光标#define LCD_NO_CURSOR 0x00 /无光标 #define LCD_FLASH 0x01 /光标闪动#define LCD_NO_FLASH 0x00 /光标不闪动 void LCD_SetDisplay(unsigne
6、d char DisplayMode) LCD_Write(LCD_COMMAND, 0x08|DisplayMode); /*设置输入模式*/#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 / default #define LCD_MOVE 0x01 / 画面可平移#define LCD_NO_MOVE 0x00 /defaultvoid LCD_SetInput(unsigned char InputMode) LCD_Write(LCD_COMMAND, 0x04|InputMode);/*初始化LCD*/void LCD_Initial(
7、) LcdEn=0; LCD_Write(LCD_COMMAND,0x38); /8位数据端口,2行显示,5*7点阵 LCD_Write(LCD_COMMAND,0x38); LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); /开启显示, 无光标 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); /清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); /AC递增, 画面不动/*LCD*/void GotoXY(unsigned char x, unsigned char y)if(y=0) LCD_Writ
8、e(LCD_COMMAND,0x80|x);if(y=1) LCD_Write(LCD_COMMAND,0x80|(x-0x40);void Print(unsigned char *str) while(*str!=0) LCD_Write(LCD_DATA,*str); str+; /*89c51初始化*/ void C51_Initial() sj=1000000.00; TMOD=0x51; / 01010001 T1为计数器,T0为定时器 EA=1; ET0=1; ET1=1; EX0=1; PX0=1; /外部中断0设置为高优先级 IT0=0; /电平触发方式/*ms延时子程序*/
9、void Delay(unsigned int t) /t随着数值越大,误差趋于平衡.unsigned char i; while(t-) for(i=0;i999400.00) if(f1040.00) sprintf(buff,Freque %4.2fkHz,(f/1000.00); else if(f0.06) sprintf(buff,Freque %3.2fHz,f); GotoXY(0,1); Print(buff);/*显示周期*/void Pdisplay(float p) if(p999400.00) if(p9950.00) sprintf(buff,Perio %4.1f
10、ms ,(p/1000.00); else if(p0.248) sprintf(buff,Perio %3.2fus ,p); else sprintf(buff,error(Time or F),p); GotoXY(0,1); Print(buff); /*显示脉宽*/void Mkdisplay(float mk) if(mk499700.00) if(p4975.00) sprintf(buff,Maikua %4.1fms,(mk/1000.00); else if(p0.124) sprintf(buff,Maikua %3.2fus,mk); else sprintf(buff
11、,error(Time or F),mk); GotoXY(0,0); Print(buff); /*测试频率*/void cepin()unsigned char a;unsigned long js;m=0;n=0;TMOD=0x51;TH0=0x3c; /定时50msTL0=0xb0;TH1=0;TL1=0;a=sj/50000.00;TCON=0x50; /启动定时器和计数器while(m!=a); TCON=0; js=TH1*256+n*65536+TL1;f=(js/(sj/1000000.00)*fenpin;p=sj/(js*fenpin);mk=p/2;Pdisplay(p
12、); Mkdisplay(mk); void ccpin()unsigned char a;unsigned long js;m=0;n=0;TMOD=0x51;TH0=0x3c; /定时50msTL0=0xb0;TH1=0;TL1=0;a=sj/50000.00;TCON=0x50; /启动定时器和计数器while(m!=a); TCON=0; js=TH1*256+n*65536+TL1;f=(js/(sj/1000000.00)*fenpin;p=sj/(js*fenpin);mk=p/2;Fdisplay(f); /*判断频率*/void panduan()xs=0; /设置结束后第二
13、次循环显示结果B153=1; /选择16分频A153=0; yichu=0;TMOD=0x51; TH0=0xff; /定时器0 200usTL0=0x38;TH1=0xff; /计数器1 100脉冲TL1=0x9c;TR0=1; /启动定时器0和计数器1TR1=1;while(yichu=0); /如果没有溢出一直循环TR0=0; /已经溢出关闭定时器0和计数器1TR1=0; if(yichu=1) /计数器先溢出:在200ms内测得的脉冲过多,说明频率较高 fenpin=16; /转为测16分频后的频率 16 cepin();else /定时器先溢出:100个脉冲的时间比较短,即频率较低,
14、可以减少分频数 yichu=0; B153=0; A153=1; TH0=0xfc; /定时器0 1ms TL0=0x18; TH1=0xff; /计数器1 100个脉冲 TL1=0x9c; TR0=1; /启动定时器0和计数器1 TR1=1; while(yichu=0); /如果没溢出一直循环 TR0=0; /已经溢出关闭定时器0和计数器1 TR1=0; if(yichu=1) /计数器先溢出:在1ms内测得的脉冲过多,说明频率较高(1khzf500khz) fenpin=4; /转为测4分频后的频率 4 cepin(); else /定时器先溢出:100个脉冲的时间比较短,即频率较低 f
15、enpin=1; B153=0; A153=0; cepin(); void pd()xs=0; /设置结束后第二次循环显示结果B153=1; /选择16分频A153=0; yichu=0;TMOD=0x51; TH0=0xff; /定时器0 200usTL0=0x38;TH1=0xff; /计数器1 100脉冲TL1=0x9c;TR0=1; /启动定时器0和计数器1TR1=1;while(yichu=0); /如果没有溢出一直循环TR0=0; /已经溢出关闭定时器0和计数器1TR1=0; if(yichu=1) /计数器先溢出:在200ms内测得的脉冲过多,说明频率较高 fenpin=16;
16、 /转为测16分频后的频率 16 ccpin();else /定时器先溢出:100个脉冲的时间比较短,即频率较低,可以减少分频数 yichu=0; B153=0; A153=1; TH0=0xfc; /定时器0 1ms TL0=0x18; TH1=0xff; /计数器1 100个脉冲 TL1=0x9c; TR0=1; /启动定时器0和计数器1 TR1=1; while(yichu=0); /如果没溢出一直循环 TR0=0; /已经溢出关闭定时器0和计数器1 TR1=0; if(yichu=1) /计数器先溢出:在1ms内测得的脉冲过多,说明频率较高(1khzf500khz) fenpin=4;
17、 /转为测4分频后的频率 4 ccpin(); else /定时器先溢出:100个脉冲的时间比较短,即频率较低 fenpin=1; B153=0; A153=0; ccpin(); void main() LCD_Initial(); /LCD初始化GotoXY(0,0);Print(*B09010407*);Delay(1000);GotoXY(0,0);Print( Testing. );C51_Initial(); /89c51初始化while(1) pd(); Delay(2000); panduan(); Delay(3000); 仅供个人用于学习、研究;不得用于商业用途。For personal use only in study and research; not for commercial use.Nur fr den persnlichen fr Studien, Forschung, zu kommerziellen Zwecken verwendet werden.Pour l tude et la recherche uniquement des fins personnelles; pas des fins commerciales. , , . 以下无正文
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1