标题:
关于状态机应用程序的电子表
[打印本页]
作者:
青春风铃
时间:
2016-10-30 20:30
标题:
关于状态机应用程序的电子表
希望能给大家提供经验,51单片机做的状态机应用程序的电子表
0.png
(23.45 KB, 下载次数: 58)
下载附件
2016-10-30 21:25 上传
#include <REGX51.H>
#include <intrins.h>
typedef unsigned char uint8;
#define NT 29
const uint8 THH=(65536-2000+NT)/256;
const uint8 TLL=(65536-2000+NT)%256;
uint8 code SEG7CC[]={0x3F,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x0};
uint8 volatile LED[]={2,3,5,9,5,0};
volatile uint8 hour=23;
volatile uint8 minute=59;
volatile uint8 sec=50;
volatile uint8 mode=0;
volatile uint8 isAddPush=0;
void timeDly(unsigned int n);
void tickProc();
void main()
{
//char i,temp;
EA=1; //总中断开关
ET0=1; //分中断开关
TMOD = 1; //设置为 16 位定时器模式。
TR0=1; //启动定时器 T0
ET1=1;
TR1=1;
TMOD |= 0x10; //不更改原先的代码
PT0 =1;//时间的刷新比按键更重要
PT1 =1;// 时间的刷新比按键更重要
EX0=1;
EX1=1;
IT0=1;
IT1=1;
while(1)
{
tickProc();
}
} void tickProc()
{ static uint8 N=0;//记录调用次数,实现闪烁
switch(mode)
{
case 0://正常运行模式下,N 不变,秒定时器运行
TR1 =1;
break;
case 1://模式 1 下,小时闪
TR1 =0;
N++;
if(isAddPush)//如果有加键按下,小时加
{ if(++hour>23) hour=0;
isAddPush=0;
}
if(N%2==0) //N 为偶数,小时数字灭
{
LED[0]=10;
LED[1]=10;
}
else //N 为奇数,小时恢复正常数字,实现闪烁
{
LED[0]=hour/10;
LED[1]=hour%10;
}
timeDly(500);
break;
case 2:
TR1 =0;
N++;
if(isAddPush)
{ if(++minute>59) minute=0; isAddPush=0; }
if(N%2==0)
{ LED[2]=10; LED[3]=10; }
else
{ LED[2]=minute/10; LED[3]=minute%10; }
timeDly(500);
break;
case 3:
TR1 =0;
N++;
if(isAddPush)
{ if(++sec>59) sec=0; isAddPush=0; }
if(N%2==0)
{ LED[4]=10; LED[5]=10; }
else
{
LED[4]=sec/10; LED[5]=sec%10;
}
timeDly(500);
break;
default: mode=0;//增强抗干扰能力
}
}
void int0ISR()interrupt 0
{ timeDly(10);//消除抖动
IE0 =0;//二次进入同类中断,中断标志位会保留,防止处理 2 次。
if(P3_2) return;//松开按键,后边沿,不处理
if(++mode>3) mode=0;
LED[0]=hour/10; //模式变后,闪的位置也会变,要重置正常显示情况
LED[1]=hour%10;
LED[2]= minute/10;
LED[3]= minute%10;
LED[4] = sec/10;
LED[5] = sec%10; }
void int1ISR() interrupt 2
{ timeDly(10);
IE1 =0;
if(P3_3) return;
isAddPush=1;//有按键则置位标志位,这个处理较为复杂,在主循环中处理。
}
void timeDly(unsigned int n)
{
unsigned int i;
for(; n>0; n--)
for(i=123; i>0; i--);
}
void t1ISR() interrupt 3
{
static uint8 N=0;//记录中断次数
TH1 = (65536-62500)/256;
TL1 = (65536-62500)%256;
if(++N>=16)
{
N=0;
ET0 =0;//时分秒比显示定时刷新重要,暂时先关刷新中断
if(++sec>59)
{
sec=0;
if(++minute>59)
{
minute =0;
if(++hour>23)
hour=0;
}
}
LED[0]=hour/10;//时分秒有改变,重置显示缓冲区
LED[1]=hour%10;
LED[2]= minute/10;
LED[3]= minute%10;
LED[4] = sec/10;
LED[5] = sec%10;
ET0 =1;
}
}
void t0ISR() interrupt 1
{
static uint8 N=0;
switch(N)
{
case 0:
P2 = (1<<5);
P1 = SEG7CC[ LED[5]];
break;
case 1:
P2 = (1<<4);
if(LED[4]!=0)
P1 = SEG7CC[ LED[4]];
else
P1 = SEG7CC[10];//秒高位为 0,则不显示
break;
case 2:
P2 = (1<<3);
P1 = SEG7CC[ LED[3]];
if(mode==0) //如果是正常显示,则将这个位置的小数点点亮
P1 = SEG7CC[ LED[3]] | 0x80;
break;
case 3:
P2 = (1<<2);
if(LED[2]!=0)
P1 = SEG7CC[ LED[2]];
else
P1 = SEG7CC[10];//分钟高位为 0,则不显示
break;
case 4:
P2 = (1<<1);
P1 = SEG7CC[ LED[1]];
if(mode==0) //如果是正常显示,则将这个位置的小数点点亮
P1 = SEG7CC[ LED[1]] | 0x80;
break;
case 5:
P2 = 1;
if(LED[0]!=0)
P1 = SEG7CC[LED[0]];
else
P1 = SEG7CC[10];//小时高位为 0,则不显示
break;
default:
N=0;//出错,令 N 归零。
}
if(++N>5) N=0;
TH0 = THH;
TL0 = TLL;
}
复制代码
0.png
(73.73 KB, 下载次数: 55)
下载附件
2016-10-30 21:25 上传
所有资料打包下载:
新建文件夹.rar
(51.65 KB, 下载次数: 14)
2016-10-30 20:29 上传
点击文件名下载附件
不错哦!
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1