ARM嵌入基礎(chǔ)應(yīng)用 16_第1頁
ARM嵌入基礎(chǔ)應(yīng)用 16_第2頁
ARM嵌入基礎(chǔ)應(yīng)用 16_第3頁
ARM嵌入基礎(chǔ)應(yīng)用 16_第4頁
ARM嵌入基礎(chǔ)應(yīng)用 16_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第15章

RTC時(shí)鐘與DS18B20傳感器作者:黃克亞2025年5月本章概要CONTENTSRTC時(shí)鐘DS18B20時(shí)序與函數(shù)驅(qū)動(dòng)BKP寄存器DS18B20簡(jiǎn)介與功能特性帶溫度顯示的電子萬年歷項(xiàng)目15.1RTC時(shí)鐘STM32F103微控制器內(nèi)部也集成了一個(gè)RTC模塊,可以實(shí)現(xiàn)不間斷計(jì)時(shí),大大簡(jiǎn)化系統(tǒng)軟硬件設(shè)計(jì)難度。15.1RTC時(shí)鐘15.1.1RTC簡(jiǎn)介RTC(Real-TimeClock),即實(shí)時(shí)時(shí)鐘。實(shí)時(shí)時(shí)鐘是一個(gè)獨(dú)立的定時(shí)器。RTC模塊擁有一組連續(xù)計(jì)數(shù)的計(jì)數(shù)器,在相應(yīng)軟件配置下,可提供時(shí)鐘日歷的功能。修改計(jì)數(shù)器的值可以重新設(shè)置系統(tǒng)當(dāng)前的時(shí)間和日期。RTC及其時(shí)鐘都使用備用存儲(chǔ)區(qū)域,而備用存儲(chǔ)區(qū)域使用VBAT備用電源(一般為紐扣電池),所以主電源斷電或系統(tǒng)復(fù)位也不影響RTC的工作。15.1RTC時(shí)鐘15.1.2RTC主要特性可編程的預(yù)分頻系數(shù):分頻系數(shù)最高為220。32位的可編程計(jì)數(shù)器,可用于較長(zhǎng)時(shí)間段的測(cè)量。2個(gè)分離的時(shí)鐘:用于APB1接口的PCLK1和RTC時(shí)鐘三種RTC的時(shí)鐘源:HSE時(shí)鐘除以128;LSE振蕩器時(shí)鐘;LSI振蕩器時(shí)鐘。2個(gè)獨(dú)立的復(fù)位類型:APB1接口由系統(tǒng)復(fù)位;RTC核心只能由后備域復(fù)位。3個(gè)專門的可屏蔽中斷:鬧鐘中斷,秒中斷,溢出中斷。RTC主要特性15.1RTC時(shí)鐘15.1.3RTC內(nèi)部結(jié)構(gòu)第一部分(APB1接口)用來和APB1總線相連。此單元還包含一組16位寄存器,可通過APB1總線對(duì)其進(jìn)行讀寫操作。第二部分(RTC核心)由一組可編程計(jì)數(shù)器組成,分成兩個(gè)主要模塊。第一個(gè)模塊是RTC的預(yù)分頻模塊,它可編程產(chǎn)生最長(zhǎng)為1s的RTC時(shí)間基準(zhǔn)TR_CLK。第二個(gè)模塊是一個(gè)32位的可編程計(jì)數(shù)器,可被初始化為當(dāng)前的系統(tǒng)時(shí)間。15.1RTC時(shí)鐘15.1.4RTC復(fù)位過程RTC核心又稱為后備區(qū)域,即圖中加陰影部分,系統(tǒng)電源正常時(shí)由VDD(即3.3V)供電,當(dāng)VDD電源被切斷,它們?nèi)匀挥蒝BAT(鈕扣電池)維持供電。系統(tǒng)復(fù)位或從待機(jī)模式喚醒后,RTC的設(shè)置和時(shí)間維持不變,即后備區(qū)域獨(dú)立工作。15.2備份寄存器(BKP)備份寄存器處于后備區(qū)域,不受復(fù)位影響。15.2備份寄存器(BKP)15.2.1BKP簡(jiǎn)介備份寄存器是42個(gè)16位的寄存器,可用來存儲(chǔ)84個(gè)字節(jié)的用戶應(yīng)用程序數(shù)據(jù)。它們處在備份域里,當(dāng)VDD電源被切斷,它們?nèi)匀挥蒝BAT維持供電。當(dāng)系統(tǒng)在待機(jī)模式下被喚醒,或系統(tǒng)復(fù)位,或電源復(fù)位時(shí),他們也不會(huì)被復(fù)位。此外,BKP控制寄存器用來管理侵入檢測(cè)和RTC校準(zhǔn)功能。復(fù)位后,對(duì)備份寄存器和RTC的訪問被禁止,并且備份域被保護(hù)以防止可能存在的意外的寫操作。15.2備份寄存器(BKP)15.2.2BKP特性20字節(jié)數(shù)據(jù)后備寄存器(中容量和小容量產(chǎn)品),或84字節(jié)數(shù)據(jù)后備寄存器(大容量和互聯(lián)型產(chǎn)品)。用來管理防侵入檢測(cè)并具有中斷功能的狀態(tài)/控制寄存器。用來存儲(chǔ)RTC校驗(yàn)值的校驗(yàn)寄存器。在PC13引腳(當(dāng)該引腳不用于侵入檢測(cè)時(shí))上輸出RTC校準(zhǔn)時(shí)鐘,RTC鬧鐘脈沖或者秒脈沖。1234BKP特性15.3RTC時(shí)鐘的操作對(duì)RTC時(shí)鐘的操作主要是初始化RTC,之后只要讀取時(shí)鐘數(shù)值即可15.3RTC時(shí)鐘的操作14.1.2I2C總線的數(shù)據(jù)傳送打開相應(yīng)的時(shí)鐘先就需要打開備份區(qū)域時(shí)鐘。而一般操作RTC,還會(huì)用到一個(gè)時(shí)鐘,就是電源時(shí)鐘,在電源控制里面有操作RTC的一些設(shè)置,所以還要將電源控制的時(shí)鐘打開。其參考代碼如下:01使能備份寄存器操作可以使用PWR_BackupAccessCmd()函數(shù),它只有一個(gè)參數(shù),也就是設(shè)置的狀態(tài),因要使能所以設(shè)為ENABLE。02RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//打開電源時(shí)鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE);//打開BKP備份區(qū)域時(shí)鐘復(fù)位備份寄存器當(dāng)然這個(gè)操作不要每次都執(zhí)行,因?yàn)閭浞輩^(qū)域的復(fù)位將導(dǎo)致之前存在的數(shù)據(jù)丟失,所以要不要復(fù)位,視情況而定。可以使用BKP_DeInit()函數(shù)復(fù)位備份寄存器。0315.3RTC時(shí)鐘的操作14.1.2I2C總線的數(shù)據(jù)傳送設(shè)置外部低速時(shí)鐘要使用外部的低速時(shí)鐘來控制RTC,代碼為:04RCC_LSEConfig(RCC_LSE_ON);//設(shè)置外部低速晶振(LSE),使用外設(shè)低速晶振。使能RTC時(shí)鐘打開RTC,代碼為:05在開啟外部低速時(shí)鐘的時(shí)候,確定它是否成功起振,需檢測(cè)外部低速時(shí)鐘是否開啟。代碼為:while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET);/*檢查指定的RCC標(biāo)志位設(shè)置與否,等待低速晶振(LSE)就緒*/等待它起振好了之后將它作為RTC的時(shí)鐘,代碼為:RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//設(shè)置RTC時(shí)鐘(RTCCLK),選擇LSE作為RTC時(shí)鐘RCC_RTCCLKCmd(ENABLE);//使能RTC時(shí)鐘在對(duì)RTC連續(xù)操作的時(shí)候還要檢測(cè)它是否執(zhí)行完成,才能夠接著對(duì)它進(jìn)行操作,所以操作完之后再檢測(cè)是否操作完成。代碼為:RTC_WaitForLastTask();//等待最近一次對(duì)RTC寄存器的寫操作完成15.3RTC時(shí)鐘的操作14.1.2I2C總線的數(shù)據(jù)傳送等待RTC時(shí)鐘寄存器同步要其參考代碼如下:06RTC_WaitForSynchro();//等待RTC寄存器同步開啟秒中斷要讀取時(shí)鐘,每秒更新一次,所以開啟秒中斷。其參考代碼如下:07RTC_ITConfig(RTC_IT_SEC,ENABLE);//使能RTC秒中斷,然后等待操作完成。RTC_WaitForLastTask();//等待最近一次對(duì)RTC寄存器的寫操作完成。設(shè)置RTC時(shí)鐘的預(yù)分頻要進(jìn)行32768分頻。其參考代碼如下:08RTC_SetPrescaler(32768-1);//設(shè)置RTC預(yù)分頻的值然后等待操作完成RTC_WaitForLastTask();//等待最近一次對(duì)RTC寄存器的寫操作完成設(shè)置初始化時(shí)間設(shè)置初始化時(shí)間也就是將要初始化的時(shí)鐘存入到32位寄存器。這里原理就是,直接將對(duì)應(yīng)的時(shí)間數(shù)據(jù)轉(zhuǎn)換為秒數(shù)值寫入到32位寄存器中,每當(dāng)這個(gè)32位寄存器加1,那么比0時(shí)0分0秒,多了一秒就是0時(shí)0分1秒。因此到時(shí)候直接讀取寄存器值即可。0915.3RTC時(shí)鐘的操作15.3.2.RTC時(shí)間寫入初始化RTC時(shí)間寫入初始化,分為兩種情況:一種情況是第一次使用RTC,需要對(duì)RTC完全初始化,即15.3.1所介紹的所有步驟均應(yīng)包含在內(nèi),還需要將當(dāng)前時(shí)間對(duì)應(yīng)數(shù)值寫入到RTC_CNT寄存器當(dāng)中,并向BKP_DR1寄存器中寫入數(shù)值0XA5A5,表示已經(jīng)初始化過RTC寄存器;另一種情況是斷電恢復(fù)或是上電復(fù)位,而不希望復(fù)位RTC寄存器后備區(qū)域,此時(shí)只需要等待RTC寄存器同步和使能RTC秒中斷即可,具體代碼會(huì)在文中后續(xù)部分貼出。15.4RTC與BKP相關(guān)庫(kù)函數(shù)介紹RTC與BKP庫(kù)函數(shù)接口,具體應(yīng)用將會(huì)在項(xiàng)目實(shí)例中詳細(xì)介紹。15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.1函數(shù)PWR_BackupAccessCmd函數(shù)名PWR_BackupAccessCmd函數(shù)原形voidPWR_BackupAccessCmd(FunctionalStateNewState)功能描述使能或者失能RTC和后備寄存器訪問輸入?yún)?shù)NewState:RTC和后備寄存器訪問的新狀態(tài),這個(gè)參數(shù)可以取:ENABLE或者DISABLE輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無15.4.2函數(shù)BKP_DeInit()函數(shù)名BKP_DeInit函數(shù)原形voidBKP_DeInit(void)功能描述將外設(shè)BKP的全部寄存器重設(shè)為缺省值輸入?yún)?shù)無輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)RCC_BackupResetCmd例:/*EnableaccesstotheRTCandbackupregisters*/PWR_BackupAccessCmd(ENABLE);例:/*ResettheBKPregisters*/BKP_DeInit();15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.3函數(shù)RCC_LSEConfigRCC_LSE:該參數(shù)設(shè)置了LSE的狀態(tài)函數(shù)名RCC_LSEConfig函數(shù)原形voidRCC_LSEConfig(u32RCC_LSE)功能描述設(shè)置外部低速晶振(LSE)輸入?yún)?shù)RCC_LSE:LSE的新狀態(tài),參閱Section:RCC_LSE查閱更多該參數(shù)允許取值范圍輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無例:/*EnabletheLSE*/RCC_LSEConfig(RCC_LSE_ON);RCC_LSE描述RCC_LSE_OFFLSE晶振OFFRCC_LSE_ONLSE晶振ONRCC_LSE_BypassLSE晶振被外部時(shí)鐘旁路15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.4函數(shù)RCC_GetFlagStatusRCC_FLAG:給出了所有可以被函數(shù)RCC_GetFlagStatus檢查的標(biāo)志位列表。函數(shù)名RCC_GetFlagStatus函數(shù)原形FlagStatusRCC_GetFlagStatus(u8RCC_FLAG)功能描述檢查指定的RCC標(biāo)志位設(shè)置與否輸入?yún)?shù)RCC_FLAG:待檢查的RCC標(biāo)志位參閱Section:RCC_FLAG查閱更多該參數(shù)允許取值范圍輸出參數(shù)無返回值RCC_FLAG的新狀態(tài)(SET或者RESET)先決條件無被調(diào)用函數(shù)無RCC_FLAG描述RCC_FLAG_HSIRDYHSI晶振就緒RCC_FLAG_HSERDYHSE晶振就緒RCC_FLAG_PLLRDYPLL就緒RCC_FLAG_LSERDYLSI晶振就緒RCC_FLAG_LSIRDYLSE晶振就緒RCC_FLAG_PINRST管腳復(fù)位RCC_FLAG_PORRSTPOR/PDR復(fù)位9RCC_FLAG_SFTRST軟件復(fù)位RCC_FLAG_IWDGRSTIWDG復(fù)位RCC_FLAG_WWDGRSTWWDG復(fù)位RCC_FLAG_LPWRRST低功耗復(fù)位例:/*TestifthePLLclockisreadyornot*/FlagStatusStatus;Status=RCC_GetFlagStatus(RCC_FLAG_PLLRDY);15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.5函數(shù)RCC_RTCCLKConfigRCC_RTCCLKSource:該參數(shù)設(shè)置了RTC時(shí)鐘(RTCCLK)函數(shù)名RCC_RTCCLKConfig函數(shù)原形voidRCC_RTCCLKConfig(u32RCC_RTCCLKSource)功能描述設(shè)置RTC時(shí)鐘(RTCCLK)輸入?yún)?shù)RCC_RTCCLKSource:定義RTCCLK參閱Section:RCC_RTCCLKSource查閱更多該參數(shù)允許取值范圍輸出參數(shù)無返回值無先決條件RTC時(shí)鐘一經(jīng)選定即不能更改,除非復(fù)位后備域被調(diào)用函數(shù)無RCC_RTCCLKSource描述RCC_RTCCLKSource_LSE

