27.3.4.2內核下的I2C驅動(二)
611
2022-05-29
設計內容
設計思路
設計解釋
設計環境介紹
51單片機芯片
DS1302芯片
設計內容
設計思路
設計解釋
設計環境介紹
51單片機芯片
DS1302芯片
程序解釋
硬件部分
軟件部分
設計體會與建議
LCD顯示萬年歷部分程序
設計內容
萬年歷是采用數字電路實現對時、分、秒等信息進行數字顯示的計時裝置。廣泛用于個人、家庭,車站,碼頭辦公室等公共場所,成為人們日常生活中不可少的必需品,由于數字集成電路的發展和石英晶體振蕩器的廣泛應用,使得數字鐘的精度,遠遠超過老式鐘表,鐘表的數字化給人們生產生活帶來了極大的方便,而且大大地擴展了鐘表原先的報時功能。諸如定時自動報警、按時自動打鈴、時間程序自動控制、定時廣播、自動起閉路燈、定時開關烘箱、通斷動力設備、甚至各種定時電氣的自動啟用等,但是所有這些,都是以鐘表數字化為基礎的。因此,研究萬年歷及擴大其應用,有著非常現實的意義。
本設計是電子萬年歷能顯示年月日時分秒及星期,并具有可調整日期和時間功能。本設計以數字集成電路技術為基礎,單片機(8051)技術為核心,來實現電子萬年歷的功能。
設計思路
設計一臺電子萬年歷,主控芯片采用STC89C516單片機,日歷時鐘芯片采用美國DALLAS公司推出的高性能、低功耗、帶RAM的實時時鐘DS1302,顯示器采用點陣字符型液晶顯示模塊,分2行顯示,第1行顯示日、月、年,第2行顯示時、分、秒。
使用DS1302時鐘芯片與單片機8051相連接,通過軟件編程的方法實現了以24小時為一個周期同時顯示小時,分鐘和秒采集并顯示的要求;利用單片機定時器及計數器產生定時效果通過編程形成數字鐘效果,再利用點陣字符型液晶顯示模塊動態掃描顯示單片機內部處理的數據。同時通過端口讀入當前外部控制狀態來改變程序的不同狀態,實現不同功能。本電子萬年歷采用單片機利用C語言來設計制作完成,由于其功能的實現主要通過軟件編程來完成,這就降低了硬件電路的復雜性,也降低了成本。
設計與制作中之所以選用單片機8051,是因為它是低功耗、高性能的CMOS型8位單片機。片內帶有4KB的存儲器,且允許在系統內改寫或用編程器編程。因此,采用8051原理制作的電子萬年歷,不僅僅在原理上能夠成功實現計時等功能,也更經濟,更適用,更符合我們實際生活的需要。
設計解釋
設計環境介紹
對此次作品的方案選定:采用8051作為主控制系統;DS1302提供時鐘;LCD液晶顯示屏作為顯示。利用C語言進行軟件開發。
單片微型計算機簡稱為單片機,又稱為微型控制器,是微型計算機的一個重要分支。單片機是70年代中期發展起來的一種大規模集成電路芯片,是CPU、RAM、ROM、I/O接口和中斷系統于同一硅片的器件。80年代以來,單片機發展迅速,各類新產品不斷涌現,出現了許多高性能新型機種,現已逐漸成為工廠自動化和各控制領域的支柱產業之一。
MCS-51是標準的40引腳雙列直插式集成電路芯片,引腳分布如圖。
P0.0 ~ P0.7 P0口8位雙向口線(在引腳的39 ~ 32號端子)。
P1.0 ~ P1.7 P1口8位雙向口線(在引腳的1 ~ 8號端子)。
P2.0 ~ P2.7 P2口8位雙向口線(在引腳的21 ~ 28號端子)。
P3.0 ~ P3.7 P3口8位雙向口線(在引腳的10 ~ 17號端子)。
P0口的三個功能
外部擴展存儲器時,當做數據總線(如圖1中的D0~D7為數據總線接口)
外部擴展存儲器時,當作地址總線(如圖1中的A0~A7為地址總線接口)
不擴展時,可做一般的I/O使用,但內部無上拉電阻,作為輸入或輸出時應外部接上拉電阻。
P1及P2口功能
P1口只做I/O口使用:其內部有上拉電阻。
P2口有兩個功能:
擴展外部存儲器時,當作地址總線使用
做一般I/O口使用,其內部有上拉電阻;
P3口有兩個功能:
除了作為I/O使用外(其內部有上拉電阻),還有一些特殊功能,寄存器來設置,具體功能請參考前面的引腳說明。
DS1302 是DALLAS 公司推出的涓流充電時鐘芯片,內含有一個實時時鐘/日歷和31 字節靜態RAM,通過簡單的串行接口與單片機進行通信實時時鐘/日歷電路,提供秒分時日日期/月年的信息,每月的天數和閏年的天數可自動調整時鐘操作可通過AM/PM 指示決定采用24或12 小時格式。DS1302 與單片機之間能簡單地采用同步串行的方式進行通信,僅需用到三個口線:1、RES 復位,2、I/O 數據線,3 、SCLK串行時鐘。時鐘/RAM 的讀/寫數據以一個字節或多達31個字節的字符組方式通信。DS1302 工作時功耗很低,保持數據和時鐘信息時功率小于1mW。DS1302 是由DS1202 改進而來,增加了以下的特性。雙電源管腳用于主電源和備份電源供應Vcc1,為可編程涓流充電電源附加七個字節存儲器。它廣泛應用于電話傳真便攜式儀器以及電池供電的儀器儀表等產品領域。
DS1302 內部寄存器
CH: 時鐘停止位 存器2 的第7 位12/24 小時標志
CH=0 振蕩器工作允許 bit7=1,12 小時模式
CH=1 振蕩器停止 bit7=0,24 小時模式
WP: 寫保護位 寄存器2 的第5 位:AM/PM 定義
WP=0 寄存器數據能夠寫入 AP=1 下午模式
WP=1 寄存器數據不能寫入 AP=0 上午模式
TCS: 涓流充電選擇 DS: 二極管選擇位
TCS=1010 使能涓流充電 DS=01 選擇一個二極管
TCS=其它 禁止涓流充電 DS=10 選擇兩個二極管
DS1302的應用
實時時鐘芯片DS1302采用串行數據傳輸,可為掉電保護電源提供可編程的充電功能,也可以關閉充電功能,芯片采用32768Hz晶振。要特別說明的是,備用電源BT1可以用電池或超級電容(10萬μF以上)。雖然DS1302在主電源掉電后耗電很小,但如果要長時間保證時鐘正常,最好選用小型充電電池。如果斷電時間較短(幾小時或幾天),可以用漏電較小的普通電解電容代替(100μF就可以保證1小時的正常走時)[9]。DS1302在第一次加電后,需進行初始化操作。初始化后就可以按正常方法調整時間及鬧鈴。
程序解釋
系統的硬件部分主要由主控制器單片機,顯示電路,時鐘電路構成。系統電路框圖如圖所示。
8051單片機與DS1302之間采用3線串行通信方式。復位/通信允許信號RST接到單片機的P1.5引腳,RST=1允許通信,RST=0禁止通信;串行時鐘信號SCLK接到單片機的P1.6引腳;數據輸入/輸出信號I/O接到單片機的P1.7引腳。8051作為主機通過控制RST、SCLK和I/O信號實現兩芯片間的數據傳送。
DS1302芯片的X1和X2端外接32.768KHz的石英晶振,Vcc1和Vcc2是電源引腳,單電源供電時接Vcc1腳,雙電源供電時主電源接Vcc2,備份電池接Vcc1,如果采用可充電鎳鎘電池,可啟用內部涓流充電器在主電壓正常時向電池充電,以延長電池使用時間。備份電池也可用1μF以上的超容量電容代替,需要注意備份電池電壓應略低于主電源工作電壓。
數據傳送是以8051單片機為主控芯片進行的,每次傳送時由8051向DS1302寫入一個命令字節開始。命令字節的格式如下
跟著再接收來命令字節的最高位必須為1。RAM/CK位為DS1302片內RAM/時鐘選擇位,RAM/CK=1選擇RAM操作,RAM/CK=0選擇時鐘操作。RD/W位為讀寫控制位,RD/W=1為讀操作,表示DS1302接受完命令字節后,按指定的選擇對象及寄存器(或RAM)地址,讀取數據并通過I/O線傳送給單片機8051.RD/W=0為寫操作,表示DS1302接受完命令字節后,緊自單片機8051的數據字節,并寫入到DS1302相應的寄存器或RAM單元中。A4~A0為片內日歷時鐘寄存器或RAM的地址選擇位。
DS1302與8051之間通過I/O線進行同步串行數據傳送,SCLK為串行通信時的位同步時鐘,一個SCLK脈沖傳送一位數據。每次數據傳送時都以字節為單位,低位在前,高位在后,傳送一個字節需要8個脈沖。數據傳送可以單字節方式或多字節突發方式進行。
數據單字節方式傳送時序如圖3所示,在RST=1期間,8051單片機先向DS1302發送一個命令字節,緊接發送一個字節的數據,DS1302在接收的命令字節后自動將數據寫入指定的片內地址或從該地址讀取數據。
DS1302共有12個寄存器,其中7個寄存器與日歷時鐘有關,存放的數據為BCD碼格式,日歷、時鐘寄存器地址及其內容如圖5所示。秒寄存器的第7位為時鐘暫??刂莆?,該位為1時暫停時鐘振蕩器,DS1302進入低功耗狀態,該位為0時啟動時鐘。時寄存器的第7位為12或24小時方式選擇,該位為1時選擇12小時方式,該位為0時選擇24小時方式。在12小時方式下,時寄存器的第5位為AM/PM選擇,該位為1時選擇PM,該位為0時選擇AM,在24小時方式下,時寄存器的第5位為第2個小時位(20~23)。
電子萬年歷的顯示部分采用點陣字符型液晶顯示模塊,以直接方式與8051單片機進行接口。將單片機的P2.7通過適當邏輯門電路組合接到液晶顯示模塊的E端,P0口通過外部鎖存器得到的最低2位地址線A0和A1分別接到液晶顯示模塊的RW和RS端,從而可得該接口電路的命令寫入地址為7FF0H,命令讀取地址為7FF1H,數據操作地址為7FF2H,分別對這3個地址進行操作即可將DS1302中的日歷時鐘信息顯示在LCD屏幕上。
Keil軟件是目前最流行開發MCS-51系列單片機的軟件,Keil C51生成的目標代碼效率非常之高,多數語句生成的匯編代碼很緊湊,容易理解。在開發大型軟件時更能體現高級語言的優勢。Keil提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調試器等在內的完整開發方案,通過一個集成開發環境(uVision)將這些部分組合在一起。運行Keil軟件需要Pentium或以上的CPU,16MB或更多RAM、20M以上空閑的硬盤空間、WIN98、NT、WIN2000、WINXP等操作系統。
由前述可知,從P2 口輸出位選碼,從P0 口輸出段選碼,LED 就會顯示出數字來。但P0口的輸出的數據是要BCD 碼,各存儲單元存儲的是二進制數,也就是和要顯示出的字符表達的含義是不一致的。可見,將要顯示的存儲單元的數據直接送到P0 口去驅動LED 數碼管顯示是不能正確表達的,必須在系統內部將要顯示的數據經過BCD 碼行轉換后,將各個單元數據的段選代碼送入P0 口,給CD4511 譯碼后去驅動數碼管顯示。
我們先將要顯示的數據裝入累加器A 中,再將A 中的數據轉換成高低兩位的BCD 碼,再放回A 中,然后將A 中的值輸出。如:有一個單元存儲了45 這樣一位數,則需轉換成四位的BCD 碼:(0100)(0101)然后放入A 中。 A 中BCD 碼,高位四位代表4低四位代表5同時送給兩個譯碼器中,譯碼后45字就在兩個LED 中顯示出來。
時間的運行依靠定時中斷子程序對時鐘單元數值進位調整來實現的。計數器T0 打開后,進入計時,滿100 毫秒后,重裝定時。中斷一次,滿一秒后秒進位,滿60 秒后即為1 分鐘,分鐘單元進位,60 分到了后,時單元進位,24 小時滿后,天單元進位。這樣然后根據進率,得到年、月、日、時、分、秒存儲單元的值,并經譯碼后,通過掃描程序送LED 中顯示出來,實現時鐘計時功能。累加是用指令INC 來實現的。進入中斷服務程序以后,執行PUSH PSW 和PUSH A 將程序狀態寄存器PSW 的內容和累加器A 中的數據保存起來,這便是所謂的保護現場 ,以保護現場和恢復現場時存取關鍵
數據的存儲區叫做堆棧。在軟件的控制之下,堆棧可在片內RAM 中的任一區間設定,而堆棧的數據存取與一般的RAM 存取又有區別,對它的操作,要遵循后進先出的原則。
系統軟件設計主要包括主程序設計、日期數據采集子模塊程序設計、按鍵處理子模塊程序設計和顯示子模塊程序設計等。主程序主要完成器件的初始化,并判斷有無按鍵按下,并根據判斷的結果調用相應的子模塊程序:日期數據采集子模塊程序完成相應的數據采集、處理和保存,按鍵處理子模塊程序完成日期的設置,而顯示子模塊程序只要把上述子模塊儲存的數據送去顯示即可。
設計體會與建議
當電子萬年歷可以成功實現時,那種激動和喜悅只有自己可以體會。在整個設計過程中,自主學習,學到了許多沒學到的知識。較好的完成了設計,達到了預期的目的,完了最初的設想。對電路的設計、布局要先有一個好的構思,才顯得電路板美觀、大方。程序編寫中,由于思路不清晰,開始時遇到了很多的問題,經過靜下心來思考,和同學討論,理清了思路,反而得心應手。在此次設計中,知道了做事要有一顆平常的心,不要想著走捷徑,一步一個腳印。此次課程設計中學到了很多很多東西,這是最重要的??傊舜握n程設計使我的能力得到了全方位的提高,使得我的操作能力和專業技能都有了很大的提高。
LCD顯示萬年歷部分程序
/******************************************************************************* 注意事項: 單片機與獨立按鍵連接說明: K1-->P31 K2-->P30 K3-->P32 單片機與DS1302模塊接線說明: P34-->DIO P35-->CE P36-->CLK 實驗操作: LCD1602顯示時鐘,按K3鍵進入時鐘設置,此時秒鐘停止走動,按K2鍵選擇設置的秒、分、時、 日、月、星期、年,按K1鍵進行加1,設置完成后,再次按下K3鍵繼續走時 *******************************************************************************/ void main() { unsigned char i; Int0Configuration(); LcdInit(); // 顯示屏初始化 Ds1302Init(); // 時鐘初始化 while(1) { if(SetState == 0) { Ds1302ReadTime(); // 讀取時間 } else { if(K1==0) // 檢測按鍵K1是否按下 { Delay10ms(); // 消除抖動 if(K1 == 0) { SetPlace++; if(SetPlace >= 7) SetPlace=0; } while((i < 50) && ( K1==0 )) //檢測按鍵是否松開 { Delay10ms(); // 消除抖動 i++; } i = 0; } if(K2 == 0) //檢測按鍵K2是否按下 { Delay10ms(); //消除抖動 if(K2 == 0) { TIME[SetPlace]++; if((TIME[SetPlace]&0x0f) > 9) //換成BCD碼。 { TIME[SetPlace] = TIME[SetPlace] + 6; } if((SetPlace < 2) && (TIME[SetPlace] >= 0x60)) // 分秒只能到59 { TIME[SetPlace] = 0; } if((SetPlace == 2) && (TIME[2] >= 0x24)) //小時只能到23 { TIME[SetPlace] = 0; } if (SetPlace == 3) // 日期限制 { int isYear = 0; int i; for ( i = 0; i < 25; i++) { if (year[i] == TIME[6]) { isYear=1; break; } } if (TIME[4]==0x02) // 閏年2月最多29天 { if (TIME[3]==0x29 && isYear==1) { TIME[3]=0x01; } if (TIME[3]>=0x30) { TIME[3]=0x01; } } else if (TIME[4] == 0x01 || TIME[4] == 0x03 || TIME[4] == 0x05 || TIME[4] == 0x07 || TIME[4] == 0x08 || TIME[4] == 0x10 || TIME[4] == 0x12) // 1、3、5、7、8、10、12最多31天 { if (TIME[3] >= 0x32) { TIME[3] = 0x01; } } else{ if (TIME[3] >= 0x31) { TIME[3] = 0x01; } } } if((SetPlace == 4) && TIME[4] >= 0x13 ){ // 月只能到12 TIME[SetPlace]=0x01; } if((SetPlace == 5) && (TIME[5] >= 0x8)) // 校正星期數值 { TIME[SetPlace] = 1; } if ((SetPlace == 6) && TIME[6] > 0x99 ) { TIME[6] = 0x00; } } while((i<50)&&(K2==0)) //檢測按鍵是否松開 { Delay10ms(); i++; } i=0; } } LcdDisplay(); } } // 顯示函數 void LcdDisplay() { LcdWriteCom(0x80 + 0X40); LcdWriteData('0' + TIME[2] / 16); // 時 LcdWriteData('0' + (TIME[2] & 0x0f)); LcdWriteData('-'); LcdWriteData('0' + TIME[1] / 16); // 分 LcdWriteData('0'+(TIME[1] & 0x0f)); LcdWriteData('-'); LcdWriteData('0' + TIME[0] / 16); // 秒 LcdWriteData('0' + (TIME[0] & 0x0f)); LcdWriteCom(0x80); LcdWriteData('2'); LcdWriteData('0'); LcdWriteData('0' + TIME[6] / 16); // 年 LcdWriteData('0' + (TIME[6] & 0x0f)); LcdWriteData('-'); LcdWriteData('0' + TIME[4] / 16); // 月 LcdWriteData('0' + (TIME[4] & 0x0f)); LcdWriteData('-'); LcdWriteData('0' + TIME[3] / 16); // 日 LcdWriteData('0' + (TIME[3] & 0x0f)); LcdWriteCom(0x8F); LcdWriteData('0' + (TIME[5] & 0x07)); // 星期 }
IoT 單片機 嵌入式 硬件開發
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。