#include<reg52.h> #define uchar unsigned char #define uint unsigned int sbit qiting=P3^0;//定义启停按键 uchar qitingnum;//定义启停次数变量 uchar wan,qian,bai,shi,ge;//定义拆字变量 uint count,pulse;//声明定时器0计时变量、脉冲计数变量 unsigned long speed;//声明速度变量 uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //共阴数码管段码数字0~9字码表,高电平点亮数码管段码数字0~9。 /**ms级延时子程序**/ void delay(uint x) { uint i,j; for(i=0;i<x;i++) for(j=0;j<110;j++); } void display(unsigned long speed) { if(speed<=99999) { // uchar wan,qian,bai,shi,ge;//定义拆字变量 // wan=speed/10000;//转速/10000得到万位 // qian=speed%10000/1000;//转速/10000的余数/1000得到千位 // bai=speed%1000/100;//取得百位 // shi=speed%100/10;//取得十位数字 // ge=speed%10;//取得个位数字 P2=0xfd;//数码管万位显示位 P1=table[wan];//数码管万位数值显示 delay(2);//延时 P2=0xfb;//数码管千位显示位 P1=table[qian];//数码管千位数值显示 delay(2);//延时 P2=0xf7;//数码管百位显示位 P1=table[bai];//数码管百位数值显示 delay(2);//延时 P2=0xef;//数码管十位显示位 P1=table[shi];//数码管十位数值显示 delay(2);//延时 P2=0xdf;//数码管个位显示位 P1=table[ge];//数码管个位数值显示 delay(2);//延时 } } /**按键扫描程序**/ void keyscan()//按键扫描函数 { if(qiting==0)//判断启停键是否按下 { // delay(5); display(speed); if(qiting==0)//判断启停键是否再次按下 { qitingnum++;//启停次数变量加加 // while(!qiting);//等待启停键松开 while(!qiting)//等待启停键松开 display(speed); // lcd_init();//LCD1602液晶显示器初始化函数 } } if(qitingnum==1)//判断启停次数变量是否为1 { display(speed);//显示速度函数 } if(qitingnum==2)//判断启停次数变量是否为2 { // write_1602com(0x08);//关LCD1602液晶显示器显示 P2=0xff;//关数码管显示位 P1=0x00;//关数码管数值显示 qitingnum=0;//启停次数变量置0 } } /**外部中断0中断服务子程序**/ void Int0() interrupt 0 { pulse++; } /**定时器0、外部中断0初始化子程序**/ void Time0_Time1_init() { TMOD=0X01;//模式选定时器0、计数器1,工作方式选定时器0定时模式1、计数器1计数模式1。 TH0=(65536-50000)/256;//定时器0高8位定时50毫秒 TL0=(65536-50000)%256;//定时器0低8位定时50毫秒 // TH1=0;//计数器1高8位计数初值为0 // TL1=0;//计数器1低8位计数初值为0 EA=1;//打开总中断 EX0=1;//开外部中断0 IT0=1;//INT0负跳变触发 ET0=1;//打开定时器0的中断 TR0=1;//打开定时器0 // ET1=1;//打开计数器1的中断 // TR1=1;//打开计数器1 } void main() { Time0_Time1_init();//定时器0、计数器1初始化子程序 while(1) { keyscan();//按键扫描函数 } } /**定时器0中断服务子程序**/ void Timer0() interrupt 1 { TH0=(65536-50000)/256;//重装定时器0高8位定时50毫秒 TL0=(65536-50000)%256;//重装定时器0低8位定时50毫秒 count++;//定时器0定时中断次数变量加加 if(count==20)//判断定时器0定时中断次数变量是否等于20,即1秒钟。 { count=0;//定时器0定时中断次数变量清0 speed=pulse/3;//通过在小直流电机轴上套上一个白色圆盘(或白色圆形图纸),把白色圆盘分成6等份,其中三等份涂黑,余下三等份为白色。利用红外线照到黑色面时,反射光很弱,红外线接收端检测到的光线可以忽略,当照到白色面时,反射光强烈,发射端发射的红外线几乎被接收端全部接收的原理来测速。为什么是pluse/3,3是咋么来的?由于套在小直流电机轴上白色圆盘表面有3份白色面被红外线照射后反射回来3次,也就是3次高低电平脉冲,也产生了3次下降沿,这3次下降沿刚好是小直流电机转一圈。若算圈/秒就是pluse/3,算圈/分就是(pluse/3)/60,即pluse/20。 pulse=0;//脉冲个数变量清0,为下一次重新计数脉冲个数。 wan=speed/10000;//转速/10000得到万位 qian=speed%10000/1000;//转速/10000的余数/1000得到千位 bai=speed%1000/100;//取得百位 shi=speed%100/10;//取得十位数字 ge=speed%10;//取得个位数字 } }