基于stc89c52rc单片机的数字钟设计程序
与数字中的数码管显示类似,
增加:
液晶初始化部分
写命令部分
写数据部分
********************************************************
#includereg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs = P2^6; //1602相应
sbit rw = P2^5;
sbit ep = P2^7;
uchar hour,min,sec,k;
uchar key;
unsigned char lcdd[]="0123456789";
uchar key_code[] = {0xb7,0xbb,0xbd,0xbe};//键盘编码,我只用到四个键。 你我的编码可能不同 ,具体看电路如何连接。
void delay(uint z)
{
uint x,y;
for(z=x;x>0;x--)
for(y=100;y>0;y--);
}
bit lcd_bz()
{ // 测试LCD忙碌状态
bit result;
rs = 0;
rw = 1;
ep = 1;
delay(5);
result = (bit)(P0 0x80);//判断P0^7是一还是零.屏蔽掉其它位0x80.强制转换位bit型数据。在返回给result。
ep = 0;
return result;
}
void lcd_cmd(uchar cmd)
{
while(lcd_bz());
rs = 0;//rs为1时写入的是“数据”为0时写入“指令”
rw = 0;//rw为1时“读取”为0时“写入”
ep = 0;//使能
delay(5);
P0 = cmd;
delay(5);
ep = 1;
delay(5);
ep = 0;
}
void lcd_data(uchar dat )//液晶写数据
{
while(lcd_bz());
rs=1;
rw=0;
ep=0;
P0 = dat;
delay(5);
ep = 1;
delay(5);
ep = 0;
//return dat;
}
void lcd_init() //液晶写命令
{
delay(15); //等待LCD电源稳定
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x38);
delay(10);
lcd_cmd(0x0c); //显示开,关光标
delay(10);
lcd_cmd(0x06); //移动光标
delay(10);
lcd_cmd(0x01); //清除LCD的显示内容
delay(10);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
k++;
if(k==20)
{
k=0;
sec++;
}
if(sec>59)
{
min++;
sec=0;
}
if(min>59)
{
min=0;
hour++;
}
if(hour>23)
{
hour=0;
}
}
void disptime() //时间显示函数
{
lcd_cmd(0x0c); //设置光标不显示、不闪烁
delay(20);
lcd_cmd(0x80); //起始显示地址
delay(20);
lcd_data(lcdd[hour/10]);
delay(10);
lcd_data(lcdd[hour%10]);
delay(10);
lcd_data(':');
delay(12);
lcd_data(lcdd[min/10]);
delay(10);
lcd_data(lcdd[min%10]);
delay(12);
lcd_data(':');
delay(12);
lcd_data(lcdd[sec/10]);
delay(12);
lcd_data(lcdd[sec%10]);
delay(12);
lcd_data(' ');
delay(12);
}
uchar keyscan() //键盘扫描程序
{
uchar scan1, scan2, keycode, j;
P1 = 0xf0;
scan1 = P1;
if (scan1 != 0xf0)
//判键是否按下
{
delay(10); //延时10ms
scan1 = P1;
if (scan1 != 0xf0)
//二次判键是否按下
{
TR0=0; //如果有键按下 则定时器停止工作
P1 = 0x0f;
scan2 = P1;
keycode = scan1 | scan2; //组合成键扫描编码
for (j = 0; j 4; j++)
{
if (keycode == key_code[j])
//查表得键值
{
key = j;
while(P1!= 0x0f) //松手有效 这里需要好好研究一下 可以用万用表测量管脚电压帮助理解
disptime();
return (key); //返回有效键值
}
}
}
}
else
P1 = 0xff;
return (key = 4); //返回无效码
}
void Set_time(uchar key)
{
if(key==0||key==1||key==2)//若s1,s2,s3其中有键按下,则为真
{
if(key==0)
{
sec++;
if(sec>59)
{
sec=0;
}
}
else if(key==1)
{
min++;
if(min>59)
{
min=0;
}
}
else if(key==2)
{
hour++;
if(hour>23)
{
hour=0;
}
}
}
else if(key==3)
{
TR0=1; //按下退出键 定时器继续工作
}
}
void sysint() //定时器初始化
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timeint() //初始化
{
hour=0;
min=0;
sec=0;
}
void main()
{
sysint() ;
timeint();
lcd_init();//函数调用
while(1)
{
keyscan();//调用键盘扫描,
Set_time(key);
disptime();
}
}
stc89c52rc 数字钟 数码管 相关文章:
- 从易到难学习单片机(单片机DIY制作、毕业设计、课程实例)(06-04)
- 初始的STC89C52RC单片机小实验(12-03)
- STC89C52RC单片机8位流水灯程序(11-29)
- 单片机STC89C52RC内部EEPROM(11-26)
- STC89C52RC特点及引脚介绍(11-25)
- 基于STC89C52RC+TEA5767的收音机(10-15)