51单片机带字库液晶12864ds1302数字时钟c源程序无按键修改功能.docx
- 文档编号:6921066
- 上传时间:2023-01-12
- 格式:DOCX
- 页数:10
- 大小:17.08KB
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 #defineucharunsignedchar #defineuintunsignedint /*DS1302端口设置*/ sbitSCK=P3^6;//DS1302时钟 sbitSDA=P3^4;//DS1302IO sbitRST=P3^5;//DS1302复位 bitReadRTC_Flag;//读DS1302全局变量 /*12864端口定义*/ #defineLCD_dataP0//带字库液晶12864数据口 sbitLCD_RS=P2^4;//寄存器选择输入 sbitLCD_RW=P2^5;//液晶读/写控制 sbitLCD_EN=P2^6;//液晶使能控制 sbitPSB=P2^1;//并口控制 sbitRES=P2^3; ucharcodedis1[]={"电子设计天地"};//液晶显示的汉字ucharcodedis2[]={"有志者,事竟成! "}; 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++);}/*******************************************************************//**//*检查LCD忙状 态*/ /*lcd_busy为1时,忙,等待。 lcd-busy为0时,闲,可写指令与数据。 *//**//*******************************************************************/bitlcd_busy(){bitresult; LCD_RS=0; LCD_RW=1; LCD_EN=1; delayNOP(); result=(bit)(P0&0x80); LCD_EN=0; return(result);}/*******************************************************************//**//*写指令数据到 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=L,E=高脉冲,D0-D7=数据。 *//**//*******************************************************************/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(0x01);//清除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);//设置显示位置为第一行的第1个字符 i=0; while(dis1[i]! ='\0') {//显示字符 lcd_wdat(dis1[i]); i++;}lcd_pos(1,0);//设置显示位置为第二行的第1个字符i=0; while(dis2[i]! ='\0'){lcd_wdat(dis2[i]);//显示字符 i++;}lcd_pos(2,0); lcd_wdat(dis4[l_tmpdate[6]/16]);//DS1302是BCD码,进行处理得到十位与个位数。 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]); 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位 TH0=0xef;//初始化值 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 数字 时钟 源程序 按键 修改 功能