数码管测速
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
P1接LED,P3.7 3.6 3.5 3.4控制三极管的开关。就这样。
#include
unsigned char sled1,sled2,sled3,sled4,sztj,valupd,xxd;//串行LED扫描数据,状态机,更新缓冲用
unsigned int T1_ISR_count,speed;//T1定时器溢出计数,速度变量
unsigned long plusewidth;//脉冲宽度值,单位微秒
/*0,1,2,3,4,5,6,7,8,9,A,b,C,c,d,E,F,H,h,L,n,N,o,P,r,t,U,-,i,*/
unsigned char code sledsg[]={0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,
0x60,0x25,0x3C,0x37,0x23,0x34,0x74,0x61,0x65,0x3D,
0x67,0x68,0x27,0x70,0x77,0x35,0x29,0xF7,0x7F,0xff};//LE D段码
void init(void) //初始化函数,就是开机首先要做的事情,init是自己起的名字
{
TMOD=0x11; //两个定时器工作于方式1
PX0=1; //计时定时器中断优先
TR1=1; //定时器1启动
TR0=1; //定时器0启动
IT0=1; //外部中断0下降沿有效
IE=0x8B; //允许定时器及外部0中断
} //这段程序启动了芯片中的两个定时器
void sledscan(void) //时速LED模块扫描子程序,定时器调用
{
switch(sztj) //切换状态机
{
case 0: //第一状态
P3=0XFF; //关闭显示
P1=sledsg[sled1]; //送段码到P1口
P3=0Xdf; //点亮第一个数码管
sztj=1; //转移状态
break; //状态结束
case 1: //第二状态
P3=0XFF; //关闭显示
P1=sledsg[sled2]; //送段码到P1口
P3=0X7f; //点亮第二个数码管
sztj=2; //转移状态
break; //状态结束
case 2: //第三状态
P3=0XFF; //关闭显示
P1=xxd&sledsg[sled3]; //与0xdf,加上小数点
P3=0Xf7;
sztj=3;
break;
case 3:
P3=0XFF; //关闭显示
P1=sledsg[sled4];
P3=0Xef;
sztj=0;
break;
default:
sztj=0; //异常时捕获状态机
break;
}
}
void speedtobcd(unsigned int spd)//速度到BCD码,传递参数:速度
{
sled1=sled2=sled3=sled4=0;
while(spd>=10000)
{
sled4++;
spd=spd-10000;
}
while(spd>=1000)
{
sled3++;
spd=spd-1000;
}
while(spd>=100)
{
sled2++;
spd=spd-100;
}
while(spd>=10)
{
sled1++;
spd=spd-10;
}
}
void getspeed(void) //取得数据函数,主循环调用
{
if(T1_ISR_count>=150) //100*65536us都没有脉冲,则说明太慢{
speed=0; //太慢,速度置零
}
else
{
speed=991199520/plusewidth;//计算速度,速度=距离常数/总脉冲宽度*脉冲数量
}
speedtobcd(speed);//转换速度值到BCD码
if(sled4==0){sled4=29;} //无效零消隐
}
void int0int(void) interrupt 0 using 1 //外中断0函数,下降沿触发,霍尔信号
{
EA=0; //关闭外部中断
TR1=0; //冻结定时器值
((unsigned char *)&plusewidth)[0]=((unsigned char *)&T1_ISR_count)[0];//使用指针
((unsigned char *)&plusewidth)[1]=((unsigned char *)&T1_ISR_count)[1];//快速拼合
((unsigned char *)&plusewidth)[2]=TH1;//拼合低十六位
((unsigned char *)&plusewidth)[3]=TL1;//拼合最低8位
TL1=0;//定时器复位
TH1=0;//定时器复位
TR1=1;//重新启动定时器
T1_ISR_count=0;//溢出计数复位
EA=1;//开中断
}
void timer0 (void) interrupt 1 using 2 //定时器中断程序,定时时间到,自动运行此程序
{
TH0=(65536-10000)/256; //这两行的数值代表每10000us运行一次此程序 TL0=(65536-10000)%256; //置定时值,每次时间到都要重新置定时值 sledscan(); //扫描时速LED模块,122个周期
valupd++; //延时辅助变量,1个周期
}
void timer1 (void) interrupt 3 //定时器中断程序
{
T1_ISR_count++; //定时器溢出计数
}
void hi(void) //开机动画程序
{
unsigned char de1=20,de2,de3; //延时函数用临时变量
xxd=0xff; //关闭小数点
sled4=sled1=27; //-Hi-
sled3=17; //-Hi-
sled2=28; //-Hi-
while(--de1)
while(--de2)
while(--de3); //延时
sled1=sled2=sled3=sled4=0; //测试0000-9999
de1=30; //测试0000-9999
while(--de1)
{
sled1=sled2=sled3=++sled4; //测试0000-9999
while(--de2)
{
while(--de3); //延时