电路原理图如下:
单片机源程序如下:
- #include "stc8.h"
- #include "LED.h"
- //#include<reg52.h> //包含头文件
- #define uchar unsigned char
- #define uint unsigned int //宏定义
- sbit COUNT_IN=P3^3; //定义信号输入
- uchar count,m,n; //定义计算速度变量
- unsigned long RPM=0; //定义速度变量
- unsigned long TT=0; //定义时间变量
- unsigned long sum=0; //计算平均值的总数
- unsigned char T_num=0; //平均值取值的次数
- unsigned long num=0; //单次转速
- unsigned long TT1=0; //定义定时器中断次数变量
- bit flag; //定义位变量,值只能是0或者1
- uchar p,sec;
-
-
-
- void delay(uint x) //延时函数,大约延时1ms,不精确
- {
- uint i,j; //定义延时函数变量
- for(i=0;i<x;i++) //for循环延时
- for(j=0;j<110;j++);
- }
- //void delayms(unsigned int m)
- // {
- // int a, b;
- // for(a=0;a<5000;a++)
- // for(b=0;b<m;b++);
- //
- // }
-
-
- unsigned char code Led_display[]={ //标准字库 共阴数码管字符
- //// // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
-
- // unsigned char LedBuff[] = { 0xFF, 0xFF, 0xFF, 0xFF}; //数码管显示缓存区
-
- // static
- unsigned long Temp;
-
-
- void LED_Init(void)
- {
- P1=0x3F;
- P34=0;
- P35=0;
-
- P36=0;
- P37=0;
-
- }
- //
- void init() //定时器中断初始化
- {
- // IT0=1; //INT0负跳变触发 =1下降沿
- IT1=1; //INT0负跳变触发 =1下降沿
-
- TMOD=0x01;//定时器工作于方式1 16位不自动重载模式 当[TH1,TL1]中的16位计数值溢出时,定时器1将从0开始计数
- TH0=0;
- TL0=0;
- EA=1; //CPU开中断总允许 中断允许寄存器
- ET0=1; ////使能定时器中断
- // EX0=1;//开外部INTO中断 //使能 INT0 中断,**********
- EX1=1;//开外部INTO中断 //使能 INT0 中断,**********
- TR0=0;//启动定时 启动定时器
- TH1=0x3c; //定时器 1 高 8 为寄存器
- TL1=0xb0; ////定时器 1 低 8 为寄存器
- ET1=1; //////使能定时器中断
- TR1=1; ////开外部INT O 中断 //使能 INT 0 中断,**********
- }
- void LedScan(void) //数码管扫描显示
- {
- if (RPM<1)
- {
- P1 = 0x00; //显示指示灯
- P34=1;
- P35=1;
- P36=1;
- P37=1;
-
- delay(10);
- }
- else{
-
- if (RPM>9999)
- {
-
- P1 = 0x6F; //显示报警9999
- P34=0;
- P35=0;
- P36=0;
- P37=0;
-
- }
- else
- {
- static unsigned char i = 0; //动态扫描索引
- unsigned char buf[4]=0;
- Temp=RPM;
- buf[0] = Temp%10;
- buf[1] = (Temp/10)%10;
- buf[2] = (Temp/100)%10;
- buf[3] = (Temp/1000)%10;
- P1 = 0x00; //显示消隐
- switch (i)
- {
- case 0: P34=1;P35=1;P36=1;P37=0; P1=Led_display[buf[i]]; i++;break;
- case 1:P34=1; P35=1;P36=0;P37=1; P1=Led_display[buf[i]]; i++;break;
- case 2: P34=1;P35=0;P36=1;P37=1; P1=Led_display[buf[i]]; i++;break;
- case 3: P34=0;P35=1;P36=1;P37=1; P1=Led_display[buf[i]];i=0; break;
- default: break;
-
- }
-
- }
-
- // }
-
- }
- }
-
-
-
- main()
- {
- init(); //调用初始化函数
- P1M1=0;P1M0=0xFF;
- // P3M1=0x00;P3M0=0x00;
- P3M1=0x08;P3M0=0x08;
-
-
- while(1)
- {
- LedScan();
- }
- }
-
-
- //中断服务函数
- void EXINT0() interrupt 2 //外部中断函数,霍尔元件有信号,会进入此中断
- {
-
- if(TR0==0) //霍尔有信号输入时,定时器没有打开就打开定时器,准备计时
- {
- TH0=0;
- TL0=0; //定时器清零
- TT=0; //计时变量清零
- TT1=0; //定时器中断次数清零
- TR0=1; //打开定时器,开始计时
- p=0;sec=0;
- }
- else //第二次检测到信号时
- {
- p=0;sec=0;
- TR0=0; //关闭定时器
- TT=TT1*65536+TH0*256+TL0; //计算两次信号的时间差。中断次数*65536+TH0*256+TL0,得到时间差
- TH0=0;
- TL0=0; //计算完成后,将定时器清零
- num=120000000/TT; //根据时间计算1min中的速度。一分钟是60秒,一秒是1000毫秒,1毫秒是1000us,所以是60*1000*1000/时间,TT的单位是单片机的最快速度1微秒
- TT1=0; //计算完速度后,TT1清零
- if(num>1000) //转速超过1000时,取50次的平均值
- {
- sum=num+sum; //将数据加一起
- T_num++; //次数加
- if(T_num>=20) //加到50次
- {
- T_num=0; //次数清零
- RPM=sum/20; //总数除以50得到平均值
- sum=0; //计算完后总数清零
- }
- }
- else //转速小于1000时
- {
- sum=0; //总数清零
- RPM=num; //数据直接赋值给转速
- num=0; //数据清零
- T_num=0; //次数清零
- }
- }
- }
- void timeT0() interrupt 1 //两次信号中间,定时器有中断
- {
- TT1++; //说明达到一次65536,将TT1加1,计算时,将TT1乘以65536就是这个的时间了
- TH0=0;
- TL0=0; //定时器清零
- }
- void timeT1() interrupt 3 //两次信号中间,定时器有中断
- {
- TH1=0x3c;
- TL1=0xb0; //定时器清零
- // LedScan();//***
- p++;
- if(p>=20)
- {
- p=0;
- sec++;
- if(sec>=5)
- {
- sec=0;
- RPM=0;
- TR0=0;
- }
- }
- }
复制代码 Keil代码下载:
转速表程序.rar
(73.11 KB, 下载次数: 33)
|