|
主要元件
89c52單片機(jī)
ds1302實(shí)時時鐘程序
24c02
18b20
pcf8574
lcd1602
不知道為什么使用i2c光標(biāo)不清晰
下面制作出來的實(shí)物圖:
單片機(jī)源程序如下:
- #include"mcu.h"
- #include"ds1302.c"
- #include"pcf8574lcd.h"
- #include"24c02.h"
- sbit a0 = ACC^0;
- sbit a1 = ACC^1;
- sbit a2 = ACC^2;
- sbit a3 = ACC^3;
- sbit a4 = ACC^4;
- sbit a5 = ACC^5;
- sbit a6 = ACC^6;
- sbit a7 = ACC^7;
- sbit SCLK = P1^2; //時鐘
- sbit IO = P1^3; //數(shù)據(jù)
- sbit RST = P1^4; //復(fù)位
- sbit DQ = P0^0 ; //18B20接口
- sbit sp = P3^4 ; //蜂鳴器
- sbit sb = P0^6 ; //繼電器電源
- //輸出
- sbit sb0 = P2^0 ;
- sbit sb1 = P2^1 ;
- sbit sb2 = P2^2 ;
- sbit sb3 = P2^3 ;
- //按鍵
- sbit MODE = P2^7 ; //模式鍵
- sbit INC = P2^6 ; //增加鍵
- sbit DEC = P2^5 ; //減少鍵
- sbit OK = P2^4 ; //OK鍵 定時開關(guān)鍵
-
- volatile uint8 data timedata[7] ; //時間值
- volatile uint8 data display_buffer1[16]; //顯示緩沖區(qū)1
- volatile uint8 data display_buffer2[16]; //顯示緩沖區(qū)2
- volatile uint8 data temdata[5] ; //存放溫度值
- volatile uint16 data tdat ; //溫度值變量
- volatile uint8 data tflag ; //溫度正負(fù)值標(biāo)志
- volatile int self_pos = 0 ;//菜單箭頭標(biāo)志變量
- volatile int OK_VALUE = 0 ; //OK鍵鍵值變量
- volatile bit bdata DIS_ON = 1 ; //顯示開關(guān) 1 == on 0 == off
- volatile bit bdata SCAN_ON = 0 ; //按鍵掃描開關(guān)位,由定時器每20MS刷新
- volatile data MODE_ON = 0 ; //模式鍵按下后顯示菜單
- volatile data INC_VALUE = 0 ;
- volatile data DEC_VALUE = 0 ;
- volatile bit bdata ALARM_VALUE = 0 ;//鬧鐘標(biāo)志位
- volatile bit bdata ALARM_ON = 1 ; //鬧鐘響時關(guān)閉標(biāo)志位
- volatile int data read_1 = 1,read_2 = 1,read_3 = 1,read_4 = 1;
-
- /****************************************************************
- 延時函數(shù)
- *****************************************************************/
- void delay_ms(uint16 count) // 延時時間count*1ms
- { uint16 i;
- for(;count>0;count--)
- {
- for(i=0;i<110;i++)
- {
- nop;
- }
- }
- }
- /**********************************************************
- 蜂鳴器
- ************************************************************/
- void speakers(uint8 speak_count)
- {
- for(;speak_count>0;speak_count--)
- {
- sp = 0 ;
- delay_ms(15) ;
- sp = 1 ;
-
- }
- }
- //底層驅(qū)動函數(shù)(輸入)
- void DS1302_input(uint8 inputdata)
- {
- ACC = inputdata ;
- IO = a0 ; SCLK = 1 ; SCLK = 0 ;
- IO = a1 ; SCLK = 1 ; SCLK = 0 ;
- IO = a2 ; SCLK = 1 ; SCLK = 0 ;
- IO = a3 ; SCLK = 1 ; SCLK = 0 ;
- IO = a4 ; SCLK = 1 ; SCLK = 0 ;
- IO = a5 ; SCLK = 1 ; SCLK = 0 ;
- IO = a6 ; SCLK = 1 ; SCLK = 0 ;
- IO = a7 ; SCLK = 1 ; SCLK = 0 ;
- }
- //底層驅(qū)動函數(shù)(輸出)控制位的第七位必須為1
- uint8 DS1302_output(void)
- {
- IO = 1 ;
- a0 = IO ;
- SCLK = 1 ; SCLK =0 ; a1 = IO ;
- SCLK = 1 ; SCLK =0 ; a2 = IO ;
- SCLK = 1 ; SCLK =0 ; a3 = IO ;
- SCLK = 1 ; SCLK =0 ; a4 = IO ;
- SCLK = 1 ; SCLK =0 ; a5 = IO ;
- SCLK = 1 ; SCLK =0 ; a6 = IO ;
- SCLK = 1 ; SCLK =0 ; a7 = IO ;
- return(ACC);
- }
- //底層驅(qū)動函數(shù)(指定地址寫一個字節(jié)的數(shù)據(jù))
- void DS1302_write_byte(uint8 cmd , uint8 dat)
- {
- SCLK = 0 ;
- RST = 0 ;
- RST = 1 ;
- DS1302_input(cmd) ;
- DS1302_input(dat) ;
- RST = 0 ;
- SCLK = 1 ;
- }
- //底層驅(qū)動函數(shù)(指定地址讀取一字節(jié)的數(shù)據(jù))
- uint8 DS1302_read_byte(int cmd)
- {
- uint8 receivedata = 0 ;
- SCLK = 0 ;
- RST = 0 ;
- RST = 1 ;
- DS1302_input(cmd) ;
- receivedata = DS1302_output() ;
- RST = 0 ;
- SCLK = 1 ;
- return(receivedata) ;
- }
- //1302的初始數(shù)據(jù)
- void DS1302_init()
- {
- if(DS1302_read_byte(0xef) != 0xf0) //檢測初始化標(biāo)志數(shù)據(jù)不為f0則初始化1302
- {
- DS1302_write_byte(0x8e,0x00) ;//允許寫操作
- DS1302_write_byte(0xee,0xf0) ; //初始化標(biāo)志
- DS1302_write_byte(0x8c,0x18) ;//年
- DS1302_write_byte(0x8a,0x01) ;//星期
- DS1302_write_byte(0x88,0x01) ;//月
- DS1302_write_byte(0x86,0x01) ;//日
- DS1302_write_byte(0x84,0x12) ;//時
- DS1302_write_byte(0x82,0x00) ;//分
- DS1302_write_byte(0x80,0x00) ;//秒
- DS1302_write_byte(0x90,0xa5) ;//充電
- DS1302_write_byte(0x8e,0x80) ;//禁止寫操作
- }
- }
- /********************************************************
- 讀取時間數(shù)據(jù)并放在timedata[]中
- *********************************************************/
- void DS1302_read_time()
- {
- timedata[0] = DS1302_read_byte(0x8d) ; //年
- timedata[1] = DS1302_read_byte(0x89) ; //月
- timedata[2] = DS1302_read_byte(0x87) ; //日
- timedata[3] = DS1302_read_byte(0x85) ; //時
- timedata[4] = DS1302_read_byte(0x83) ; //分
- timedata[5] = DS1302_read_byte(0x81) ; //秒
- timedata[6] = DS1302_read_byte(0x8b) ; //星期
- }
- /***********************************************************
- DS18B20函數(shù)
- *************************************************************/
- void delay_18b20(int16 sum) //短暫延時
- {
- while(sum--);
- }
- void rst_18b20() //18B20復(fù)位
- { //uchar flag;
- DQ=1;
- delay_18b20(8);
- DQ=0;
- delay_18b20(80);
- DQ=1;
- delay_18b20(13);
- //flag=DQ;
- //return(flag);
- // delay_18b20(20);
- }
- void wr_18b20(int dat) //寫一個字節(jié)的數(shù)據(jù)
- {
- uint8 i=8;
- for(;i>0;i--)
- {
- DQ=0;
- DQ=dat&0x01;
- delay_18b20(5);
- DQ=1;
- dat>>=1;
- }
- }
- uint8 rd_18b20() //讀一個字節(jié)的內(nèi)容
- {
- uint8 dat=0,i=8;
- for(;i>0;i--)
- {
- DQ=0;
- dat>>=1;
- DQ=1;
- if(DQ)
- dat|=0x80;
- delay_18b20(4);
- }
- return(dat);
- }
- uint16 rd_temperature() //讀取溫度值
- {
- uint8 a=0,b=0;
- uint16 t=0;
- float tt=0;
- rst_18b20(); //復(fù)位
- wr_18b20(0xcc); //跳過ROM
- wr_18b20(0x44); //啟動溫度轉(zhuǎn)換
- rst_18b20(); //再次對18B20操作時,需要重新復(fù)位一次
- wr_18b20(0xcc); //跳過ROM
- wr_18b20(0xbe); //讀取內(nèi)部RAM的內(nèi)容
- a=rd_18b20(); //讀溫度值低位(內(nèi)部RAM的第0個字節(jié))
- b=rd_18b20(); //讀溫度值高位(內(nèi)部RAM的第1個字節(jié))
- t=b;
- t<<=8; //溫度值的高8位放在t的高8位
- t=t|a; //溫度值的低8位放在t的低8位
- if(t<0x0fff) //判斷溫度值得正負(fù)值
- tflag=0; //tflag=0溫度值為正
- else
- {
- t=~t+1; //溫度值為負(fù),負(fù)值以補(bǔ)碼形式存放,這里要將其還原成原碼
- tflag=1; //tflag=1溫度值為負(fù)
- }
- tt=t*0.0625;
- t = tt*100 ;
- return(t);
-
- }
- //***********************************************//
- void tem_conv() //溫度轉(zhuǎn)換
- {
- uint8 flagdat ;//定義溫度值符號
- if(tflag==0)
- temdata[4]=flagdat=0x20;//溫度為正不顯示負(fù)號
- else
- temdata[4]=flagdat=0x2d;//負(fù)溫度顯示負(fù)號
- temdata[0]=tdat/1000+0x30;//溫度十位
- temdata[1]=tdat%1000/100+0x30;//溫度個位
- temdata[2]=tdat%100/10+0x30;//小數(shù)十位
- temdata[3]=tdat%10+0x30;//小數(shù)百位
- /*if(temdata[0]==0x30)
- {temdata[0]=0x20;//?????0,???
- if(temdata[1]==0x30)
- {
- temdata[1]=0x20;//?????0,???0????
- }
- }*/
-
- }
-
- /**************************************************************
- 更新顯示緩沖區(qū)
- ***************************************************************/
- void updata_buffer(void)
- {
- //顯示日期
- display_buffer1[0] = '2' ;
- display_buffer1[1] = '0' ;
- display_buffer1[2] = timedata[0]/16+0x30 ; //年
- display_buffer1[3] = timedata[0]%16+0x30 ;
- display_buffer1[4] = 0 ;
- display_buffer1[5] = timedata[1]/16+0x30 ; //月
- display_buffer1[6] = timedata[1]%16+0x30 ;
- display_buffer1[7] = 0 ;
- display_buffer1[8] = timedata[2]/16+0x30 ; //日
- display_buffer1[9] = timedata[2]%16+0x30 ;
- display_buffer1[10] = ' ' ;
- display_buffer1[11] = ' ' ;
- display_buffer1[12] = ' ' ;
- switch(timedata[6]%16) //顯示星期
- { case 1 : {display_buffer1[13] = '1' ;
- }break ;
- case 2 : {display_buffer1[13] = '2' ;
- }break ;
- case 3 : {display_buffer1[13] = '3' ;
- }break ;
- case 4 : {display_buffer1[13] = '4' ;
- }break ;
- case 5 : {display_buffer1[13] = '5' ;
- }break ;
- case 6 : {display_buffer1[13] = '6' ;
- }break ;
- case 7 : {display_buffer1[13] = '7' ;
- }break ;
- default : break; }
- display_buffer1[14] = ' ' ;
- if(ALARM_VALUE == 1)
- display_buffer1[15] = 1 ; //按下ok鍵顯示定時標(biāo)志
- else
- if(ALARM_VALUE == 0)
- display_buffer1[15] = 3 ;
-
- //當(dāng)前時間值
- display_buffer2[0] = timedata[3]/16+0x30; //時
- display_buffer2[1] = timedata[3]%16+0x30;
- display_buffer2[2] = ':' ;
- display_buffer2[3] = timedata[4]/16+0x30 ; //分
- display_buffer2[4] = timedata[4]%16+0x30 ;
- display_buffer2[5] = ':' ;
- display_buffer2[6] = timedata[5]/16+0x30 ; //秒
- display_buffer2[7] = timedata[5]%16+0x30 ;
-
- //溫度值
- display_buffer2[8] = ' ' ;
- display_buffer2[9] = temdata[4] ; //負(fù)號
- display_buffer2[10] = temdata[0] ; //溫度十位
- display_buffer2[11] = temdata[1] ; //溫度個位
- display_buffer2[12] = '.' ;
- display_buffer2[13] = temdata[2] ; //小數(shù)十位
- display_buffer2[14] = temdata[3] ; //小數(shù)百位
- display_buffer2[15] = 'C' ;
- }
- /******************************************************************
- 顯示緩沖區(qū)內(nèi)容
- *******************************************************************/
- void display_buffer(void)
- {
- uint8 i ;
- send_command(0x80) ; //顯示第一行
- for(i=0;i<16;i++)
- send_data(display_buffer1[i]);
- send_command(0xc0) ; //顯示第二行
- for(i=0;i<16;i++)
- send_data(display_buffer2[i]);
- }
- /*****************************************************************
- 按鍵掃描函數(shù)
- ******************************************************************/
- void key_scan(void)
- {
- if(MODE == 0)
- {
- delay_ms(10) ;
- while(!MODE) ;
- speakers(5) ;
- DIS_ON = 0 ;
- MODE_ON ++ ;
- if(MODE_ON == 1 && OK_VALUE == 0)
- send_command(0x01);
- if(MODE_ON == 2 && OK_VALUE == 0)
- {
- MODE_ON = 0 ;
- DIS_ON = 1 ;
- self_pos = 0 ;
- }
- }
-
- if(INC == 0 && MODE_ON == 1 && OK_VALUE == 0)
- {
- delay_ms(10) ;
- while(!INC) ;
- speakers(5) ;
- send_command(0x01) ;
- self_pos++ ;
- if(self_pos > 4)
- self_pos = 0 ;
- }
- if(DEC == 0 && MODE_ON == 1 && OK_VALUE == 0)
- {
- delay_ms(10) ;
- while(!DEC) ;
- speakers(5) ;
- send_command(0x01) ;
- self_pos++ ;
- if(self_pos > 4)
- self_pos = 0 ;
- }
- if(DEC == 0 )
- {
- delay_ms(10) ;
- while(!DEC) ;
- speakers(5) ;
- DEC_VALUE++;
- }
- if(INC == 0)
- {
- delay_ms(10) ;
- while(!INC) ;
- speakers(5) ;
- INC_VALUE++;
- }
- if(OK == 0 && MODE_ON != 0)
- {
- delay_ms(10) ;
- while(!OK) ;
- speakers(5) ;
- send_command(0x01) ;
- OK_VALUE++;
- INC_VALUE = 0 ;
- DEC_VALUE = 0 ;
- }
- if(OK == 0 && MODE_ON == 0)
- {
- delay_ms(10) ;
- while(!OK) ;
- speakers(5) ;
- ALARM_ON = 1 ;
- if(ALARM_VALUE == 1)
- ALARM_VALUE = 0 ;
- else
- ALARM_VALUE = 1 ;
- }
- }
- /*******************************************************************
- 按鍵菜單人機(jī)交互函數(shù)(第一級)
- ********************************************************************/
- void menu_display_1()
- {
- if(MODE_ON == 1 && OK_VALUE == 0)
- {
- switch(self_pos)
- {
- case 0 : {
- LCD1602_write_string(1,1,"Time ") ;
- LCD1602_write_string(1,0," Timing1 ") ;
- }break ;
- case 1 : {
- LCD1602_write_string(1,1," Time ") ;
- LCD1602_write_string(1,0,"Timing1 ") ;
- }break ;
- case 2 : {
- LCD1602_write_string(1,1," Timing1 ") ;
- LCD1602_write_string(1,0,"Timing2") ;
- }break ;
- case 3 : {
- LCD1602_write_string(1,1," Timing2 ") ;
- LCD1602_write_string(1,0,"Timing3") ;
- }break ;
- case 4 : {
- LCD1602_write_string(1,1," Timing3 ") ;
- LCD1602_write_string(1,0,"Timing4") ;
- }break ;
- default : break ;
- }
- }
- }
- /*******************************************************************
- 按鍵菜單人機(jī)交互函數(shù)(第二級)
- ********************************************************************/
- void menu_display_2(void)
- {
- uint8 i ,j;
- if(MODE_ON != 0 && OK_VALUE != 0)
- {
- send_command(0x0f) ;
- if(self_pos == 0 )
- {
-
- send_command(0x81) ;
- for(i=0;i<15;i++)
-
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
8574and1602ti.rar
(92.21 KB, 下載次數(shù): 98)
2018-2-17 10:14 上傳
點(diǎn)擊文件名下載附件
|
評分
-
查看全部評分
|