版主
主题
帖子
积分38239
阅读权限200
注册时间2009-11-23
最后登录1970-1-1
在线时间 小时
|
本帖最后由 199003326 于 2010-9-9 08:53 编辑
前段时间从坛友手里收了部手台,但是没充电器,于是就打算自己做一个,用IBM 16V笔记本电源供电,AT89C2051做主控,KIS-3R33模块降压提供单片机用5V,KIS-3R33模块做恒流,四位共阴数码管显示时间,由于I/O口少的可怜,最后只有一个按键了,所以就把按键定议成短按调时长按开始。
由于是第一个自己写的程序,虽说现已正常工作,但还是想让大家帮忙提提意见,毕竟俺是灰常菜灰常菜的菜菜鸟...
谢谢大家。
使用2051的T0计时,P1接数码管段选,P3.0-3.3接数码管位选,P3.5接按键,P3.7接恒流模块使能端。
#include <REG2051.H>
#define uint unsigned int
#define uchar unsigned char
sbit LED0=P3^0; //数码管位定义
sbit LED1=P3^1;
sbit LED2=P3^2;
sbit LED3=P3^3;
sbit key=P3^5;
sbit power=P3^7;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //第10为不显示
uint times;
uchar hour,min,sec;
bit secflag;
void init()
{
TR0=0; //定时器T0设置,24M晶振,25ms进一次中断
TMOD=0x11;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
hour=8; //上电默认时间8小时
min=0;
sec=0;
secflag=0; //用于秒点闪烁
power=0; //上电时不充电
}
void delay(uint x) //延时程序,晶振为24M
{
uint y,z;
for(y=x;y>0;y--)
for(z=220;z>0;z--);
}
void display(uchar hour,uchar min) //动态扫描显示程序
{
uchar hs,hg,ms,mg;
hs=hour/10;
hg=hour%10;
ms=min/10;
mg=min%10;
if (hs==0) //如果小时十位是0的话,不显示
hs=10;
LED0=0;
P1=table[hs];
delay(2);
LED0=1;
P1=0;
LED1=0;
P1=table[hg]+0x80; //+0x80,让小时个位的小数点常亮
delay(2);
LED1=1;
P1=0;
LED2=0;
P1=table[ms];
delay(2);
LED2=1;
P1=0;
LED3=0;
P1=table[mg];
delay(2);
LED3=1;
P1=0;
if(secflag==1) //分种个位小数点每0.5秒取反一次,用于显示计时状态
{
LED3=0;
P1=0x80;
delay(2);
LED3=1;
P1=0;
}
}
void keyscan() //按键扫描程序
{
uint keynum;
if (key==0)
{
delay(5);
while(key==0) //按下键后keynum累加,在后边判断其数值,得知是长按还是短按
{
keynum++;
delay(1);
}
if (keynum<800) //短按
{
keynum=0;
hour++;
if(hour>24) //最长计时24小时
hour=0;
}
else
{
TR0=1; //长按启动计时
power=1; //启动充电电源
}
}
}
void main()
{
init();
while(1)
{
display(hour,min);
keyscan();
}
}
void timer0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
times++;
if((times%20)==0) //半秒secflag取反一次,用于秒点闪烁
{
secflag=~secflag;
}
if (times>40) //一秒种sec++一次
{
times=0;
sec++;
if(sec>59)
{
sec=0;
min--;
if(min>60)
{
min=59;
hour--;
}
if(hour==0)
if(min==0) //判断是否结束
{
TR0=0;
power=0;
}
}
}
} |
|