液晶屏+ds1302自動顯示
單片機源程序如下:
- /*頭文件*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- /*引腳端口定義*/
- sbit lcd_psb=P3^7;
- sbit LCD12864_RS_PORT=P3^5; /*LCD12864引腳定義*/
- sbit LCD12864_RW_PORT=P3^6;
- sbit LCD12864_E_PORT=P3^4;
- #define LCD12864_DA_PORT P0
- sbit dula=P2^6; //數碼管的段選信號
- sbit DQ=P2^2; //定義DS18B20通信端口
- sbit Beep=P2^3; //蜂鳴器通信端口
- sbit T_CLK=P1^7; /*ds1302實時時鐘時鐘線引腳 */
- sbit T_IO=P2^4; /*ds1302實時時鐘數據線引腳 */
- sbit T_RST=P1^6; /*ds1302實時時鐘復位線引腳 */
- sbit ACC0=ACC^0; /*ds1302位尋址寄存器*/
- sbit ACC7=ACC^7;
-
- uchar code num_to_char[]={"0123456789"};/*數字轉換為ASCII字符碼*/
- uchar code Week1_to_char[]={"一"};
- uchar code Week2_to_char[]={"二"};
- uchar code Week3_to_char[]={"三"};
- uchar code Week4_to_char[]={"四"};
- uchar code Week5_to_char[]={"五"};
- uchar code Week6_to_char[]={"六"}; /*星期數字轉換為漢字的ASCII碼*/
- uchar code Week7_to_char[]={"日"};
- uchar hanzi_buff1[]={" 年 月 日 "};//0-15
- uchar hanzi_buff2[]={" 星期 "};
- uchar hanzi_buff3[]={" : : "};
- uchar hanzi_buff4[]={"當前溫度: . 度"};
- uchar data time_data_buff[7]={0x00,0x00,0x12,0x01,0x12,0x06,0x17};/*格式為: 秒 分 時 日 月 星期 年 */
- /*1MS為單位的延時程序*/
- void delay_1ms(uchar x)
- {
- uchar j;
- while(x--){
- for(j=0;j<125;j++)
- {;}
- }
- }
- void beep()
- {
- Beep=0;
- delay_1ms(2000);
- Beep=1;
- }
- ////////////////////以下是時鐘讀取程序/////////////////
- /********************************************************************
- 函 數 名:InputByte()
- 功 能:實時時鐘寫入一字節
- 說 明:往DS1302寫入1Byte數據 (內部函數)
- 入口參數:d 寫入的數據
- 返 回 值:無
- ***********************************************************************/
- void InputByte(uchar d)
- {
- uchar i;
- ACC=d;
- for(i=8;i>0;i--)
- {
- T_IO=ACC0; /*相當于匯編中的 RRC */
- T_CLK=1;
- T_CLK=0;
- ACC=ACC>>1;
- }
- }
- /********************************************************************
- 函 數 名:OutputByte()
- 功 能:實時時鐘讀取一字節
- 說 明:從DS1302讀取1Byte數據 (內部函數)
- 入口參數:無
- 返 回 值:ACC
- ***********************************************************************/
- uchar OutputByte()
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- ACC=ACC>>1; /*相當于匯編中的 RRC */
- ACC7=T_IO;
- T_CLK=1;
- T_CLK=0;
- }
- return(ACC);
- }
- /********************************************************************
- 函 數 名:W1302()
- 功 能:往DS1302寫入數據
- 說 明:先寫地址,后寫命令/數據 (內部函數)
- 調 用:RTInputByte() , RTOutputByte()
- 入口參數:ucAddr: DS1302地址, ucData: 要寫的數據
- 返 回 值:無
- ***********************************************************************/
- void W1302(uchar ucAddr, uchar ucDa)//先寫命令字,再寫數據
- {
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- InputByte(ucAddr); /* 地址,命令 */
- InputByte(ucDa); /* 寫1Byte數據*/
- T_CLK=1;
- T_RST=0;
- }
- /********************************************************************
- 函 數 名:Set1302()
- 功 能:設置初始時間
- 說 明:先寫地址,后讀命令/數據(寄存器多字節方式)
- 調 用:W1302()
- 入口參數:pClock: 設置時鐘數據地址 格式為: 秒 分 時 日 月 星期 年
- 7Byte (BCD碼)1B 1B 1B 1B 1B 1B 1B
- 返 回 值:無
- ***********************************************************************/
- void Set1302(uchar *pClock) //指針指向time_data_buff數組
- {
- uchar i;
- uchar ucAddr=0x80;
- //EA=0;
- W1302(0x8e,0x00);/*對寫保護寄存器操作,0x8e寫保護寄存器寫命令字,0x00使該寄存器最高位WP=0時間日歷寄存器可進行寫操作*/
- //W1302(0x90,0xa6);
- for(i=7;i>0;i--)
- {
- W1302(ucAddr,*pClock); //秒 分 時 日 月 星期 年 ucAddr先為0x80,此地址為秒寄存器寫控制命令字
- pClock++;
- ucAddr+=2; //每次加2分別進入分、時、日。。。年寫命令字
- }
- W1302(0x8e,0x80); /* 控制命令,WP=1,寫保護,此后時鐘寄存器不斷變化*/
- //EA = 1;
- }
- /********************************************************************
- 函 數 名:R1302()
- 功 能:讀取DS1302某地址的數據
- 說 明:先寫地址,后讀命令/數據 (內部函數)
- 調 用:RTInputByte() , RTOutputByte()
- 入口參數:ucAddr: DS1302地址
- 返 回 值:ucData :讀取的數據
- ***********************************************************************/
- uchar R1302(uchar ucAddr)//先寫命令字,再讀數據
- {
- uchar ucData;
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- InputByte(ucAddr); /* 地址,命令 */
- ucData=OutputByte(); /* 讀1Byte數據 */
- T_CLK=1;
- T_RST=0;
- return(ucData);
- }
- /********************************************************************
- 函 數 名:Now1302()
- 功 能:讀取DS1302當前時間
- 說 明:
- 調 用:R1302()
- 入口參數:ucCurtime: 保存當前時間地址。當前時間格式為: 秒 分 時 日 月 星期 年
- 7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
- 返 回 值:無
- ***********************************************************************/
- void Now1302(uchar ucCurtime[])
- {
- uchar i;
- uchar ucAddr=0x81;
- //EA=0;
- for (i=0;i<7;i++)
- {
- ucCurtime[i]=R1302(ucAddr);/*格式為: 秒 分 時 日 月 星期 年 */
- ucAddr+=2;
- }
- //EA=1;//考慮保持總中斷開啟
- }
- void delay(uint i)
- {
- while(i--);
- }
- //////////////////以下是DS18B20驅動程序////////////////
- void Init_DS18B20()//初始化函數
- {
- unsigned char x=0;
- DQ = 1; //DQ復位
- delay(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay(80); //精確延時 大于 480us
- DQ = 1; //拉高總線
- delay(14);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- DQ=1;
- }
- uchar ReadOneChar()//讀一個字節
- {
- uchar i;
- uchar dat=0;
- for(i=8;i>0;i--)
- {
- DQ=0; // 給脈沖信號
- dat>>=1;
- DQ=1; // 給脈沖信號
- if(DQ)
- dat|=0x80; //利用0x80將溫度數據賦給dat
- delay(4);
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)//寫一個字節
- {
- uchar i=0;
- for (i=8;i>0;i--){
- DQ=0;
- DQ=dat&0x01;
- delay(5);
- DQ=1;
- dat>>=1;
- }
- }
- uint ReadTemperature()//讀取溫度,注意返回值為16bit
- {
- uchar a=0;
- uchar b=0;
- uint t=0;
- float tt=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號列號的操作
- WriteOneChar(0x44); // 啟動溫度轉換
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- a=ReadOneChar();
- b=ReadOneChar();
- t=b;
- t<<=8;
- t=t|a; //將溫度的高位與低位合并
- tt=t*0.0625;
- t=tt*10+0.5; //對結果進行4舍5入
- return(t);
- }
- //////////////////以下是LCD12864驅動程序////////////////
- void LCD12864_WaitIdle()
- //LCD12864 忙 信號檢測
- {
- LCD12864_DA_PORT = 0xff;
- LCD12864_RS_PORT = 0;
- LCD12864_RW_PORT = 1;
- LCD12864_E_PORT = 1;
- while((LCD12864_DA_PORT&0x80)==1); /*等待BF 不為1*/
- LCD12864_E_PORT = 0;
- }
- void LCD12864_COM_Write( uchar com_da) /* 檢測忙信號寫入命令字 com_da 為待寫入的命令字*/
- {
- LCD12864_WaitIdle();
- LCD12864_RS_PORT = 0;
- LCD12864_RW_PORT = 0;
- LCD12864_DA_PORT = com_da;
- LCD12864_E_PORT = 1;
- delay_1ms(1);
- LCD12864_E_PORT = 0;
- }
- void LCD12864_NoWaitIdle_COM_Write(uchar com) /*不檢測忙信號寫入命令字,com_da 為待寫入的命令字*/
- {
- LCD12864_RS_PORT=0; //0寫命令
- LCD12864_RW_PORT=0;
- LCD12864_E_PORT=0;
- LCD12864_DA_PORT=com;
- delay_1ms(1);
- LCD12864_E_PORT=1;
- delay_1ms(1);
- LCD12864_E_PORT=0;
- }
- void LCD12864_Data_Write(uchar da) /*數據寫入 da為待寫入8位數據*/
- {
- LCD12864_WaitIdle(); /*檢測忙信號*/
- LCD12864_RS_PORT = 1; //寫數據
- LCD12864_RW_PORT = 0;
- LCD12864_DA_PORT = da;
- LCD12864_E_PORT = 1;
- delay_1ms(1);
- LCD12864_E_PORT = 0;
- }
- void LCD12864_init() /*LCD12864初始化*/
- {
- lcd_psb=1;
- LCD12864_NoWaitIdle_COM_Write(0x30); /*基本指令操作*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x0c); /*顯示開及光標設置*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x01); /*顯示清屏*/
- delay_1ms(10);
- LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址計數器(AC)加1*/
- delay_1ms(10);
- }
- void LCD12864_HAIZI_WRITE(uchar x,uchar y,uchar daH,uchar daL) //漢字16bit寫入 x寫入的X位置 y寫入的Y位置 daH寫入漢字高八位 daL寫入漢字低八位
- {
- uchar xy;
- if((x>=8)||(y>=4)) return; /*X位置超出顯示范圍退出*/
- if(y==0) xy=0x80+x;
- else if(y==1) xy=0x90+x; /*計算轉換地址*/
- else if(y==2) xy=0x88+x;
- else if(y==3) xy=0x98+x;
- LCD12864_COM_Write(xy); /*寫地址*/
- delay_1ms(1);
- LCD12864_Data_Write(daH); /*寫高八位數據*/
- delay_1ms(1);
- LCD12864_Data_Write(daL); /*寫低八位數據*/
- delay_1ms(1);
- }
- //鍵盤掃描函數,低電位按下
- /*void keyscan()
- {
- int s1num;
- rd=0;
- if(key1==0)
- {
- delay_1ms(5);
- if(key1==0)
- {
- Set1302(time_data_buff);
- W1302(0x8e,0x00);
- W1302(0x80,0x80);
- W1302(0x8e,0x80);
- s1num++;
- while(!key1);
- if(s1num==1)
- {
- //LCD12864_COM_Write(0x81);年
- if(key2==0)
- {
- delay_1ms(5);
- if(key2==0)
- {
- while(!key2);
- time_data_buff[6]++;
- }
- }
- }
- /*if(s1num==2)
- {
- LCD12864_COM_Write(0x83);//月
- }
- if(s1num==3)
- {
- LCD12864_COM_Write(0x85);//日
- }
- if(s1num==4)
- {
- LCD12864_COM_Write(0x8a);//時
- }
- if(s1num==5)
- {
- LCD12864_COM_Write(0x88+)/////////////////
- }
- if(s1num==6)
- {
- LCD12864_COM_Write(0x8d);//秒
- }*/
- /* if(s1num==2)
- {
- s1num=0;
- W1302(0x8e,0x00);
- W1302(0x80,0x00);
- W1302(0x8e,0x80);
- }
- //W1302(0x80,此處應為修改的秒值);
-
- }
- }
- }
- */
- void main()//主函數
- {
- uchar i;
- uint temp_buff;
- P0=0x00;//關掉數碼管位選信號。阻止數碼管受到P0口信號的影響。
- dula=1;
- delay_1ms(1);
- dula=0;
- delay_1ms(1);
-
- LCD12864_init(); /*LCD初始化*/
- LCD12864_DA_PORT = 0xff; /*釋放P0端口*/
-
- Set1302(time_data_buff);
- while(1){
-
- // keyscan();
-
- Now1302(time_data_buff);
- hanzi_buff1[2] = num_to_char[time_data_buff[6]/0x10];
- hanzi_buff1[3] = num_to_char[time_data_buff[6]%0x10]; /*年*/
- hanzi_buff1[6] = num_to_char[time_data_buff[4]/0x10];
- hanzi_buff1[7] = num_to_char[time_data_buff[4]%0x10]; /*月*/
- hanzi_buff1[10] = num_to_char[time_data_buff[3]/0x10];
- hanzi_buff1[11] = num_to_char[time_data_buff[3]%0x10]; /*日*/
- hanzi_buff3[4] = num_to_char[time_data_buff[2]/0x10];
- hanzi_buff3[5] = num_to_char[time_data_buff[2]%0x10]; /*時*/
- hanzi_buff3[7] = num_to_char[time_data_buff[1]/0x10];
- hanzi_buff3[8] = num_to_char[time_data_buff[1]%0x10]; /*分*/
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
test_2_3.zip
(40.99 KB, 下載次數: 28)
2017-12-9 23:51 上傳
點擊文件名下載附件
源碼 下載積分: 黑幣 -5
|