選擇LSE作為RTC時(shí)鐘RCC_RTCCLKSource_LSI

選擇LSI作為RTC時(shí)鐘RCC_RTCCLKSource_HSE_Div128

選擇HSE時(shí)鐘頻率除以128作為RTC時(shí)鐘例:/*SelecttheLSEasRTCclocksource*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.6函數(shù)RCC_RTCCLKCmd15.4.7函數(shù)RTC_WaitForSynchro函數(shù)名RCC_RTCCLKCmd函數(shù)原形voidRCC_RTCCLKCmd(FunctionalStateNewState)功能描述使能或者失能RTC時(shí)鐘輸入?yún)?shù)NewState:RTC時(shí)鐘的新狀態(tài),這個(gè)參數(shù)可以取:ENABLE或者DISABLE輸出參數(shù)無返回值無先決條件該函數(shù)只有在通過函數(shù)RCC_RTCCLKConfig選擇RTC時(shí)鐘后,才能調(diào)用被調(diào)用函數(shù)無函數(shù)名RCC_RTCCLKCmd函數(shù)名RTC_WaitForSynchro函數(shù)原形voidRTC_WaitForSynchro(void)功能描述等待RTC寄存器與RTC的APB時(shí)鐘同步輸入?yún)?shù)無輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無例:/*EnabletheRTCclock*/RCC_RTCCLKCmd(ENABLE);例:/*WaituntiltheRTCregistersaresynchronizedwithRTCAPBclock*/RTC_WaitForSynchro();15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.8函數(shù)RTC_WaitForLastTask函數(shù)名RTC_WaitForLastTask函數(shù)原形voidRTC_WaitForLastTask(void)功能描述等待最近一次對(duì)RTC寄存器的寫操作完成輸入?yún)?shù)無輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無15.4.10函數(shù)RTC_SetPrescaler函數(shù)名RTC_SetPrescaler函數(shù)原形voidRTC_SetPrescaler(u32PrescalerValue)功能描述設(shè)置RTC預(yù)分頻的值輸入?yún)?shù)PrescalerValue:新的RTC預(yù)分頻值輸出參數(shù)無返回值無先決條件在使用本函數(shù)前必須先調(diào)用函數(shù)RTC_WaitForLastTask(),等待標(biāo)志位RTOFF被設(shè)置被調(diào)用函數(shù)RTC_EnterConfigMode()RTC_ExitConfigMode()例:/*WaituntillastwriteoperationonRTCregistersisterminated*/RTC_WaitForLastTask();/*SetsAlarmvalueto0x10*/RTC_SetAlarm(0x10);例:/*WaituntillastwriteoperationonRTCregistersisterminated*/RTC_WaitForLastTask();/*SetsPrescalervalueto0x7A12*/RTC_SetPrescaler(0x7A12);15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.9函數(shù)RTC_ITConfigRTC_IT:輸入?yún)?shù)RTC_IT使能或者失能RTC的中斷。函數(shù)名RTC_ITConfig函數(shù)原形voidRTC_ITConfig(u16RTC_IT,FunctionalStateNewState)功能描述使能或者失能指定的RTC中斷輸入?yún)?shù)1RTC_IT:待使能或者失能的RTC中斷源參閱Section:RTC_IT查閱更多該參數(shù)允許取值范圍輸入?yún)?shù)2NewState:RTC中斷的新狀態(tài)這個(gè)參數(shù)可以取:ENABLE或者DISABLE輸出參數(shù)無返回值無先決條件在使用本函數(shù)前必須先調(diào)用函數(shù)RTC_WaitForLastTask(),等待標(biāo)志位RTOFF被設(shè)置被調(diào)用函數(shù)無例:/*WaituntillastwriteoperationonRTCregistersisterminated*/RTC_WaitForLastTask();/*Alarminterruptenabled*/RTC_ITConfig(RTC_IT_ALR,ENABLE);RTC_IT描述RTC_IT_OW溢出中斷使能RTC_IT_ALR鬧鐘中斷使能RTC_IT_SEC秒中斷使能15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.11函數(shù)RTC_SetCounter函數(shù)名RTC_SetCounter函數(shù)原形voidRTC_SetCounter(u32CounterValue)功能描述設(shè)置RTC計(jì)數(shù)器的值輸入?yún)?shù)CounterValue:新的RTC計(jì)數(shù)器值輸出參數(shù)無返回值無先決條件在使用本函數(shù)前必須先調(diào)用函數(shù)RTC_WaitForLastTask(),等待標(biāo)志位RTOFF被設(shè)置被調(diào)用函數(shù)RTC_EnterConfigMode()RTC_ExitConfigMode()15.4.12函數(shù)RTC_GetCounter()函數(shù)名RTC_GetCounter函數(shù)原形u32RTC_GetCounter(void)功能描述獲取RTC計(jì)數(shù)器的值輸入?yún)?shù)無輸出參數(shù)無返回值RTC計(jì)數(shù)器的值先決條件無被調(diào)用函數(shù)無例:/*WaituntillastwriteoperationonRTCregistersisterminated*/RTC_WaitForLastTask();/*SetsCountervalueto0xFFFF5555*/RTC_SetCounter(0xFFFF5555);例:/*Getsthecountervalue*/u32RTCCounterValue;RTCCounterValue=RTC_GetCounter();15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.13函數(shù)BKP_ReadBackupRegister函數(shù)名BKP_ReadBackupRegister函數(shù)原形u16BKP_ReadBackupRegister(u16BKP_DR)功能描述從指定的后備寄存器中讀出數(shù)據(jù)輸入?yún)?shù)BKP_DR:數(shù)據(jù)后備寄存器輸出參數(shù)無返回值指定的后備寄存器中的數(shù)據(jù)先決條件無被調(diào)用函數(shù)無15.4.15函數(shù)RCC_ClearFlag函數(shù)名RCC_ClearFlag函數(shù)原形voidRCC_ClearFlag(void)功能描述清除RCC的復(fù)位標(biāo)志位輸入?yún)?shù)RCC_FLAG:清除的RCC復(fù)位標(biāo)志位,可以清除的復(fù)位標(biāo)志位有:RCC_FLAG_PINRST,RCC_FLAG_PORRST,RCC_FLAG_SFTRST,RCC_FLAG_IWDGRST,RCC_FLAG_WWDGRST,RCC_FLAG_LPWRRST輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無例如:/*ReadDataBackupRegister1*/u16Data;Data=BKP_ReadBackupRegister(BKP_DR1);例如:/*Cleartheresetflags*/RCC_ClearFlag();15.4RTC與BKP相關(guān)庫(kù)函數(shù)15.4.14函數(shù)BKP_WriteBackupRegisterBKP_DR:參數(shù)BKP_DR用來選擇數(shù)據(jù)后備寄存器函數(shù)名BKP_WriteBackupRegister函數(shù)原形voidBKP_WriteBackupRegister(u16BKP_DR,u16Data)功能描述向指定的后備寄存器中寫入用戶程序數(shù)據(jù)輸入?yún)?shù)1BKP_DR:數(shù)據(jù)后備寄存器參閱Section:BKP_DR查閱更多該參數(shù)允許取值范圍輸入?yún)?shù)2Data:待寫入的數(shù)據(jù)輸出參數(shù)無返回值無先決條件無被調(diào)用函數(shù)無BKP_DR描述BKP_DR描述BKP_DR1選中數(shù)據(jù)寄存器1BKP_DR6選中數(shù)據(jù)寄存器6BKP_DR2選中數(shù)據(jù)寄存器2BKP_DR7選中數(shù)據(jù)寄存器7BKP_DR3選中數(shù)據(jù)寄存器3BKP_DR8選中數(shù)據(jù)寄存器8BKP_DR4選中數(shù)據(jù)寄存器4BKP_DR9選中數(shù)據(jù)寄存器9BKP_DR5選中數(shù)據(jù)寄存器5BKP_DR10選中數(shù)據(jù)寄存器10例:/*Write0xA587toDataBackupRegister1*/BKP_WriteBackupRegister(BKP_DR1,0xA587);15.5DS18B20溫度傳感器溫度傳感器則提供了感知周圍溫度的手段,是嵌入式系統(tǒng)常用且實(shí)用的擴(kuò)展功能。15.5DS18B20溫度傳感器15.5.1功能特性與內(nèi)部結(jié)構(gòu)DS18B20是由Dallas半導(dǎo)體公司推出的一種單總線接口的溫度傳感器。與傳統(tǒng)的熱敏電阻等測(cè)溫元件相比,它是一種新型的體積小、適用電壓寬、與微處理器接口簡(jiǎn)單的數(shù)字化溫度傳感器。單總線接口具有簡(jiǎn)潔且經(jīng)濟(jì)的特點(diǎn),可使用戶輕松地組建傳感器網(wǎng)絡(luò),DS18B20測(cè)量溫度范圍為-55~+125℃,可編程配置9~12有效數(shù)據(jù)位數(shù),對(duì)應(yīng)0.5、0.25、0.125和0.0625轉(zhuǎn)換精度。測(cè)量數(shù)據(jù)直接以單總線的數(shù)字方式傳輸,大大提高了系統(tǒng)的抗干擾性。圖15-2DS18B20內(nèi)部結(jié)構(gòu)15.5DS18B20溫度傳感器15.5.2數(shù)據(jù)組件數(shù)據(jù)組件包括64位光刻ROM、高速緩存RAM和EEPROM存儲(chǔ)器。1.光刻ROM2.高速緩存RAM光刻ROM總共64位,只能讀不能寫,其中前8位是產(chǎn)品家族碼,中間48位是DS18B20的序列號(hào),最后8位是前面56位的循環(huán)冗余校驗(yàn)碼。每片DS18B20的ROM編碼各不相同。高速緩存RAM總共9個(gè)字節(jié),用來存放各類數(shù)據(jù),各字節(jié)的作用如下:字節(jié)0、字節(jié)1:存放當(dāng)前16位溫度轉(zhuǎn)換結(jié)果,字節(jié)1為高字節(jié),字節(jié)0為低字節(jié)。D15~D11:5位,符號(hào)位S,表示溫度正負(fù),0表示正溫度,1表示負(fù)溫度。D10~D4:共7位,溫度值的整數(shù)位。D3~D0:共4位,溫度值的小數(shù)位。15.5DS18B20溫度傳感器高速緩存RAM字節(jié)2、字節(jié)3:依次為高溫觸發(fā)器TH和低溫觸發(fā)器TL,用來臨時(shí)存放用戶設(shè)定的溫度報(bào)警上限值和下限值。字節(jié)4:配置寄存器,用來臨時(shí)存放用戶設(shè)定的配置數(shù)據(jù)。D7固定為0,D4~D0固定為1,R1、R0為溫度轉(zhuǎn)換精度選擇控制位R1R0分辨率轉(zhuǎn)換精度最大轉(zhuǎn)換時(shí)間009位0.5℃93.75ms0110位0.25℃187.5ms1011位0.125℃375ms1112位0.0625℃750ms字節(jié)5~字節(jié)7:保留字節(jié)字節(jié)8:CRC校驗(yàn)字節(jié),其內(nèi)容為高速緩存RAM前8個(gè)字節(jié)內(nèi)容的循環(huán)冗余校驗(yàn)值。3.EEPROM存儲(chǔ)器EEPROM存儲(chǔ)器共3個(gè)字節(jié),分別與高速緩存RAM的字節(jié)2(TH)、字節(jié)3(TL)、字節(jié)4(配置寄存器)相對(duì)應(yīng),用來保存用戶對(duì)DS18B20的設(shè)定值。15.5DS18B20溫度傳感器15.5.3訪問命令DS18B20的ROM命令表命令代碼用法說明讀ROM33H讀取DS18B20溫度傳感器ROM中的64位編碼。匹配ROM55H發(fā)出此命令之后,接著發(fā)出64位ROM編碼,訪問單總線上與該編碼相對(duì)應(yīng)的DS18B20。跳過ROMCCH忽略64位的ROM序列號(hào)的匹配而直接訪問單總線上的DS18B20,適用于單片工作。搜索ROMF0H獲取單總線上各DS18B20的64位光刻ROM序列號(hào)。報(bào)警搜索ECH執(zhí)行該命令后,只有溫度超過設(shè)定值上限或下限的DS18B20才作出響應(yīng)。DS18B20的存儲(chǔ)控制命令命令代碼用法說明溫度轉(zhuǎn)換44H啟動(dòng)DS18B20進(jìn)行溫度轉(zhuǎn)換,結(jié)果存入內(nèi)部高速緩存RAM的字節(jié)0、字節(jié)1中。寫高速緩存RAM4EH命令后要緊隨1~3個(gè)字節(jié)的待寫人的數(shù)據(jù)。用于將數(shù)據(jù)依次寫入TH、TL和配置寄存器中。讀高速緩存RAMBEH命令執(zhí)行后,DS18B20會(huì)依次將高速緩存RAM中的字節(jié)0至字節(jié)8的內(nèi)容發(fā)送到單總線上。復(fù)制高速緩存RAM48H將高速緩存RAM中字節(jié)2至字節(jié)4的內(nèi)容復(fù)制到片內(nèi)EEPROM中。讀EEPROMB8H將片內(nèi)EEPROM的內(nèi)容對(duì)應(yīng)地復(fù)制到高速緩存RAM的字節(jié)2至字節(jié)4中。讀電源供供電方式B4H讀取DS18B20的供電方式,0:寄生供電方式,1:外部電源供電。15.5DS18B20溫度傳感器15.5.4引腳功能與接口電路DS18B20具有3引腳的TO-92和8引腳的SOIC兩種封裝形式。各封裝形式下的引腳分布如圖所示,其中NC表示空引腳,不與任何電路連接,GND為接地引腳,DQ為數(shù)據(jù)輸入/輸出引腳,VDD為可選的供電電源引腳。DS18B20可以采用DQ引腳輸入寄生電源供電,也可以采用VDD引腳連接獨(dú)立電源供電。開發(fā)板實(shí)際電路15.5DS18B20溫度傳感器15.5.5讀寫時(shí)序與驅(qū)動(dòng)函數(shù)引腳定義將實(shí)驗(yàn)平臺(tái)使用的引腳、端口以及電平操作函數(shù)采用宏定義的形式寫入到傳感器頭文件當(dāng)中。01GPIO配置DS18B20連接微控制器PE4引腳,對(duì)其進(jìn)行初始化,因采用單總線方式通信,一條數(shù)據(jù)線既需要發(fā)送數(shù)據(jù)又需要接收數(shù)據(jù),還需要分別編寫輸入配置函數(shù)和輸出配置函數(shù)。02參考代碼如下:#definedq(GPIO_Pin_4)//PE4#defineGPIO_ds18b20GPIOE#defineds18b20_dq_HGPIO_SetBits(GPIO_ds18b20,dq)#defineds18b20_dq_LGPIO_ResetBits(GPIO_ds18b20,dq)參考代碼如下:voidds18b20_init()/*DS18B20端口初始化函數(shù)*/{ GPIO_InitTypeDefGPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStructure.GPIO_Pin=dq; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIO_ds18b20,&GPIO_InitStructure);}15.5DS18B20溫度傳感器15.5.5讀寫時(shí)序與驅(qū)動(dòng)函數(shù)voidDQININT()/*GPIO輸入配置函數(shù)*/{GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=dq;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIO_ds18b20,&GPIO_InitStructure); }voidDQOUTINT()/*GPIO輸出配置函數(shù)*/{GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=dq;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIO_ds18b20,&GPIO_InitStructure); }初始化03參考代碼如下:voidds18b20init(){DQOUTINT();//配置輸出ds18b20_dq_L;delay_us(480);//延時(shí)480微妙ds18b20_dq_H;delay_us(480);//延時(shí)480微妙}15.5DS18B20溫度傳感器15.5.5讀寫時(shí)序與驅(qū)動(dòng)函數(shù)寫時(shí)序DS18B20字節(jié)寫入程序首先將數(shù)據(jù)引腳配置為輸出模式,隨后拉低總線15μs,如果待發(fā)送數(shù)據(jù)位為1則拉高總線,如果待發(fā)送數(shù)據(jù)位為0則繼續(xù)拉低總線,延時(shí)60μs,循環(huán)8次即可完成一個(gè)字節(jié)的發(fā)送。04voidds18b20wr(u8dat){u8i=0;DQOUTINT();//輸出for(i=0;i<8;i++){ds18b20_dq_L;//拉低總線delay_us(15);//延時(shí)15微妙if((dat&0x01)==1)ds18b20_dq_H;elseds18b20_dq_L;delay_us(60);//延時(shí)60微妙ds18b20_dq_H;//拉高總線dat>>=1;//準(zhǔn)備下一位數(shù)據(jù)的發(fā)送 }}15.5DS18B20溫度傳感器15.5.5讀寫時(shí)序與驅(qū)動(dòng)函數(shù)DS18B20字節(jié)讀取程序首先配置引腳為輸出模式,拉低總線4μs,再釋放總線10μs,然后配置引腳為輸入模式,讀取引腳電平,并將其移入讀入數(shù)據(jù)字節(jié)當(dāng)中,依次類推,循環(huán)8次即可完成一個(gè)字節(jié)的讀取。讀時(shí)序05DS18B20字節(jié)讀取程序首先配置引腳為輸出模式,拉低總線4μs,再釋放總線10μs,然后配置引腳為輸入模式,讀取引腳電平,并將其移入讀入數(shù)據(jù)字節(jié)當(dāng)中,循環(huán)8次即可完成一個(gè)字節(jié)的讀取。u8DS18b20rd(){u8i=0,value=0;for(i=0;i<8;i++){value>>=1;DQOUTINT();//輸出ds18b20_dq_L;//拉低delay_us(4);//延時(shí)4微妙ds18b20_dq_H;delay_us(10);//延時(shí)10微妙DQININT();//輸入配置if(GPIO_ReadInputDataBit(GPIO_ds18b20,dq)==1){value|=0x80;//讀數(shù)據(jù)從低位開始}delay_us(45);//延時(shí)45微妙}returnvalue;}15.5DS18B20溫度傳感器15.5.6讀取溫度參考代碼如下:doublereadtemp(){ u16temp; u8low,high; doublevalue; ds18b20init(); //初始化

