#include<reg52.h> #include<intrins.h> #define uint8 unsigned char #define uint16 unsigned int #define CMD 0x00 #define DAT 0x01 #define DataPort P0//LCD数据口 sbit RW=P2^6; sbit RS=P2^5; sbit E=P2^7; uint16 N=0; uint8 C_50ms; uint8 Z=0; uint8 count=0; bit flag_1s=0; /**ms级延时子程序**/ void delay(uint16 t) { uint16a; for(;t>0;t--) for(a=123;a>0;a--); } /**LCD时序**/ void write_LCD(uint8 dat,bit rs) { E=0; RW=0; RS=rs;//选择指令or数据 _nop_(); _nop_(); _nop_(); E=1; _nop_();//delay(1); _nop_(); _nop_(); DataPort=dat;//将数据送到LCD数据口 _nop_(); _nop_(); _nop_(); E=0; delay(1); } /**LCD选择显示位置子函数**/ void SetXY(uint8 x,uint8 y) { x=x&0x0f;//防止X、Y 超过量程 y=y&0x01; if(y) { write_LCD(0x80+x,CMD); } else { write_LCD(0xc0+x,CMD); } } /**转速数值转换子函数**/ void disload(uint16 a) { SetXY(4,0); write_LCD(a/1000+'0',DAT); write_LCD(a%1000/100+'0',DAT); write_LCD(a%100/10+'0',DAT); write_LCD(a%10+'0',DAT); write_LCD('r',DAT); write_LCD('/',DAT); write_LCD('m',DAT); write_LCD('i',DAT); write_LCD('n',DAT); } /**LCD字符指针函数**/ void LCD_wrstr(uint8*str) { while(*str!='\0') { write_LCD(*str,DAT); str++; } } /**初始化子程序**/ void All_init() { delay(500); write_LCD(0x38,CMD); write_LCD(0x38,CMD); write_LCD(0x0c,CMD); write_LCD(0x01,CMD); delay(10); SetXY(0,1);//设置标题显示位置 LCD_wrstr("Tachometer:"); TMOD=0x01;//设置T0位工作方式1——作为16位定时器 ET0=1;//打开定时器0的中断 TR0=1;//打开定时器0 TH0=(65536-50000)/256;//装入初值 TL0=(65536-50000)%256; IT0=1;//外部中断0为下降沿中断 EX0=1;//打开外部中断 EA=1;//打开总中断 } void main() { All_init();//先进行初始化 while(1) { if(flag_1s==1) { flag_1s=0;//1s标志位清零 disload(N); } } } /**定时器0中断服务子程序**/ void timer0() interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; if(++C_50ms>19) { EX0=0;//关闭外部中断0 C_50ms=0;//定时1s之后C_50ms清零 N=60*Z;//计算转速 Z=0;//初始化圈数 flag_1s=1;//1s标志位置1 TH0=0x3c;//重新赋值 TL0=0xb0; EX0=1;//打开外部中断0,开始计数。 } } void wai0() interrupt 0 { count++; if(count==2)//两次外部脉冲,电机转一圈。 { Z++;//转圈+1 count=0;//初始计数值 } }
|