求lm016l与ds1302 52 单片机实现时钟显示的程序

求lm016l与ds1302 52 单片机实现时钟显示的程序,第1张

#define LCM_RW P2^4 //定义引脚

#define LCM_RS P2^3

#define LCM_EP2^5

#define LCM_Data P0

#define Busy 0x80 //用于检测LCM状态字中的Busy标识

#include <reg52.h>

void WriteDataLCM(unsigned char WDLCM)

void WriteCommandLCM (unsigned char WCLCM,BuysC)

void DisplayOneChar (unsigned char X, unsigned char Y, unsigned char DData)

void DisplayListChar (unsigned char X, unsigned char Y, unsigned char code *DData)

unsigned char ReadDataLCM(void)

unsigned char ReadStatusLCM(void)

void pro_timedate(void)

bit leap_year()//判断是否为闰年

unsigned char data year=11,month=5,date=22//年、月、日、星期

unsigned char disbuf[16]

unsigned char data hour=23,min=59,sec=55,sec20=0//时、分、秒、百分之一秒

unsigned char code email[] = {"YEA:MON:DAT:TIME"}

void updatetime (void)

void LCMInit(void)

void pro_display(void)

void Delay400Ms (void)

void Delay5Ms (void)

void main(void)

{

Delay400Ms()//启动等待,等LCM讲入工作状态

LCMInit()//LCM初始化

DisplayListChar(0, 1, email)

TMOD=0X01

TH0=0X4C

TL0=0X00

TR0=1

ET0=1

EA=1

while(1)

}

void pro_timedate()

{

sec++

if(sec >59)

{sec = 0

min++

if(min>59)

{min=0

hour++

if(hour>23)

{hour=0

date++

if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)

if (date>31)

{date=1month++} //大月31 天

if (month==4||month==6||month==9||month==11)

if (date>30)

{date=1month++} //小月30 天

if (month==2)

{if( leap_year()) //闰年的条件

{if (date>29) {date=1month++}} //闰年2 月为29 天

else

{if (date>28) {date=1month++}} //平年2 月为28 天

}

if (month>12) {month=1year++}

if (year>99) year=0

}

}

}

}

bit leap_year()

{

bit leap

if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件

leap=1

else

leap=0

return leap

}

//Timer0 中断处理程序,秒的产生

void timer0() interrupt 1

{

TH0=0x4C//Timer0 置10ms 定时初值dc00H(2^16=65536D,dc00H=56320D)

TL0=0x00//定时时间=(65536-56320)*(1/11.0592)*12=10ms (f0=11.0592Mhz)

sec20++

if(sec20 >= 20) //1 秒时间 (100*10ms=1000ms=1s)

{ sec20=0

updatetime ()

pro_timedate()

pro_display ()

if(sec&0x01)

disbuf[13]=' '

else disbuf[13]=':'

}

}

void updatetime(void)

{ disbuf[0] ='2'

disbuf[1] ='0'

disbuf[2] =year/10+48

disbuf[3] =year%10+48

disbuf[4] =' '

disbuf[5] =month/10+48

disbuf[6] =month%10+48

disbuf[7] ='.'

disbuf[8] =date/10+48

disbuf[9] =date%10+48

disbuf[10] =' '

disbuf[11]=hour/10+48

disbuf[12]=hour%10+48

//disbuf[13]=' '

disbuf[14]=min/10+48

disbuf[15]=min%10+48

}

//显示处理程序

void pro_display()

{ unsigned char f

for (f=0f<=15f++)

{DisplayOneChar( f, 0, disbuf[f])}

}

//写数据

void WriteDataLCM(unsigned char WDLCM)

{

ReadStatusLCM()//检测忙

//WDLCM = ((WDLCM&0x01)<<7)|((WDLCM&0x02)<<5)|((WDLCM&0x04)<<3)|((WDLCM&0x08)<<1)|((WDLCM&0x10)>>1)|((WDLCM&0x20)>>3)|((WDLCM&0x40)>>5)|((WDLCM&0x80)>>7)

LCM_Data = WDLCM

LCM_RS = 1

LCM_RW = 0

LCM_E = 0

LCM_E = 0//延时

LCM_E = 1

}

//写指令

void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测

