基于单片机的测速系统的程序源代码:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit COUNT_IN=P3^2;
//定义1602相关管脚
sbit rs=P2^7;
sbit en=P2^6;
//按键定义
sbit add=P3^3;
sbit dec=P3^4;
sbit BUZZ=P1^0;
uint count,m,n;
unsigned long RPM;
long shangxian=10000;
bit flag;
uchar code tab1[]={" VH: r/min "}; //一行显示的固定字符
uchar code tab2[]={" RV: r/min "};//转速显示的固定字符
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
void init()
{
IT0=1;//INT0负跳变触发
TMOD=0x01;//定时器工作于方式1
TH0=0xfc; //1ms
TL0=0x18;
EA=1; //CPU开中断总允许
ET0=1;//开定时中断
EX0=1;//开外部INTO中断
TR0=1;//启动定时
}
/********液晶写入指令函数与写入数据函数,以后可调用**************/
void write_1602com(uchar com)//****液晶写入指令函数****
{
rs=0;//数据/指令选择置为指令
P0=com;//送入数据
delay(1);
en=1;//拉高使能端,为制造有效的下降沿做准备
delay(1);
en=0;//en由高变低,产生下降沿,液晶执行命令
}
void write_1602dat(uchar dat)//***液晶写入数据函数****
{
rs=1;//数据/指令选择置为数据
P0=dat;//送入数据
delay(1);
en=1; //en置高电平,为制造下降沿做准备
delay(1);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
void lcd_init()//***液晶初始化函数****
{
uchar a;
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写固定符号部分
}
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示固定符号
}
}
void display()
{
uchar gw,sw,bw,qw,ww;
if(RPM<=99999) //范围内时
{
ww=RPM/10000;
qw=RPM%10000/1000;
bw=RPM%1000/100;//取得百位
sw=RPM%100/10;//取得十位数字
gw=RPM%10;//取得个位数字
write_1602com(0x80+0x40+5);
if(ww==0)
write_1602dat(' ');
else
write_1602dat(0x30+ww);
if((ww+qw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+qw);
if((ww+qw+bw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+bw);
if((ww+qw+bw+sw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
else //超过范围时显示-----
{
write_1602com(0x80+0x40+2);
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
}
}
void display_shangxian()
{
write_1602com(0x80+5);
if(shangxian/10000==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian/10000);
if((shangxian/1000)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000/1000);
if((shangxian/100)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000%1000/100);
if((shangxian/10)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000%1000%100/10);
write_1602dat(0x30+shangxian%10000%1000%100%10);//数字+30得到该数字的LCD1602显示码
}
void key()
{
uint key_press_num;
uchar p;
if(add==0)
{
delay(20);
if(add==0)
{
while(!add)
{
key_press_num++;
if(key_press_num>=20)
{
key_press_num=0;
while(!add)
{
shangxian=shangxian+10;
if(shangxian>20000)
shangxian=0;
//for(p=0;p<20;p++)
display_shangxian();
}
}
display();
delay(10);
}
if(key_press_num!=0)
{
key_press_num=0;
shangxian++;
if(shangxian>20000)
shangxian=0;
}
}
}
if(dec==0)
{
delay(20);
if(dec==0)
{
while(!dec)
{
key_press_num++;
if(key_press_num>=20)
{
key_press_num=0;
while(!dec)
{
shangxian=shangxian-10;
if(shangxian<0)
shangxian=20000;
//for(p=0;p<20;p++)
display_shangxian();
}
}
display();
delay(10);
}
if(key_press_num!=0)
{
key_press_num=0;
shangxian--;
if(shangxian<0)
shangxian=20000;
}
}
}
}
void alarm()
{
if(RPM>=shangxian)
BUZZ=0;
else
BUZZ=1;
}
void main()
{
init();
lcd_init();
while(1)
{
display();
display_shangxian();
key();
alarm();
}
}
void EXINT0() interrupt 0
{
count++;
flag=1;
n=0;
if(count>=10)
{
RPM=600000/m;//60*1000*10 RPM=个数*60*1000/m m单位为ms 所以乘以1000
m=0;
count=0;
}
}
void time0() interrupt 1
{
TH0=0xfc;
TL0=0x18; //1ms
if(flag==1)
{
n++; m++;
if(n==6000)
{
RPM=(60000*count)/m;
m=0;
n=0;
count=0;
flag=0;
}
}
if(flag==0&&count==0)
{
n++;
if(n==3000)
{
RPM=0;
n=0;
}
}
}
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit COUNT_IN=P3^2;
//定义1602相关管脚
sbit rs=P2^7;
sbit en=P2^6;
//按键定义
sbit add=P3^3;
sbit dec=P3^4;
sbit BUZZ=P1^0;
uint count,m,n;
unsigned long RPM;
long shangxian=10000;
bit flag;
uchar code tab1[]={" VH: r/min "}; //一行显示的固定字符
uchar code tab2[]={" RV: r/min "};//转速显示的固定字符
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
void init()
{
IT0=1;//INT0负跳变触发
TMOD=0x01;//定时器工作于方式1
TH0=0xfc; //1ms
TL0=0x18;
EA=1; //CPU开中断总允许
ET0=1;//开定时中断
EX0=1;//开外部INTO中断
TR0=1;//启动定时
}
/********液晶写入指令函数与写入数据函数,以后可调用**************/
void write_1602com(uchar com)//****液晶写入指令函数****
{
rs=0;//数据/指令选择置为指令
P0=com;//送入数据
delay(1);
en=1;//拉高使能端,为制造有效的下降沿做准备
delay(1);
en=0;//en由高变低,产生下降沿,液晶执行命令
}
void write_1602dat(uchar dat)//***液晶写入数据函数****
{
rs=1;//数据/指令选择置为数据
P0=dat;//送入数据
delay(1);
en=1; //en置高电平,为制造下降沿做准备
delay(1);
en=0; //en由高变低,产生下降沿,液晶执行命令
}
void lcd_init()//***液晶初始化函数****
{
uchar a;
write_1602com(0x38);//设置液晶工作模式,意思:16*2行显示,5*7点阵,8位数据
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写固定符号部分
}
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示固定符号
}
}
void display()
{
uchar gw,sw,bw,qw,ww;
if(RPM<=99999) //范围内时
{
ww=RPM/10000;
qw=RPM%10000/1000;
bw=RPM%1000/100;//取得百位
sw=RPM%100/10;//取得十位数字
gw=RPM%10;//取得个位数字
write_1602com(0x80+0x40+5);
if(ww==0)
write_1602dat(' ');
else
write_1602dat(0x30+ww);
if((ww+qw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+qw);
if((ww+qw+bw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+bw);
if((ww+qw+bw+sw)==0)
write_1602dat(' ');
else
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
else //超过范围时显示-----
{
write_1602com(0x80+0x40+2);
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
write_1602dat('-');
}
}
void display_shangxian()
{
write_1602com(0x80+5);
if(shangxian/10000==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian/10000);
if((shangxian/1000)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000/1000);
if((shangxian/100)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000%1000/100);
if((shangxian/10)==0)
write_1602dat(' ');
else
write_1602dat(0x30+shangxian%10000%1000%100/10);
write_1602dat(0x30+shangxian%10000%1000%100%10);//数字+30得到该数字的LCD1602显示码
}
void key()
{
uint key_press_num;
uchar p;
if(add==0)
{
delay(20);
if(add==0)
{
while(!add)
{
key_press_num++;
if(key_press_num>=20)
{
key_press_num=0;
while(!add)
{
shangxian=shangxian+10;
if(shangxian>20000)
shangxian=0;
//for(p=0;p<20;p++)
display_shangxian();
}
}
display();
delay(10);
}
if(key_press_num!=0)
{
key_press_num=0;
shangxian++;
if(shangxian>20000)
shangxian=0;
}
}
}
if(dec==0)
{
delay(20);
if(dec==0)
{
while(!dec)
{
key_press_num++;
if(key_press_num>=20)
{
key_press_num=0;
while(!dec)
{
shangxian=shangxian-10;
if(shangxian<0)
shangxian=20000;
//for(p=0;p<20;p++)
display_shangxian();
}
}
display();
delay(10);
}
if(key_press_num!=0)
{
key_press_num=0;
shangxian--;
if(shangxian<0)
shangxian=20000;
}
}
}
}
void alarm()
{
if(RPM>=shangxian)
BUZZ=0;
else
BUZZ=1;
}
void main()
{
init();
lcd_init();
while(1)
{
display();
display_shangxian();
key();
alarm();
}
}
void EXINT0() interrupt 0
{
count++;
flag=1;
n=0;
if(count>=10)
{
RPM=600000/m;//60*1000*10 RPM=个数*60*1000/m m单位为ms 所以乘以1000
m=0;
count=0;
}
}
void time0() interrupt 1
{
TH0=0xfc;
TL0=0x18; //1ms
if(flag==1)
{
n++; m++;
if(n==6000)
{
RPM=(60000*count)/m;
m=0;
n=0;
count=0;
flag=0;
}
}
if(flag==0&&count==0)
{
n++;
if(n==3000)
{
RPM=0;
n=0;
}
}
}
