oled時鐘單片機源程序如下:
- #include "REG52.h"
- #include "oled.h"
- #define uchar unsigned char
- #define uint unsigned int
- #include <intrins.h>
- sbit DQ = P3^6; //數據口define interface
- /***********************DS1302端口定義*******************************************/
- sbit clock_rst=P3^5; //1302復位管腳定義
- sbit clock_dat=P1^3; //1302I/O管腳定義
- sbit clock_clk=P1^2; //1302時鐘管腳定義
- /***************寄存器定義(用于記錄1302IO的輸入和輸出)*************************/
- 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;
- /**********************1302全局變量定義******************************************/
- uchar sec,min,hour,day,month,year1,year2=20;//秒,分,時,日,月,星期,年
- /************************蜂鳴器端口定義******************************************/
- sbit beep=P3^7;
- /***********************按鍵定義*************************************************/
- sbit key1=P1^0;
- sbit key2=P1^1;
- sbit key3=P3^4;
- uchar status=0;//按鍵功能選擇定義(年0,月1,日2,時3,分4 )
- uint tmp; //溫度值 variable of temperature
- uint Temp_Buffer = 0;
- uint t1;
- uint t2;
- uint t3;
- float tt;
- void delay2(unsigned char i) //延時函數
- {
- while(--i);
- }
- /**********************延時函數*************************************************/
- void delay(uint t)
- {
- uint b;
- for(;t;t--)
- for(b=0;b<121;b++);
- }
- void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command
- {
- DQ = 1; //DQ復位,不要也可行。
- delay2(1); //稍做延時
- DQ = 0; //單片機拉低總線
- delay2(250); //精確延時,維持至少480us
- DQ = 1; //釋放總線,即拉高了總線
- delay2(100); //此處延時有足夠,確保能讓DS18B20發出存在脈沖。
- }
- uchar Read_One_Byte() //讀取一個字節的數據read a byte date
- //讀數據時,數據以字節的最低有效位先從總線移出
- {
- uchar i = 0;
- uchar dat = 0;
- for(i=8;i>0;i--)
- {
- DQ = 0; //將總線拉低,要在1us之后釋放總線
- //單片機要在此下降沿后的15us內讀數據才會有效。
- _nop_(); //至少維持了1us,表示讀時序開始
- dat >>= 1; //讓從總線上讀到的位數據,依次從高位移動到低位。
- DQ = 1; //釋放總線,此后DS18B20會控制總線,把數據傳輸到總線上
- delay2(1); //延時7us,此處參照推薦的讀時序圖,盡量把控制器采樣時間放到讀時序后的15us內的最后部分
- if(DQ) //控制器進行采樣
- {
- dat |= 0x80; //總線為1, DQ為1,那就把dat的最高位置1;若為0,不處理,保持0
- }
- delay2(10); //此延時不能少,確保讀時序的長度60us。
- }
- return (dat);
- }
- void Write_One_Byte(uchar dat)
- {
- uchar i = 0;
- for(i=8;i>0;i--)
- {
- DQ = 0; //拉低總線
- _nop_(); //至少維持了1us,表示寫時序(包括寫0時序或寫1時序)開始
- DQ = dat&0x01; //從字節的最低位開始傳輸
- //指令dat的最低位賦予給總線,必須在拉低總線后的15us內,
- //因為15us后DS18B20會對總線采樣。
- delay2(10); //必須讓寫時序持續至少60us
- DQ = 1; //寫完后,必須釋放總線,
- dat >>= 1;
- delay2(1);
- }
- }
- uint Get_Tmp() //獲取溫度get the temperature
- {
-
- uchar a=0,b=0;
-
- Init_Ds18b20(); //初始化
- Write_One_Byte(0xcc); //忽略ROM指令
- Write_One_Byte(0x44); //溫度轉換指令
- Init_Ds18b20(); //初始化
- Write_One_Byte(0xcc); //忽略ROM指令
- Write_One_Byte(0xbe); //讀暫存器指令
- a = Read_One_Byte(); //讀取到的第一個字節為溫度LSB
- b = Read_One_Byte(); //讀取到的第一個字節為溫度MSB
- tmp = b; //先把高八位有效數據賦于temp
- tmp <<= 8; //把以上8位數據從temp低八位移到高八位
- tmp = tmp|a; //兩字節合成一個整型變量
- tt = tmp*0.0625; //得到真實十進制溫度值,DS18B20可以精確到0.0625度
- tmp =(uint)( tt*10+0.5); //放大十倍,目的是將小數點后第一位也轉換為可顯示數字
- return (tmp);
- }
- void Display_Temp()
- {
-
- Temp_Buffer = Get_Tmp() ; //讀取DS18B20的值
- t1=(Temp_Buffer%1000/100); //顯示溫度十位值
- t2=(Temp_Buffer%100/10); //顯示溫度個位值
-
- t3=(Temp_Buffer%10); //顯示溫度十分位值
-
-
- }
-
- /*******************************************************************************/
- /*************************DS1302子函數******************************************/
- /************************1302寫驅動函數*****************************************/
- void write_clock(uchar dat)
- {
- ACC=dat;
- clock_dat=a0; clock_clk=1; clock_clk=0; //數據在上升沿變化
- clock_dat=a1; clock_clk=1; clock_clk=0; //下降沿寫入1302
- clock_dat=a2; clock_clk=1; clock_clk=0;
- clock_dat=a3; clock_clk=1; clock_clk=0;
- clock_dat=a4; clock_clk=1; clock_clk=0;
- clock_dat=a5; clock_clk=1; clock_clk=0;
- clock_dat=a6; clock_clk=1; clock_clk=0;
- clock_dat=a7; clock_clk=1; clock_clk=0;
- }
- /************************1302讀驅動函數*****************************************/
- uchar read_clock()
- {
- clock_dat=1; //輸出賦1
- a0=clock_dat;clock_clk=1; clock_clk=0; //位0為1,讀1302
- a1=clock_dat;clock_clk=1; clock_clk=0; //下降沿讀出有效
- a2=clock_dat;clock_clk=1; clock_clk=0;
- a3=clock_dat;clock_clk=1; clock_clk=0;
- a4=clock_dat;clock_clk=1; clock_clk=0;
- a5=clock_dat;clock_clk=1; clock_clk=0;
- a6=clock_dat;clock_clk=1; clock_clk=0;
- a7=clock_dat;clock_clk=1; clock_clk=0;
- return(ACC);
- }
- /***************************寫數據入1302****************************************/
- void write_dat_clock(uchar add,uchar dat)
- {
- clock_clk=0;
- clock_rst=0; //時鐘脈沖為低時
- clock_rst=1; //復位端才能置高
- write_clock(add); //寫入地址(命令字節)
- write_clock(dat); //寫入數據
- clock_rst=0; //終止數據傳送
- clock_clk=1;
- }
- /***************************從1302讀出數據**************************************/
- uchar read_dat_clock(uchar add)
- {
- uchar dat=0; //定義數據儲存變量
- clock_clk=0;
- clock_rst=0;
- clock_rst=1;
- write_clock(add); //寫入要讀數據的地址
- dat=read_clock(); //讀出數據
- clock_rst=0; //終止數據傳送
- clock_clk=1;
- return dat; //返回數據
- }
- /**************************設置初始時間函數*************************************/
- void set_time()
- {
- read_dat_clock(0x81); //讀取秒
- if(sec==0x80) //sec為秒讀出的數值,如果最高位為1,則初始化
- write_dat_clock(0x8e,0x00); //允許寫操作
- write_dat_clock(0x8c,0x13); //年
- write_dat_clock(0x8a,0x03); //星期
- write_dat_clock(0x88,0x10); //月
- write_dat_clock(0x86,0x14); //日
- write_dat_clock(0x84,0x21); //小時
- write_dat_clock(0x82,0x56); //分
- write_dat_clock(0x80,0x00); //秒,且振蕩器工作
- write_dat_clock(0x90,0xa5); //充電
- write_dat_clock(0x8e,0x80); //禁止寫操作
- }
- void get_time()
- {
- sec=read_dat_clock(0x81); //讀取秒
- sec=(sec>>4)*10+(sec&0x0f); //秒二進制轉換
- delay(1);
- min=read_dat_clock(0x83); //讀取分鐘
- min=(min>>4)*10+(min&0x0f); //分二進制轉換
- delay(1);
- hour=read_dat_clock(0x85); //讀取小時
- hour=(hour>>4)*10+(hour&0x0f);//小時二進制轉換
- delay(1);
- day=read_dat_clock(0x87); //讀取日期
- day=(day>>4)*10+(day&0x0f); //日期二進制轉換
- delay(1);
- month=read_dat_clock(0x89); //讀取月份
- month=(month>>4)*10+(month&0x0f);//月二進制轉換
- delay(1);
- //week=read_dat_clock(0x8b); //讀取星期
- //week=(week>>4)*10+(week&0x0f);//星期二進制轉換
- delay(1);
- year1=read_dat_clock(0x8d); //讀取年份
- year1=(year1>>4)*10+(year1&0x0f); //年份二進制轉換
- }
-
- /******************************************************************************/
- /*****************************按鍵功能函數*************************************/
- void key_1() //選擇變量函數
- {
- key1=1;
- if(key1==0)
- delay(10);
- {
- if(key1==0)
- {
- if(++status>5)status=0; //1控制年的變化,2控制月的變化,3控制日的變化
- } //4控制時的變化,5控制分的變化
- while(key1==0);
- }
- }
- /******************************************************************************/
- void key_2() //加函數
- {
- key2=1;
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- switch(status)
- {
- case 1:if(++year1>99)year1=0;break;
- case 2:if(++month>12)month=1;break;
- case 3:if(++day>31)day=1;break;
- case 4:if(++hour>=24)hour=0;break;
- case 5:if(++min>=60)min=0;break;
- }
- }
- while(key2==0);
- }
- }
- /*****************************************************************************/
- void key_3()//減函數
- {
- key3=1;
- if(key3==0)
- {
- delay(10);
- if(key3==0)
- {
- switch(status)
- {
- case 1:if((year1--)<=0)year1=99;break;
- case 2:if((month--)<=1)month=12;break;
- case 3:if((day--)<=1)day=31;break;
- case 4:if((hour--)<=0)hour=23;break;
- case 5:if((min--)<=0)min=59;break;
- }
- }
- while(key3==0);
- }
- }
- /*****************************************************************************/
- void key_time() //按鍵設置時間的處理
- {
- if(status>0)
- {
- write_dat_clock(0x8e,0x00); //允許寫操作
- write_dat_clock(0x8c,(year1/10)*16+year1%10); //年
- //write_dat_clock(0x8a,(week/10)*16+week%10); //星期
- write_dat_clock(0x88,(month/10)*16+month%10); //月
- write_dat_clock(0x86,(day/10)*16+day%10); //日
- write_dat_clock(0x84,(hour/10)*16+hour%10); //小時
- write_dat_clock(0x82,(min/10)*16+min%10); //分
- write_dat_clock(0x8e,0x80); //禁止寫操作
- }
- }
-
- void main()
- {
- OLED_Init(); //初始化OLED
- OLED_Clear();
- Init_Ds18b20();
- Get_Tmp();
- delay(10);
- set_time();
-
- while(1)
- {
-
-
- Display_Temp();
- //OLED_Clear();
- OLED_ShowCHinese(0,0,0);//軟
- OLED_ShowCHinese(18,0,1);//件
- OLED_ShowCHinese(36,0,2);//設
- OLED_ShowCHinese(54,0,3);//計
- OLED_ShowCHinese(72,0,4);//田
- OLED_ShowCHinese(90,0,5);//增
- OLED_ShowCHinese(108,0,6);//良
-
- //OLED_ShowString(8,2,"Design by TZL");
- //OLED_ShowString(0,4,"Tel:15083395396");
-
- OLED_ShowCHinese(0,2,7);//實
- OLED_ShowCHinese(18,2,8);//測
- OLED_ShowCHinese(36,2,9);//溫
- OLED_ShowCHinese(54,2,10);//度
- OLED_ShowCHinese(36,4,11);//年
- OLED_ShowCHinese(74,4,12);//月
- OLED_ShowCHinese(110,4,13);//日
- get_time();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
OLED時鐘顯示.zip
(90.82 KB, 下載次數: 570)
2018-6-6 15:14 上傳
點擊文件名下載附件
|