新建 DOC 文檔.doc
(42.5 KB, 下載次數: 3)
2019-11-10 17:05 上傳
點擊文件名下載附件
51hei圖片20191110170422.png (47.54 KB, 下載次數: 49)
下載附件
2019-11-10 17:05 上傳
請問如何將程序修改一下使LCD1602正確顯示
發現下載附件要花費黑幣,所以我把代碼發出來吧
- /****************************main.c************************************/
- #include <reg51.h>
- #include <intrins.h>
- #include <string.h>
-
- #define uchar unsigned char
- #define uint unsigned int
-
- uchar *week[] = {"sun","mon","tus","wes","thu","fri","sat"}; //周信息,周一到周日。
- uchar lcd_buf1[] = "00-00-00 "; //日期信息。
- uchar lcd_buf2[] = "00:00:00 "; //時間信息。
-
- extern void InitTIMER0();
- extern void lcd_init();
- extern void lcd_showstring(uchar ,uchar ,uchar *);
- extern uchar l_tmpdate[7];
- extern bit ReadRTC_Flag;
- extern void delay(uint i);
- extern void Read_RTC();
- extern void Set_RTC();
-
- //將日期和時間信息轉化為數字字符。
- void format_datetime(uint d,uchar * a)
- {
- *a=(d>>4)+'0';
- *(a+1)=(d&0x0f)+'0';
- }
-
- void main()
- {
- lcd_init(); //LCD的初始化。
- InitTIMER0(); //初始化定時器0。
- Set_RTC(); //寫入時鐘值(寫入時鐘初值),如果不用改時間可以不用這一項。
-
- while(1)
- {
- if(ReadRTC_Flag)
- {
- ReadRTC_Flag = 0;
- Read_RTC();
-
- //日期轉換。
- format_datetime(l_tmpdate[6],lcd_buf1+5);
- format_datetime(l_tmpdate[4],lcd_buf1+8);
- format_datetime(l_tmpdate[3],lcd_buf1+11);
- //星期轉換。
- strcpy(lcd_buf1 + 13,week[l_tmpdate[5]-1]);
- //定義一個字符串char a[20],和一個字符串c[]="i am a teacher!";
- //把c復制到a中就可以這樣用:strcpy(a,c);
-
- //時間轉換。
- format_datetime(l_tmpdate[2],lcd_buf2+5);
- format_datetime(l_tmpdate[1],lcd_buf2+8);
- format_datetime(l_tmpdate[0],lcd_buf2+11);
-
- lcd_showstring(0,0,lcd_buf1); //將lcd_buf1和lcd_buf2字符輸出。
- lcd_showstring(1,0,lcd_buf2);
-
- }
- }
- }
- /******************************************************************1602.h**************************************************************************/
- typedef bit bool;
-
- sbit RS = P2^6; //復位端
- sbit RW = P2^5; //寫數據端
- sbit EN = P2^7; //使能端
- #define uint unsigned int
- #define uchar unsigned char
-
- void delay(int i);
- bit lcd_bz();
- void lcd_wcmd(int cmd);
- void lcd_showstring(uchar r,uchar c,uchar *str);
- void lcd_wdat(uchar dat);
- void lcd_init();
- /******************************************************************1602.c***************************************************************************/
- #include <reg51.h>
- #include <intrins.h>
- #include "1602.h"
-
- //延時函數
- void delay(int i)
- {
- int j;
- while(i--)
- {
- for(j=0;j<250;j++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
-
- //側忙,判斷LCD是否為忙
- bool lcd_bz()
- {
- bool result;
- RS = 0;
- RW = 1;
- EN = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- result = (bool)(P0 & 0x80);//檢測P0最高位是否為1.
- EN = 0;
- return result; //返回判斷的結果。
- }
-
- //寫命令函數。
- void lcd_wcmd_8bit(int cmd)
- {
- while(lcd_bz());
- RS = 0;
- RW = 0;
- EN = 0; //先為低電平。
- _nop_();
- _nop_();
- P0 = cmd; //獲得數據。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 1; //將電平拉高。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 0; //再拉低。
- }
-
- //寫命令函數。
- void lcd_wcmd(int cmd)
- {
- while(lcd_bz());
- RS = 0;
- RW = 0;
- EN = 0; //先為低電平。
- _nop_();
- _nop_();
- P0 = cmd; //獲得高四位數據。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 1; //拉高。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 0; //再拉低。
-
- P0 = (cmd & 0x0f)<<4; //再獲得低四位數據。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 1; //將電平拉高。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 0; //再拉低。
- }
-
-
- void lcd_showstring(uchar r,uchar c,uchar *str)
- {
- uchar i=0;
- code uchar DDRAM[] = {0x80,0xc0}; //設定顯示的位置。
- lcd_wcmd(DDRAM[r] | c);
- for(i=0;str[i] && i<16;i++)
- lcd_wdat(str[i]);
- for(;i<16;i++)
- lcd_wdat(' ');
- }
-
- //數據寫入的函數。
- void lcd_wdat(uchar dat)
- {
- while(lcd_bz());
- RS = 1;
- RW = 0;
- EN = 0; //先處于低電平。
- P0 = dat; //獲得數據高四位。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 1;
- _nop_();
- _nop_(); //再產生一個負脈沖。
- _nop_();
- _nop_();
- EN = 0;
-
- RS = 1;
- RW = 0;
- EN = 0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- P0 = (dat & 0x0f)<<4; //同理獲得低四位。
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- EN = 0;
- }
-
- //LCD初始化。
- void lcd_init()
- {
- lcd_wcmd_8bit(0x38);
- delay(1);
- lcd_wcmd_8bit(0x38);
- delay(1);
- lcd_wcmd_8bit(0x38);
- delay(1);
- lcd_wcmd(0x38);
- delay(1);
- lcd_wcmd(0x0c);
- delay(1);
- lcd_wcmd(0x02);
- delay(1);
- lcd_wcmd(0x01);
- delay(1);
- }
- /****************************************************************ds1302.c****************************************************/
- #include <reg52.h>
- #include <intrins.h>
-
- sbit SCK = P3^6; //時鐘線
- sbit IO = P3^4; //數據線
- sbit RST = P3^5; //DS1302復位線
-
- bit ReadRTC_Flag; //讀DS1302的標志
- #define uint unsigned int
- #define uchar unsigned char
-
- //七項數據:秒分時日月周年
- uchar l_tmpdate[7] = {0,0,12,19,11,5,1};
- //用來存放轉化好的時間數據
- uchar l_tmpdisplay[8];
-
- //7個數據的寫地址
- code uchar write_rtc_add[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
- //7個數據的讀地址
- code uchar read_rtc_add[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
-
- //函數的聲明
- void Write_Ds1302_byte(uchar temp);
- void write_Ds1302(uchar add,uchar dat);
- uchar Read_Ds1302(uchar add);
- void Read_RTC();
- void Set_RTC();
- void InitTIMER0();
-
- //定時器的初始化
- void InitTIMER0()
- {
- TMOD |= 0x01;
- TH0 = 0xef;
- TL0 = 0xf0;
- ET0 = 1;
- TR0 = 1;
- EA = 1;
- }
-
- //向1302中發送一個字節數據。
- void Write_Ds1302_Byte(uchar temp)
- {
- uchar i;
- for(i=0;i<8;i++) //循環8位依次寫入數據
- {
- SCK = 0;
- IO = temp & 0x01; //傳輸時從低到高
- temp>>=1; //右移1位。
- SCK = 1;
-
- }
- }
-
- //向1302中寫入數據。參數有要寫入的地址和數據
- void Write_Ds1302(uchar add,uchar dat)
- {
- RST = 0;
- _nop_();
- SCK = 0;
- _nop_();
- RST = 1;
- _nop_();
- Write_Ds1302_Byte(add); //發送地址
- Write_Ds1302_Byte(dat); //發送數據
- RST = 0;
- }
-
- //從1302中的讀出數據
- uchar Read_Ds1302(uchar add)
- {
- uchar i,temp=0x00;
- RST = 0;
- _nop_();
- _nop_();
- SCK = 0;
- _nop_();
- _nop_();
- RST = 1;
- _nop_();
- _nop_();
- Write_Ds1302_Byte(add); //發送地址,找到地址
- for(i=0;i<8;i++) //循環8次讀出數據
- {
- if(IO) //傳輸從低到高
- temp |= 0x80;
- SCK = 0;
- temp>>=1; //右移1位
- _nop_();
- _nop_();
- _nop_();
- SCK = 1;
- }
- RST = 0; //之后為DS1302復位
- _nop_();
- _nop_();
- // RST = 0; //試驗時去掉該句沒有影響
- SCK = 0;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- SCK = 1;
- _nop_();
- _nop_();
- IO = 0;
- _nop_();
- _nop_();
- IO = 1;
- _nop_();
- _nop_();
- return temp; //將讀到的數據返回
- }
-
- //從時鐘中讀取數據
- void Read_RTC()
- {
- uchar i,*p;
- p = read_rtc_add; //讀日歷數據對應的地址
- for(i=0;i<7;i++) //分7次分別將:時分秒日月周年讀出
- {
- l_tmpdate[i] = Read_Ds1302(*p);
- p++;
- }
- }
-
- //設定時鐘的時間數據
- void Set_RTC()
- {
- uchar i,*p,tmp;
- for(i=0;i<7;i++) //將數從BCD碼轉化出來,因為1302中用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_add; //傳送地址
- for(i=0;i<7;i++) //將數據依次寫入
- {
- Write_Ds1302(*p,l_tmpdate[i]);
- p++;
- }
-
- Write_Ds1302(0x8e,0x80); //打開寫入保護,不能再寫入
- }
-
-
- //定時器中斷函數
- void tim() interrupt 1 using 1
- {
- static uchar i,num;
- TH0 = 0xf5;
- TL0 = 0xe0;
-
- i++;
-
- if(i==8)
- {
- i=0;
- num++;
- if(10==num) //間隔一定時間讀取1302中數據,更新數碼管數據
- {
- ReadRTC_Flag = 1; //置標志位,從而進行判斷
- num = 0;
- }
- }
- }
復制代碼 求大佬解答。
|