ds18b20wr(0xcc); //發(fā)送忽略ROM指令

ds18b20wr(0x44); //發(fā)送溫度轉(zhuǎn)換指令

delay_ms(800); ds18b20init(); //初始化

ds18b20wr(0xcc); //發(fā)送忽略ROM指令

ds18b20wr(0xbe); //發(fā)讀暫存器指令

low=DS18b20rd(); //溫度的低八位

high=DS18b20rd(); //溫度的高八位

temp=high; temp=(temp<<8)+low; if((temp&0xf800)==0xf800) { temp=(~temp)+1; //負(fù)數(shù)原碼為取反加1 value=temp*(-0.0625);//乘以12位的分辨率

} else {value=temp*0.0625;//正數(shù)原碼、補(bǔ)碼相同} returnvalue;}讀取一次D18B20溫度的操作步驟如下:初始化DS18B20。因?yàn)閱纹ぷ鳎蕴^ROM操作。發(fā)送溫度轉(zhuǎn)換命令,延時(shí)等待轉(zhuǎn)換完成。再次初始化,跳過ROM操作。發(fā)送讀取溫度命令讀取溫度值。15.5DS18B20溫度傳感器15.5.6讀取溫度參考代碼如下:voidds18b20_start_convert()//啟動(dòng)溫度轉(zhuǎn)換{ds18b20init();//初始化ds18b20wr(0xcc);//發(fā)送忽略ROM指令ds18b20wr(0x44);//發(fā)送溫度轉(zhuǎn)換指令}doubleds18b20_read_operate() //讀取溫度操作{u16temp;u8low,high;doublevalue;ds18b20init(); //初始化ds18b20wr(0xcc); //發(fā)送忽略ROM指令ds18b20wr(0xbe); //發(fā)讀暫存器指令low=DS18b20rd(); //溫度的低八位high=DS18b20rd(); //溫度的高八位temp=high;temp=(temp<<8)+low;if((temp&0xf800)==0xf800){temp=(~temp)+1; //負(fù)數(shù)原碼為取反加1value=temp*(-0.0625);}else{value=temp*0.0625; //正數(shù)原碼、補(bǔ)碼相同}returnvalue;}由上述代碼可知,溫度讀取函數(shù)有一個(gè)長(zhǎng)達(dá)800ms的延時(shí),對(duì)系統(tǒng)實(shí)時(shí)性影響很大,為跳過這一長(zhǎng)延時(shí),可以將整個(gè)溫度讀取函數(shù)拆分為啟動(dòng)溫度轉(zhuǎn)換和讀取溫度操作兩個(gè)函數(shù),以便在某些場(chǎng)合進(jìn)行特殊應(yīng)用,15.6帶溫度顯示的電子萬年歷本項(xiàng)目實(shí)現(xiàn)帶溫度顯示的電子萬年歷,同時(shí)可以通過串口實(shí)現(xiàn)網(wǎng)絡(luò)時(shí)間同步。15.6帶溫度顯示的電子萬年歷15.6.1項(xiàng)目分析一是利用STM32F103微控制器的RTC模塊實(shí)現(xiàn)電子萬年歷,要求主電源斷電而計(jì)時(shí)不間斷,利用USART串口通信功能自動(dòng)將PC時(shí)間同步到實(shí)驗(yàn)平臺(tái),實(shí)現(xiàn)時(shí)間精確設(shè)置。01

數(shù)碼管動(dòng)態(tài)顯示02串口初始化03對(duì)RTC進(jìn)行初始化,寫入當(dāng)前時(shí)間數(shù)值。04RTC同步05開啟秒中斷15.6帶溫度顯示的電子萬年歷15.6.1項(xiàng)目分析另一個(gè)功能是利用單總線溫度傳感器DS18B20實(shí)時(shí)檢測(cè)環(huán)境溫度進(jìn)行DS18B20初始化DS18B20實(shí)時(shí)檢測(cè)環(huán)境溫度無限循環(huán)結(jié)構(gòu)中讀取溫度項(xiàng)目交換了操作順序,即在一個(gè)讀取周期內(nèi),先讀取上一次轉(zhuǎn)換完成的溫度數(shù)據(jù)。然后再啟動(dòng)下一次轉(zhuǎn)換,其余時(shí)間交給CPU的其他任務(wù),成功地實(shí)現(xiàn)了多任務(wù)融合。15.6帶溫度顯示的電子萬年歷第一步:復(fù)制第14章創(chuàng)建工程模板文件夾到桌面,并將文件夾改名為“14RTC+USART+18B20”,將原工程模板編譯一下,直到?jīng)]有錯(cuò)誤和警告為止。13I2C+24C0214RTC+USART+18B20第二步:為工程模板的ST_Driver項(xiàng)目組添加3個(gè)RTC操作需要用到的源文件,分別為stm32f10x_bkp.c、stm32f10x_pwr.c和stm32f10x_rtc.c,這3個(gè)文件均位于..\Libraries\STM32F10x_StdPeriph_Driver\src目錄下。15.6.2項(xiàng)目實(shí)施第三步:點(diǎn)擊“File/New”新建兩個(gè)文件,將其改名為RTC.C和RTC.H并保存到工程模板下的APP文件夾中。并將RTC.C文件添加到APP項(xiàng)目組下。15.6帶溫度顯示的電子萬年歷項(xiàng)目實(shí)施第四步:在RTC.C文件中輸入如下源程序,在程序中首先包含RTC.H頭文件,并重新聲明本文件中需要引用的外部變量。然后創(chuàng)建3個(gè)函數(shù),分別為RTC_NVIC_Config()、rtc_init()和clockinit_RTC()。為實(shí)現(xiàn)電子萬年歷功能,編寫了3個(gè)日歷處理函數(shù),分別為RTC_GetCountValue()、RTC_GetDateTime()和RTC_GetWeek()。RTC_NVIC_Config()函數(shù)用于RTC秒中斷優(yōu)先級(jí)設(shè)置。rtc_init()函數(shù)用于RTC初始化,只在第一次設(shè)置RTC模塊時(shí)調(diào)用。clockinit_RTC()為復(fù)位初始化函數(shù),在main函數(shù)中調(diào)用。函數(shù)RTC_GetCountValue()將時(shí)間信息轉(zhuǎn)換為RTC計(jì)數(shù)值,一般用于時(shí)間設(shè)定。函數(shù)RTC_GetDateTime()將RTC計(jì)數(shù)值轉(zhuǎn)換為日歷,一般用于時(shí)間讀取。函數(shù)RTC_GetWeek由日期自動(dòng)計(jì)算出星期。RTC源程序,非放映時(shí)雙擊右側(cè)圖標(biāo)可打開15.6帶溫度顯示的電子萬年歷項(xiàng)目實(shí)施第五步:在RTC.H文件中輸入如下源程序,其中條件編譯格式不變,只要更改一下預(yù)定義變量名稱即可,需要將剛定義函數(shù)的聲明加到頭文件當(dāng)中。參考代碼如下:#ifndef_RTC_H#define_RTC_H#include"stm32f10x.h"voidrtc_init(void);voidclockinit_RTC(void);voidRTC_GetDateTime(void);u8RTC_GetWeek(u16year,u8month,u8day);u32RTC_GetCountValue(u16year,u8month,u8day,u8hour,u8minute,u8second);#endif15.6帶溫度顯示的電子萬年歷項(xiàng)目實(shí)施第六步:新建兩個(gè)文件,將其改名為ds18b20.c和ds18b20.h并保存到工程模板下的APP文件夾中。將ds18b20.c文件添加到APP項(xiàng)目組下。在ds18b20.c文件中輸入DS18B20驅(qū)動(dòng)源程序,包括端口初始化、輸入配置、輸出配置、DS18B20初始化、字節(jié)寫入、字節(jié)讀取和讀溫度函數(shù),相關(guān)代碼在上一節(jié)均有詳細(xì)講解,在此就不將代碼再次貼出。在ds18b20.h文件中輸入如下源程序,其中條件編譯格式不變,需要將引腳宏定義和驅(qū)動(dòng)函數(shù)聲明添加到頭文件當(dāng)中。參考代碼如下:#ifndef_DS18B20_H#define_DS18B20_H#include"stm32f10x.h"#include"systick.h"/*引腳宏義*/#definedq(GPIO_Pin_4)//PE4#defineGPIO_ds18b20GPIOE#defineds18b20_dq_HGPIO_SetBits(GPIO_ds18b20,dq)#defineds18b20_dq_LGPIO_ResetBits(GPIO_ds18b20,dq)/*DS18B20驅(qū)動(dòng)函數(shù)聲明*/voidds18b20_init(void);voidDQOUTINT(void);voidDQININT(void);voidds18b20init(void);voidds18b20wr(u8dat);u8DS18b20rd(void);doublereadtemp(void);voidds18b20_start_convert(void);doubleds18b20_read_operate(void);#endif15.6帶溫度顯示的電子萬年歷項(xiàng)目實(shí)施第七步:在main.h文件的中間部分添加#include"RTC.H"和#include"ds18b20.h"語句,即包含RTC.H和ds18b20.h頭文件,為精簡(jiǎn)工程以及提高編譯速度,本項(xiàng)目移除了部分沒有使用的項(xiàng)目文件,相應(yīng)頭文件包含語句一并刪除。參考代碼如下:#ifndef_MAIN_H#define_MAIN_H#include"stm32f10x.h"#include"dsgshow.h"#include"OLED.H"#include"USART.H“#include"EXTI.H"#include"ds18b20.h"#include"RTC.H"#include"stdio.h"#include"string.h"#endif15.6帶溫度顯示的電子萬年歷項(xiàng)目實(shí)施第八步:在main.c文件中輸入如下源程序,在main函數(shù)中,首先定義變量并賦初值,然后分別對(duì)所有用到的外設(shè)進(jìn)行初始化,最后進(jìn)入日期更新、溫度讀取和數(shù)碼管動(dòng)態(tài)顯示的無限循環(huán)結(jié)構(gòu)當(dāng)中,并等待中斷發(fā)生。參考代碼如下:#include"main.h"u16year=2024;u8TempStr[17]={0},DateFresh=1;u8month=10,day=31,week=4,hour=9,minute=30,second=25;char*name[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};intmain(){u8Start=0;doublevalue=20.0; //溫度值clockinit_RTC(); //時(shí)鐘初始化Usart1_Init(); //串口初始化ds18b20_init(); //DS18B20初始化EXTIInti(); //外部中斷初始化DsgShowInit(); //數(shù)碼管顯示初始化GPIO_Write(GPIOE,0xFFFF); //關(guān)所有數(shù)碼管OLED_Init(); //OLED初始化OLED_Clear(); //OLED清屏value=readtemp(); //開機(jī)進(jìn)行一次溫度檢測(cè)OLED_ShowCHinese(12+8*0,6,0); /*"溫",0*/OLED_ShowCHinese(12+8*2,6,1); /*"度",1*/OLED_ShowCHinese(12+8*11,6,2); /*"℃",2*/if(value>0)sprintf((char*)TempStr,"+%05.2f",value);elsesprintf((char*)TempStr,"-%05.2f",value);注意:需要修改OLEDFont.h中的字模”蘇州大學(xué)”為“溫度℃”。OLED_ShowString(12+8*5,6,TempStr)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論