模組選型
模組選型解析
設計思路
産品接線
部分代碼解析
總結
模組選型設計電子時鐘的時候采取了最基礎的單片機51單片機,使用的芯片為STC89C52RC,開發闆選用了最小系統闆,也方便朋友們了解接線以及原理,簡單清晰,時鐘芯片選型方面選取了DS1302的時鐘模組,接線方面選用杜邦線進行連接,顯示方面采用低功耗的lcd1602進行顯示,LCD1602的對比度調節選取單圈精密電阻器10K電阻器。
模組選型解析模組具體圖片如下:
DS1302時鐘芯片是美國DALLAS公司推出的具有涓細電流充電能力的低功耗實時時鐘電路DS1302的結構、工作原理及其在實時顯示時間中的應用。它可以對年、月、日、周日、時、分、秒進行計時,且具有閏年補償功能;
LCD1602液晶顯示屏為工業字符型液晶,能夠同時顯示16x02即32個字符。(16列2行),剛好可以上排顯示年月日,下排顯示時鐘。
設計思路功能介紹***lcd1602顯示實時時鐘可以在函數中實現設置時鐘芯片初始值,缺點: 由于沒有增加其他功能,此功能較為簡單,校準時間隻能通過源代碼進行校準。
流程:
1. 在程序前端定義一個初始化的數組文件,注意的是DS1302需要轉成壓縮的BCD碼進行存儲,方便後面的初始化時鐘芯片時關閉芯片寫保護時候調用數組。
2. 進行LCD1602和DS1302的讀寫初始化時序代碼。由于51沒有直接的SPI通信而DS1302與LCD1602有點類似三線SPI通信可使用軟件進行模拟通信。
3. 對DS1302讀出的數據進行取出操作并顯示在LCD1602上
産品接線産品接線具體如下圖所示,接線中LCD的數據口使用的是單片機的P0口,時鐘信号口使用的是P2_0到P2_3,DS1302 使用的為P1_1到P1_3口。具體效果和接線可看下圖所示:
部分代
串行通信字節發送解析:
如何将一個字節拆分成0101的二進制位發出去,并分析如何将0101的二進制位變成一個完整的字節。
首先23 H=0010 0011B,最低位是1,最高位是0,現在将0x23&0x01進行運算,結果當然是0x01,這時,我們就應該将數據線變成1,然後0x23往右移動一個二進制位,得出的結果是11 H=0001 0001 B(這裡有一個重點,數據右移的時候,最高位是補0的,數據左移的時候,最低位補0)。
假設上面的數據右移了2次後,最初的23 H變成了08 H=0000 1000 B,現在繼續對0x08&0x01做運算得出的結果是0,這時,将數據線變為0,如此循環8次,就可以将1個字節分成串行數據一位一位的傳送出去了。
接收解析:
假設串行數據先發送最低位,首先将一個數據00 H右移一個二進制位,得出的數據當然還是00 H,然後如果數據總線上的電平是1,那麼此時就把00 H和80 H做或運算,得出的結果就是80 H,然後下一個電平的時候80 H右移一個二進制位,得出的結果是40 H,如果此時數據線的電平還是1,那就繼續和80 H做或運算,得C0 H,最終通過8次運算,就可以将1個字節全部接收完畢。
時序解析
上面讀寫時序可以知道,讀單字節的時候是在時鐘脈沖的下降沿脈沖信号,因此在程序中可以先給時鐘信号高電平再給低電平制造一個下降沿的脈沖信号從而讀取一個字節,一個字節有8位可以使用for循環進行8位循環讀取。代碼如下:
u8 DS1302_Read_Byte()
{
u8 i, Byte ;
DS_CLK = 1 ; //時鐘線拉高
Byte = 0 ;
for( i=0; i<8; i )
{
Byte >>= 1 ; //數據右移一個位
DS_CLK = 0 ; //時鐘線拉低産生下降沿
if( DS_IO==1 ) //判斷數據線上的值為1
Byte |= 0x80 ; //字節寫入1
DS_CLK = 1 ; //時鐘線拉高
}
return Byte ;
}
讀的時序剛好和寫的相反,在上升沿寫入:
void DS1302_Write_Byte( u8 Byte )
{
u8 i ;
for( i=0; i<8; i )
{
if( ( Byte&0x01 )==0x01 ) //判斷最低位是1
DS_IO = 1 ; //數據線拉高發送1
else
DS_IO = 0 ; //數據線拉低發送0
Byte >>= 1 ; //數據右移一個位
DS_CLK = 0 ; //時鐘線複位
DS_CLK = 1 ; //時鐘線拉高産生上升沿
}
}
1:LCD1602初始化代碼
void LCD_init(void)
{
Write_Instruction(0x38); //8bit interface,2line,5*7dots
Delay_xms(5);
Write_Instruction(0x38);
Delay_xms(5);
Write_Instruction(0x38);
Write_Instruction(0x08); //關顯示,不顯光标,光标不閃爍
Write_Instruction(0x01); //清屏
Delay_xms(5);
Write_Instruction(0x04); //寫一字符,整屏顯示不移動
//Write_Instruction(0x05); //寫一字符,整屏右移
//Write_Instruction(0x06); //寫一字符,整屏顯示不移動
//Write_Instruction(0x07); //寫一字符,整屏左移
Delay_xms(5);
//Write_Instruction(0x0B); //關閉顯示(不顯示字符,隻有背光亮)
Write_Instruction(0x0C); //開顯示,光标、閃爍都關閉
//Write_Instruction(0x0D); //開顯示,不顯示光标,但光标閃爍
//Write_Instruction(0x0E); //開顯示,顯示光标,但光标不閃爍
//Write_Instruction(0x0F); //開顯示,光标、閃爍均顯示
}
2:DS1302寫入初始值代碼因為前面有定義一個初始化時鐘的數組,并在先關閉芯片寫保護的情況下可直接寫入DS1302時鐘的初始值。
void ds1302_write_time(void)
{
ds1302_write_byte(ds1302_control_add,0x00); //關閉寫保護
ds1302_write_byte(ds1302_sec_add,0x80); //暫停時鐘
//ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充電
ds1302_write_byte(ds1302_year_add,time_buf[1]); //年
ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
ds1302_write_byte(ds1302_date_add,time_buf[3]); //日
ds1302_write_byte(ds1302_hr_add,time_buf[4]); //時
ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
ds1302_write_byte(ds1302_control_add,0x80); //打開寫保護
}
本次51電子時鐘的設計過程中,并沒有使用到任何其他的校準調試的按鍵等等按鈕,有需要使用到按鍵進行調試的可在此代碼基礎上進行添加案件函數做成鬧鐘配合蜂鳴器加中斷函數,有需要全代碼的可下方留言郵箱獲取,長期發布此類文章,喜歡的可以常關注,有不對的地方歡迎大家指點。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!