51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能.docx
- 文档编号:4818848
- 上传时间:2022-12-09
- 格式:DOCX
- 页数:10
- 大小:18.75KB
51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能.docx
《51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能.docx》由会员分享,可在线阅读,更多相关《51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能.docx(10页珍藏版)》请在冰豆网上搜索。
51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能
51单片机+带字库液晶12864+DS1302数字时钟C源程序(无按键修改功
能)过两天的搜索与调试,在别人程序的基础上,不断修改,终于调试成功了这个程序。
目前还不能修改时间与日期,只是以预定时间以始。
适用于开发板:
51单片机(AT89S52+带字库液晶
12864(ST7920)+DS1302实时时钟)
实现功能:
简单,数字时钟+日期(以后会不断完美)。
C语言源程序如下:
#include 52.h> #include //DS1302时钟 //DS1302IO //DS1302复位 //读DS1302全局变量 /*DS1302端口设置*/ sbitSCK=P3A6; sbitSDA=P3A4; sbitRST=P3A5; bitReadRTC_Flag; //带字库液晶12864数据口 //寄存器选择输入 //液晶读/写控制 /*12864端口定义*/#defineLCD_dataP0sbitLCD_RS=P2A4; sbitLCD_RW=P2A5; sbitLCD_EN=P2A6;//液晶使能控制 sbitPSB二卩2八1;//并口控制 sbitRES=P2A3; ucharcodedis1[]={"电子设计天地"};//液晶显示的汉字ucharcode dis2[]={"有志者,事竟成! "}; ucharcodedis4[]={'0','1','2','3','4','5','6','7','8','9'};unsignedchartemp; #definedelayNOP();{_nop_();_nop_();_nop_();_nop_();}; voidlcd_pos(ucharX,ucharY);//确定显示位置 unsignedcharl_tmpdate[7]={0,7,16,19,10,1,9};〃秒分时日月周年09-10-1916: 07: 00 codeunsignedchar write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//秒分时日月周年最低位读写位 codeunsignedchar read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; voidWrite_Ds1302_byte(unsignedchartemp); voidWrite_Ds1302(unsignedcharaddress,unsignedchardat);unsignedcharRead_Ds1302(unsignedcharaddress); voidRead_RTC(void);//readRTC voidSet_RTC(void);//setRTC voidInitTIMER0(void);//initaltimer0 /***************************************************************** **//* *//*延时函数*//**//*******************************************************************/voiddelay(unsignedintm)//延时程序{unsignedinti,j; for(i=0;i for(j=0;j<10;j++);}/* **************** ************************************************* *// return(result);}/ ************** *//*检查LCD忙状 态*/ /*lcd_busy为1时,忙,等待。 Icd-busy为0时,闲,可写指令与数据。 *//******************************************************************* /bitlcd_busy(){bitresult; LCD_RS=0; LCD_RW=1; LCD_EN=1; delayNOP(); result=(bit)(P0&0x80); LCD_EN=0; **************************************************** *//*写指令数据到 LCD*/ /*RS=L,RW=L,E二高脉冲,D0-D7=^|令码。 *//* *//******************************************************************* /voidlcd_wcmd(ucharcmd){while(lcd_busy()); LCD_RS=0; LCD_RW=0; LCD_EN=0; _nop_(); _nop_(); P0=cmd; delay (1); LCD_EN=1; delay (1); LCD_EN= 0;}/****************************************************************** *//* *//*写显示数据到 LCD*/ /*RS=H,RW=LE镐脉冲,。 0-。 7=数据。 *//**//*******************************************************************/voidlcd_wdat(uchardat){while(lcd_busy()); LCD_RS=1; LCD_RW=0; LCD_EN=0; P0=dat; delayNOP(); LCD_EN=1; delay (1); LCD_EN= 0;}/ *******************************************************************//*//*LCD初始化设定*// /voidlcd_init(){P0=0xFF; P2=0xFF; delay (40); PSB=1;//并口方式。 delay (1); RES=0; delay (1); RES=1; delay (10); lcd_wcmd(0x30); delay (100); lcd_wcmd(0x30); delay (37); lcd_wcmd(0x08); delay (100); lcd_wcmd(0x10); delay (100); lcd_wcmd(0x0C);//显示开,关光标delay (100); lcd_wcmd(OxO1);//清除LCD的显示内容 delay (100); lcd_wcmd(0x06); delay (100);}voidmain(){uchari; InitTIMER0(); Set_RTC(); lcd_init(); //初始化LCD while (1){if(ReadRTC_Flag){ReadRTC_Flag=0; Read_RTC();lcd_pos(0,0); i=0; while(dis1[i]! ='\0'){lcd_wdat(dis1[i]);i++;}lcd_pos(1,0); //设置显示位置为第一行的第1个字符 //显示字符 //设置显示位置为第二行的第1个字符i=0; while(dis2[i]! ='\0'){lcd_wdat(dis2[i]); i++;}lcd_pos(2,0);lcd_wdat(dis4[l_tmpdate[6]/16]); 得到十位与个位数。 lcd_pos(2,1);lcd_wdat(dis4[l_tmpdate[6]%16]); lcd_pos(2,2); lcd_wdat('-'); lcd_pos(2,3);lcd_wdat(dis4[l_tmpdate[4]/16]); //显示字符 //DS1302是BCD码,进行处理 lcd_pos(2,4); lcd_wdat(dis4[l_tmpdate[4]%16]); lcd_pos(2,5); lcd_wdat('-'); lcd_pos(2,6); lcd_wdat(dis4[l_tmpdate[3]/16]); lcd_pos(2,7); lcd_wdat(dis4[l_tmpdate[3]%16]);//设置显示位置为第三行的第 1个字符 lcd_pos(3,0);//设置显示位置为第四行的第1个字符 lcd_wdat(dis4[l_tmpdate[2]/16]); lcd_pos(3,1); lcd_wdat(dis4[l_tmpdate[2]%16]); lcd_pos(3,2); lcd_wdat(': '); lcd_pos(3,3); lcd_wdat(dis4[l_tmpdate[1]/16]); lcd_pos(3,4); lcd_wdat(dis4[l_tmpdate[1]%16]); lcd_pos(3,5); lcd_wdat(': '); lcd_pos(3,6); lcd_wdat(dis4[l_tmpdate[0]/16]); *********************************** lcd_pos(3,7); lcd_wdat(dis4[l_tmpdate[0]%16]);}}}/********************** */ */ /* /*设定显示位置*/ /* /*********************************************************/ voidlcd_pos(ucharX,ucharY){ucharpos; if(X==0) {X=0x80;} elseif(X==1) {X=0x90;} elseif(X==2) {X=0x88;} elseif(X==3) {X=0x98;} pos=X+Y; lcd_wcmd(pos);//显示地址}voidInitTIMER0(void){TMOD|=0x01;〃定时器设置16位 THO=Oxef;〃初始化值 TL0=0xf0; ET0=1; TR0=1; EA=1;}voidWrite_Ds1302_Byte(unsignedchartemp){unsignedchari;for(i=0;i<8;i++)//循环8次写入数据{SCK=0; SDA=temp&0x01;//每次传输低字节 temp>>=1;//右移一位 SCK=1;}} /***************************************************************** ***********/ voidWrite_Ds1302(unsignedcharaddress,unsignedchardat){RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_();//启动 Write_Ds1302_Byte(address);//发送地址 Write_Ds1302_Byte(dat);//发送数据 RST=0;//恢 复}/****************************************************************** **********/ unsignedcharRead_Ds1302(unsignedcharaddress){unsignedchari,temp=0x00; RST=0; _nop_(); SCK=0;_nop_(); RST=1; _nop_(); Write_Ds1302_Byte(address); for(i=0;i<8;i++)//循环8次读取数据{if(SDA) temp|=0x80;//每次传输低字节 SCK=0; temp>>=1;//右移一位 SCK=1;}RST=0; _nop_();//以下为DS1302复位的稳定时间 RST=0; SCK=0; _nop_(); SCK=1; _nop_(); SDA=0; _nop_(); SDA=1; _nop_(); return(temp);//返 回}/* ***************************************************************** ********** voidRead_RTC(void)//读取日历{unsignedchari,*p; p=read_rtc_address;//地址传递 for(i=0;i<7;i++)//分7次读取秒分时日月周年{l_tmpdate[i]=Read_Ds1302(*p); p++;}} /***************************************************************** ******/ voidSet_RTC(void)//设定日历{unsignedchari,*p,tmp; for(i=0;i<7;i++){//BCD处理 tmp=l_tmpdate[i]/10; l_tmpdate[i]=l_tmpdate[i]%10; l_tmpdate[i]=l_tmpdate[i]+tmp*16;}Write_Ds1302(0x8E,0X00); p=write_rtc_address;//传地址 for(i=0;i<7;i++)//7次写入秒分时日月周年{Write_Ds1302(*p,l_tmpdate[i]); p++;}Write_Ds1302(0x8E,0x80);}voidtim(void)interrupt1using1//中断,用于数码管扫描{staticunsignedchari,num; TH0=0xf5; TL0=0xe0; //P0=table[l_tmpdisplay[i]];//查表法得到要显示数字的数码段//P2=table1[i]; i++;if(i==8){i=0;num++; if(20==num)//隔段时间读取1302的数据。 时间间隔可以调整{ReadRTC_Flag=1;/使/用标志位判断num=0;}}}/*****END************/以上经过在开发板上调试OK。 下面讲一下调试经验与大家分享。 首先用液晶显示DS1302分三步走。 第一步: 搞清楚液晶12864(带字库,方便使用),也就是怎样让其显示汉字及字符。 第二步: 搞清楚DS1302怎样用,怎样写入与显示出时间数据。 第三步: 把上面两步程序合在一起进行调试,当然要注意各端口的定义与连接。 这里并不能修改时间日期,以后会进一步研究。 总之,在液晶显示学习上又进一步了。 路要一步步走。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 字库 液晶 12864 ds1302 数字 时钟 源程序 按键 修改 功能