{

if (BuysC) ReadStatusLCM()//根据需要检测忙

//WCLCM = ((WCLCM&0x01)<<7)|((WCLCM&0x02)<<5)|((WCLCM&0x04)<<3)|((WCLCM&0x08)<<1)|((WCLCM&0x10)>>1)|((WCLCM&0x20)>>3)|((WCLCM&0x40)>>5)|((WCLCM&0x80)>>7)

LCM_Data = WCLCM

LCM_RS = 0

LCM_RW = 0

LCM_E = 0

LCM_E = 0

LCM_E = 1

}

//读数据

unsigned char ReadDataLCM(void)

{

LCM_RS = 1

LCM_RW = 1

LCM_E = 0

LCM_E = 0

LCM_E = 1

return(LCM_Data)

}

//读状态

unsigned char ReadStatusLCM(void)

{

LCM_Data = 0xFF

LCM_RS = 0

LCM_RW = 1

LCM_E = 0

LCM_E = 0

LCM_E = 1

while (LCM_Data &Busy)//检测忙信号

return(LCM_Data)

}

void LCMInit(void) //LCM初始化

{

LCM_Data = 0

WriteCommandLCM(0x38,0)

1

//三次显示模式设置,不检测忙信号

Delay5Ms()

WriteCommandLCM(0x38,0)

Delay5Ms()

WriteCommandLCM(0x38,0)

Delay5Ms()

WriteCommandLCM(0x38,1)//显示模式设置,开始要求每次检测忙信号

WriteCommandLCM(0x08,1)//关闭显示

WriteCommandLCM(0x01,1)//显示清屏

WriteCommandLCM(0x06,1)// 显示光标移动设置

WriteCommandLCM(0x0C,1)// 显示开及光标设置

}

//按指定位置显示一个字符

void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)

{

Y &= 0x1

X &= 0xF//限制X不能大于15,Y不能大于1

if (Y) X |= 0x40//当要显示第二行时地址码+0x40

X |= 0x80//算出指令码

WriteCommandLCM(X, 0)//这里不检测忙信号,发送地址码

WriteDataLCM(DData)

}

//按指定位置显示一串字符

void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)

{

unsigned char ListLength

ListLength = 0

Y &= 0x1

X &= 0xF//限制X不能大于15,Y不能大于1

while (DData[ListLength]>0x20) //若到达字串尾则退出

{

if (X <= 0xF) //X坐标应小于0xF

{

DisplayOneChar(X, Y, DData[ListLength])//显示单个字符

ListLength++

X++

}

}

}

//50ms延时

void Delay5Ms(void)

{

unsigned int TempCyc = 5552

while(TempCyc--)

}

//400ms延时

void Delay400Ms(void)

{

unsigned char TempCycA = 5

unsigned int TempCycB

while(TempCycA--)

{

TempCycB=7269

while(TempCycB--)

}

}

1行的LCD和 LCD1602 驱动是一样的。。。。1602的代码,网上参考很多。。。

先把键盘判断的去掉,驱动好LCD,再做键盘部分。。。

LCD 写成这样,要方便很多

/********************************************************************

* 名称 : L1602_char(uchar hang,uchar lie,char sign)

* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符显示"b" ,调用该函数如下

L1602_char(1,5,'b')

* 输入 : 行,列,需要输入1602的数据

* 输出 : 无

***********************************************************************/

void L1602_char(uchar hang,uchar lie,char sign){

uchar a

if(hang == 1) a = 0x80

if(hang == 2) a = 0xc0

a = a + lie - 1

writecode(a)

writedata(sign)

}

/********************************************************************

* 名称 : L1602_string(uchar hang,uchar lie,uchar *p)

* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下

L1602_string(1,5,"ab cd ef")

* 输入 : 行,列,需要输入1602的数据

* 输出 : 无

***********************************************************************/

void L1602_string(uchar hang,uchar lie,uchar *p){

uchar a

if(hang == 1) a = 0x80

if(hang == 2) a = 0xc0

a = a + lie - 1

writecode(a)

while(1){

if(*p == '\0') break

writedata(*p)

p++

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/11060249.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-13
下一篇 2023-05-13

发表评论

登录后才能评论

评论列表(0条)

保存