历史上的今天
今天是:2025年01月20日(星期一)
2020年01月20日 | 第一次偿试51单片机做个100分钟倒计时定时器
2020-01-20 来源:51hei
偿试着做了个100分钟倒计时定时器,原理图和代码都是东拼西凑来的(自己不会写啊
),侵删
制作出来的实物图如下:
电路原理图如下:
单片机源程序如下:
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar duan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar wei[4]={0XEf,0XDf,0XBf,0X7f}; //位的控制端
uint setfen,setmiao,runfen,runmiao;
uint z,x,c,v;
uint fs,fg,ms,mg;
uint setwz;
sbit KEYSTOP=P3^7; //停止键
sbit KEYSET=P1^7; //设置键
sbit KEYUP=P1^6; //上调
sbit KEYDOWN=P1^5; //下调
sbit KEYRUN=P1^4; //开始
sbit LEDSET=P1^3; //设置灯
sbit LEDRUN=P1^2; //运行灯
sbit LEDSTOP=P1^1; //停止灯
sbit LABA=P1^0; //喇叭
uint runmod=0; //状态,0是等待运行(停止),1是运行,2是设置,3是刚刚完成
unsigned char n_50ms;
bit flag;
/****************特殊功能寄存器声明,以下是关于读写FLASH的****************/
sfr ISP_DATA = 0xe2;
sfr ISP_ADDRH = 0xe3;
sfr ISP_ADDRL = 0xe4;
sfr ISP_CMD = 0xe5;
sfr ISP_TRIG = 0xe6;
sfr ISP_CONTR = 0xe7;
void cc(uint addr);
void xcx(uint addr,uchar dat);
uchar dcx(uint addr);
void Q0();
/******************************************************************
延时函数
******************************************************************/
void delay(uchar t)
{
uchar i,j;
for(i=0;i
for(j=13;j>0;j--);
{ ; }
}
}
/**********使用定时器显示数字*********************/
void timer_display(uchar gw)
{
if(runmod==2)
{
z=setfen/10; //求分十位
x=setfen%10; //求分个位
c=setmiao/10; //求秒十位
v=setmiao%10; //求秒个位
}
else
{
z=runfen/10; //求分十位
x=runfen%10; //求分个位
c=runmiao/10; //求秒十位
v=runmiao%10; //求秒个位
}
if(gw==1 && (z>0 || runmod==2))
{
P2=wei[0];
if(runmod==2 && setwz==1)
{
if(flag)
{P0=duan[z];}
else
{P0=0xFF;}
}
else {P0=duan[z];}
}
else if(gw==2 && (x>0 || z>0 || runmod==2))
{
P2=wei[1];
if(runmod==2 && setwz==1)
{
if(flag)
{P0=duan[x];}
else
{P0=0xFF;}
}
else {P0=duan[x];}
}
else if(gw==3 && (c>0 || x>0 || runmod==2))
{
P2=wei[2];
if(runmod==2 && setwz==0)
{
if(flag)
{P0=duan[c];}
else
{P0=0xFF;}
}
else {P0=duan[c];}
}
else if(gw==4)
{
P2=wei[3];
if(runmod==2 && setwz==0)
{
if(flag)
{P0=duan[v];}
else
{P0=0xFF;}
}
else
{P0=duan[v];}
}
}
void Timer0_Init()
{
TMOD|=0X01;
TH0=60928/256;
TL0=60928%256;//每5ms进入一次中断
TF0=0;
TR0=1;
EA=1;
ET0=1; //TF0 如果这个标志为1,进入中断子函数
}
void tshow()
{
static char i=0;
i++;
timer_display(i);
if(i>=4)
{
i=0;
}
}
void TF0_isr() interrupt 1
{
TH0=60928/256;
TL0=60928%256;//重装初值
tshow();
}
void Timer1_Init()
{
TMOD|=0x10; //定时器1方式1,计数与否不受P3.3的影响
TH1=(65536-50000)/256; //50ms
TL1=(65536-50000)%256;
TF1=0;
ET1=1;
TR1=1;
}
void TF1_isr() interrupt 3
{
TH1=(65536-50000)/256; //50ms
TL1=(65536-50000)%256;
n_50ms++;
if(runmod==2)
{
n_50ms %= 5; //10对应1Hz
if(!n_50ms) flag = ~flag;
}
else if(runmod==1)
{
n_50ms %= 20; //
if(!n_50ms)
{
if(runmiao>0) runmiao--;
if(runmiao==0)
{
if(runfen>0)
{
runmiao=59;
runfen--;
}
}
if(runfen==0 && runmiao==0)
{
runmod=3; //状态改为到时
LEDRUN=0; //运行灯灭
LEDSTOP=1; //停止灯亮
}
}
}
else if(runmod==3) //到时,喇叭响
{
n_50ms %= 5; //10对应1Hz
if(!n_50ms)
{
LABA=!LABA;
}
}
}
void key() //按键扫描函数
{
if(runmod==0) //停止状态下
{
if(KEYSET==0) //设置键
{
delay(100);
if(KEYSET==0)
{
LEDSTOP=0;
LEDRUN=0;
LEDSET=1;
runmod=2;
setwz=0;
while (KEYSET==0)
{ delay(100);}
Timer1_Init();
}
}
else if(KEYRUN==0) //开始运行
{
delay(100);
if(KEYRUN==0)
{
runfen=setfen;
runmiao=setmiao;
runmod=1;
LEDSTOP=0;
LEDRUN=1;
LEDSET=0;
while (KEYRUN==0)
{ delay(100);}
Timer1_Init();
}
}
}
else if(runmod==1 || runmod==3) //运行或到时状态
{
if(KEYSTOP==0) //按下停止
{
delay(100);
if(KEYSTOP==0)
{
ET1=0;
TR1=0;
runmod=0;
LEDSTOP=1;
LEDRUN=0;
LEDSET=0;
LABA=0;
while (KEYSTOP==0)
{ delay(100);}
}
}
}
else if(runmod==2) //设置状态
{
if(KEYRUN==0) //前移
{
delay(10);
if(KEYRUN==0)
{
setwz++;
if(setwz>1) {setwz=0;}
while (KEYRUN==0){ delay(10);}
}
}
else if(KEYUP==0) //增加
{
delay(10);
if(KEYUP==0)
{
if(setwz==0)
{
if(setmiao<59) setmiao++;
else
setmiao=0;
}
else if(setwz==1)
{
if(setfen<99) setfen++;
else
setfen=0;
}
while (KEYUP==0) { delay(10);}
}
}
else if(KEYDOWN==0) //减少
{
delay(10);
if(KEYDOWN==0)
{
if(setwz==0)
{
if(setmiao>0) setmiao--;
else setmiao=59;
}
else if(setwz==1)
{
if(setfen>0) setfen--;
else setfen=99;
}
while (KEYDOWN==0) { delay(10);}
}
}
else if(KEYSET==0) //设置完成
{
delay(10);
if(KEYSET==0)
{
while (KEYSET==0) { delay(10);}
ET1=0;
EA=0;
TR1=0;
flag=1;
fs=setfen/10; //求分十位
fg=setfen%10; //求分个位
ms=setmiao/10; //求秒十位
mg=setmiao%10; //求秒个位
cc(0x2000);
xcx(0x2001,fs);
xcx(0x2002,fg);
xcx(0x2003,ms);
xcx(0x2004,mg);
Q0();
LEDSTOP=1;
LEDSET=0;
LEDRUN=0;
runmod=0;
Timer0_Init();
}
}
}
}
/*************************************************************************
主函数
**************************************************************************/
void main()
{
fs = dcx(0x2001); // 开机读取EEPROM区2002h数据
fg = dcx(0x2002);
ms = dcx(0x2003);
mg = dcx(0x2004);
setfen=fs*10+fg;
setmiao=ms*10+mg;
runmod=0;
LEDSET=0;
LEDSTOP=1;
LEDRUN=0;
LABA=0;
Timer0_Init();
flag=1;
setwz=0;
while(1)
{
key();
}
}
上一篇:STC单片机不重新加电烧写方法
史海拾趣
|
日前,全球著名的商店零售自动化解决方案供应商———NCR公司以鲜明的技术理念和完备的产品阵容在第七届中国连锁店展览会上展示了崭新的形象。其中NCR享誉全球的FastLaneTM自助结账系统、“RFID结账通道”及“ ...… 查看全部问答> |
|
请教一下,我用的是CODEVISION,AVR单片机。我申请了一个结构,运行结果发现不正确,在线仿真时,发现结构里面的变量盆地址不是按顺序分配的。有这方面经历或经验的朋友指导一下呀。 这个是我们的一个会员问的。在我的报到帖里,但是我没有用过这 ...… 查看全部问答> |
|
用DNW通过USB下载NK。BIN,有些可以成功下载下去,有些NK。BIN不管下载多少次都下不下去,进度条老是停在中间就没动静了,怎么一回事啊? 用DNW通过USB下载NK。BIN,有些可以成功下载下去,有些NK。BIN不管下载多少次都下不下去,进度条老是停在中间就没动静了,怎么一回事啊? 这些NK没什么区别,也就大小差个0。1MB的样子,好奇怪。你说不能下就都不能下,为什么有的可以有的又不行 ...… 查看全部问答> |
|
VGA和TFT的切换会是在哪里处理呢,BIOS还是应用程序? 个人感觉只有应用程序才能解决,因为切换过程中会造成屏幕模糊,有涉及到显卡驱动,但是为什么我关掉了所有可能的进程还是能够切换,不解,请高人指点一二。… 查看全部问答> |




