STM32學(xué)習(xí)手記(5):數(shù)據(jù)的保存與毀滅!(一)
從51開始,單片機(jī)玩了很長(zhǎng)時(shí)間了,有51,PIC,AVR等等,早就想跟潮流玩玩ARM,但一直沒有開始,原因-----不知道玩了ARM可以做什么(對(duì)我自己而言)。如果為學(xué)習(xí)而學(xué)習(xí),肯定學(xué)不好。然后cortex-m3出來了,據(jù)說,這東西可以替代單片機(jī),于是馬上開始關(guān)注。也在第一時(shí)間開始學(xué)習(xí),可惜一開始就有點(diǎn)站錯(cuò)了隊(duì),選錯(cuò)了型(仍是對(duì)我自己而言)。我希望這種芯片應(yīng)該是滿大街都是,隨便哪里都可以買得到,但我選的第一種顯然做不到。為此,大概浪費(fèi)了一年多時(shí)間吧,現(xiàn)在,回到對(duì)我來說是正確的道路上來啦,邊學(xué)邊寫點(diǎn)東西?! ?/p>本文引用地址:http://butianyuan.cn/article/170608.htm 一、認(rèn)識(shí)ADC兼進(jìn)一步看懂STM的庫 ADC是多少位的? 12位 ADC有多少個(gè)? 1個(gè)、2個(gè)或多至3個(gè),視不同的器件而不同;每個(gè)又有多個(gè)通道。 關(guān)于通道的名堂: 10.3.3 通道選擇 有16個(gè)多路通道??梢园艳D(zhuǎn)換分成兩組:規(guī)則的和注入的。在任意多個(gè)通道上以任意順序進(jìn)行的一系列轉(zhuǎn)換構(gòu)成成組轉(zhuǎn)換。例如,可以如下順序完成轉(zhuǎn)換:通道3、通道8、通道2、通道2、通道0、通道2、通道2、通道15。 ● 規(guī)則組由多達(dá)16個(gè)轉(zhuǎn)換組成。規(guī)則通道和它們的轉(zhuǎn)換順序在ADC_SQRx寄存器中選擇。規(guī)則組中轉(zhuǎn)換的總數(shù)寫入ADC_SQR1寄存器的L[3:0]位中。 ● 注入組由多達(dá)4個(gè)轉(zhuǎn)換組成。注入通道和它們的轉(zhuǎn)換順序在ADC_JSQR寄存器中選擇。注入組里的轉(zhuǎn)換總數(shù)目必須寫入ADC_JSQR寄存器的L[1:0]位中。 它們有什么區(qū)別: l 不同的組轉(zhuǎn)換后保存數(shù)據(jù)的地方不一樣,產(chǎn)生的中斷標(biāo)志不一樣。 l 在掃描模式下,規(guī)則組會(huì)有能力把各通道數(shù)據(jù)通過DMA傳給SRAM,而注入組的數(shù)據(jù)總是存在在ADC_JDRx中。 還有其他的一些區(qū)別,這里暫不一一羅列。 ST為什么這么樣來設(shè)計(jì)AD轉(zhuǎn)換,肯定是有理由的,但是我不知道,因此,我也就難以深入地理解AD轉(zhuǎn)換的各種模式。這也就是說,對(duì)于知識(shí)的理解,要把它放在其應(yīng)用背景中去學(xué)習(xí)才能學(xué)得好。因此,其他知識(shí)積累得越多,學(xué)起來也就越快,這也就是所謂的“功底”問題。某人功底深厚,意味著他見多識(shí)廣,遇到的事情多,能夠很快找到處理某件事情的“原型”。當(dāng)然,也有一些人抽象學(xué)習(xí)能力極強(qiáng),就算找不到“原型”,他也能學(xué)得很好?;旧?,這類人的科學(xué)素養(yǎng)更高一些,在工程師、工科類學(xué)生中并不多見。 閑話少說,下面來看怎么樣來使用AD轉(zhuǎn)換器? 以一段源程序?yàn)槔謩e來解讀,同時(shí)進(jìn)一步理解STM32中有關(guān)符號(hào)的含義,相信以后再讀庫源程序,定能更上一層樓。 為看得清楚一些,以下代碼用一種顏色表示。 /* ADC1 開始準(zhǔn)備配置*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /*設(shè)置ADC-》CR1的19:16,確定ADC工作模式,一共有10種工作模式 #define ADC_Mode_Independent ((uint32_t)0x00000000) 0000:獨(dú)立模式 #define ADC_Mode_RegInjecSimult ((uint32_t)0x00010000) 0001:混合的同步規(guī)則+注入同步模式 #define ADC_Mode_RegSimult_AlterTrig ((uint32_t)0x00020000) 0010:混合的同步規(guī)則+交替觸發(fā)模式 #define ADC_Mode_InjecSimult_FastInterl ((uint32_t)0x00030000) 0011:混合同步注入+快速交替模式 #define ADC_Mode_InjecSimult_SlowInterl ((uint32_t)0x00040000) 0100:混合同步注入+慢速交替模式 #define ADC_Mode_InjecSimult ((uint32_t)0x00050000) 0101:注入同步模式 #define ADC_Mode_RegSimult ((uint32_t)0x00060000) 0110:規(guī)則同步模式 #define ADC_Mode_FastInterl ((uint32_t)0x00070000) 0111:快速交替模式 #define ADC_Mode_SlowInterl ((uint32_t)0x00080000) 1000:慢速交替模式 #define ADC_Mode_AlterTrig ((uint32_t)0x00090000) 1001:交替觸發(fā)模式 */ ADC_InitStructure.ADC_ScanConvMode = ENABLE; /* ADC_ScanConvMode在stm32f10x_adc.h中定義如下: FunctionalState ADC_ScanConvMode; 這個(gè)參數(shù)用來指定轉(zhuǎn)換是掃描(多通道模式)還是單個(gè)轉(zhuǎn)換(單通道模式),該參數(shù)可以被設(shè)置為DISABLE或者ENABLE。 在數(shù)據(jù)手冊(cè)中,SCAN位是這樣描述的:掃描模式 該位由軟件設(shè)置和清除,用于開啟或關(guān)閉掃描模式。在掃描模式中,由ADC_SQRx或ADC_JSQRx寄存器選中的通道被轉(zhuǎn)換。 0:關(guān)閉掃描模式 1:使用掃描模式 注:如果分別設(shè)置了EOCIE或JEOCIE位,只在最后一個(gè)通道轉(zhuǎn)換完畢才會(huì)產(chǎn)生EOC或JEOC中斷。 這樣,如果一次需要對(duì)多個(gè)通道進(jìn)行轉(zhuǎn)換,這位就必須設(shè)置為ENABLE。 */ ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; /* FunctionalState ADC_ContinuousConvMode; 這個(gè)參數(shù)用來指定轉(zhuǎn)換是連續(xù)進(jìn)行還是單次進(jìn)行,它可以設(shè)置為ENABLE或者DISABLE。 這兩個(gè)參數(shù)中出現(xiàn)了FunctionalState數(shù)據(jù)類型,那么它是什么呢,順滕摸瓜,可以看到它的的定義如下: typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; 因此,它相當(dāng)于是一個(gè)位變量,我的理解,DISPABLE=0這個(gè)沒有問題,ENABLE=!DISABLE是否應(yīng)該確切的是1??否則下面的設(shè)置就會(huì)有問題。 用這兩個(gè)符號(hào)來對(duì)寄存器中的位進(jìn)行設(shè)置的話,還需要提供位置信息,如下面的代碼所示: tmpreg1 |= (uint32_t)(ADC_InitStruct-》ADC_DataAlign | ADC_InitStruct-》ADC_ExternalTrigConv | ?。ǎ╱int32_t)ADC_InitStruct-》ADC_ContinuousConvMode 《《 1)); 這個(gè)《《1就是位置信息,CONT是CON2寄存器的位1 這樣,我們看STM32的庫又能多看懂一點(diǎn)了。 用于設(shè)定CON2的CONT位(位1):是否連續(xù)轉(zhuǎn)換 該位由軟件設(shè)置和清除。如果設(shè)置了此位,則轉(zhuǎn)換將連續(xù)進(jìn)行直到該位被清除。 0:?jiǎn)未无D(zhuǎn)換模式 1:連續(xù)轉(zhuǎn)換模式 */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /* uint32_t ADC_ExternalTrigConv; 定義如何來觸發(fā)AD轉(zhuǎn)換,一共有8個(gè)可選項(xiàng),以下給出兩個(gè)來解釋一下: #define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x00040000) 將0x00040000寫成二進(jìn)制,就是: 0000 0000 0000 0100 0000 0000 0000 0000 對(duì)照下面的說明,不難看出,第19:17位是 010,即定時(shí)器1的CC3事件觸發(fā)。 #define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000) 將0x000E0000寫成二進(jìn)制,就是: 0000 0000 0000 1110 0000 0000 0000 0000 對(duì)照下面的說明,是SWSTART方式,即用軟件標(biāo)志來啟動(dòng)轉(zhuǎn)換。 關(guān)于EXTSEL[2:0]的說明: 位19:17 EXTSEL[2:0]:選擇啟動(dòng)規(guī)則通道組轉(zhuǎn)換的外部事件 這些位選擇用于啟動(dòng)規(guī)則通道組轉(zhuǎn)換的外部事件 ADC1和ADC2的觸發(fā)配置如下 000:定時(shí)器1的CC1事件 100:定時(shí)器3的TRGO事件 001:定時(shí)器1的CC2事件 101:定時(shí)器4的CC4事件 010:定時(shí)器1的CC3事件 110:EXTI線11/ TIM8_TRGO, 僅大容量產(chǎn)品具有TIM8_TRGO功能 011:定時(shí)器2的CC2事件 111:SWSTART ADC3的觸發(fā)配置如下 000:定時(shí)器3的CC1事件 100:定時(shí)器8的TRGO事件 001:定時(shí)器2的CC3事件 101:定時(shí)器5的CC1事件 010:定時(shí)器1的CC3事件 110:定時(shí)器5的CC3事件 011:定時(shí)器8的CC1事件 111:SWSTART */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* 這個(gè)是用來設(shè)定數(shù)據(jù)對(duì)齊模式的,有兩種可能: #define ADC_DataAlign_Right ((uint32_t)0x00000000) #define ADC_DataAlign_Left ((uint32_t)0x00000800) 找到數(shù)據(jù)手冊(cè)上的相關(guān)說明: 位11:ALIGN:數(shù)據(jù)對(duì)齊 該位由軟件設(shè)置和清除。 0:右對(duì)齊 1:左對(duì)齊 */ ADC_InitStructure.ADC_NbrOfChannel = 1; /* ADC_NbrOfChannel的定義如下: uint8_t ADC_NbrOfChannel; 指定有多少個(gè)通道會(huì)被轉(zhuǎn)換,它的值可以是1~16,這個(gè)數(shù)據(jù)將會(huì)影響到寄存器ADC_SQR1,下面是stm32f10x_adc.c中的相關(guān)代碼: 。。.。。. tmpreg2 |= (uint8_t) (ADC_InitStruct-》ADC_NbrOfChannel - (uint8_t)1); tmpreg1 |= (uint32_t)tmpreg2 《《 20; ADCx-》SQR1 = tmpreg1; 看到mpreg1 |= (uint32_t)tmpreg2 《《 20;中的:20,用上面我們剛理解到的原則,這個(gè)值的低位將在ADC_SQR1的20位,而它的值是1~16,從代碼中可以看到這里又減去1,則其設(shè)置值為:0~15,即4bit就夠了,那么從20往前數(shù),也就是[23:20],那么SQR1中這幾位的用途是什么呢?順這條線索我們?nèi)フ襍QR1中的23:20位,看它是怎么用的。 位23:20 L[3:0]:規(guī)則通道序列長(zhǎng)度 這些位定義了在規(guī)則通道轉(zhuǎn) 0000:1個(gè)轉(zhuǎn)換 0001:2個(gè)轉(zhuǎn)換 …… 1111:16個(gè)轉(zhuǎn)換 也就是設(shè)置一次進(jìn)行幾個(gè)通道的轉(zhuǎn)換,看來我們的理解完全正確。 */ ADC_Init(ADC1, ADC_InitStructure); //通過前面一系列的設(shè)置,可以執(zhí)行ADC_Init函數(shù)了。 /* ADC1 規(guī)則通道15(Channel15)配置(規(guī)則通道見文章開頭)*/ ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_55Cycles5); /* 這個(gè)函數(shù)一共有4個(gè)參數(shù),第一個(gè)是指定轉(zhuǎn)換器,根據(jù)所采用的器件的不同,可以是ADC1,ADC2,ADC3;第二個(gè)參數(shù)是指定通道號(hào);第三個(gè)參數(shù)是指定該通道在轉(zhuǎn)換序列中第幾個(gè)開始轉(zhuǎn)換,第四個(gè)參數(shù)是指定轉(zhuǎn)換時(shí)間 第一、二個(gè)參數(shù)不難理解,這里就不再多說了,看一看第三個(gè)參數(shù)。 先看一看這個(gè)函數(shù)的內(nèi)容,它在stm32f10x_adc.c中,這是STM庫提供的一個(gè)函數(shù): void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) { 。。.。。.前面的不寫了 /* For Rank 1 to 6 */ if (Rank 《 7) //這個(gè)Rand就是第三個(gè)參數(shù) { /* Get the old register value */ tmpreg1 = ADCx-》SQR3; /* Calculate the mask to clear */ tmpreg2 = SQR3_SQ_Set 《《 (5 * (Rank - 1)); SQR3的值如下: //#define SQR3_SQ_Set ((uint32_t)0x0000001F) 之所以用5去乘,看下圖中的表格:ADC_SQ3中SQ1~SQ6每個(gè)都是占5位。 這下理解了:如果這個(gè)Rank是1,那么tmpreg2這個(gè)變量第[4:0]這5位將會(huì)是11111(即SQR3_SQ_Set的初始值:0x0000001f),如果Rank是2,那么tmpreg2這個(gè)變量的第[9:5]將會(huì)是11111,即tmpreg2將等于:0x00001f00,依此類推。 /* Clear the old SQx bits for the selected rank */ tmpreg1 = ~tmpreg2; /* tmpreg2取反再與,即清掉tmpreg1中相應(yīng)的5位*/ tmpreg2 = (uint32_t)ADC_Channel 《《 (5 * (Rank - 1)); /*這次tmpreg2取的是通道值了,然后同相根據(jù)Rank的值左移5、10或更多位 */ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx-》SQR3 = tmpreg1; } */ 第四個(gè)參數(shù)是采樣時(shí)間設(shè)定,代碼如下: tmpreg2 = (uint32_t)ADC_SampleTime 《《 (3 * ADC_Channel); /* 設(shè)定新的采樣時(shí)間,這里為什么用3,理由和上面的5一樣,看下圖。*/ tmpreg1 |= tmpreg2; /* Store the new register value */ ADCx-》SMPR2 = tmpreg1; /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); 至此一次ADC轉(zhuǎn)換配置完畢。很麻煩。。.。。.也許功能強(qiáng)大的副產(chǎn)品就是麻煩吧,沒有辦法。 二、使用內(nèi)置溫度傳感器測(cè)量溫度 學(xué)習(xí)使用ADC多通道轉(zhuǎn)換方式,驗(yàn)證溫度測(cè)量的準(zhǔn)確性,為以后的工程實(shí)踐打好基礎(chǔ)。 ?。?) ADC的單次與連續(xù)轉(zhuǎn)換 ADC轉(zhuǎn)換可以在一次轉(zhuǎn)換后停止,然后再次觸發(fā)后進(jìn)行下一次轉(zhuǎn)換;也可以是持續(xù)不斷地轉(zhuǎn)換下去。這個(gè)是通過設(shè)定ADC_CR2的CONT位來確定。 而在ST提供的庫里面,是這樣來設(shè)定的: ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; (2) ADC的掃描模式 ADC的掃描模式是用來掃描一組選定的通道的,它們將會(huì)被依次轉(zhuǎn)換。這個(gè)在上一份筆記中已說明過。 那么連續(xù)轉(zhuǎn)換和掃描轉(zhuǎn)換之間又是什么關(guān)系呢?字面上理解,似乎它們都是持續(xù)不斷地轉(zhuǎn)換啊。 答案是:連續(xù)轉(zhuǎn)換的層次比掃描更高,它管著掃描呢。也就是說,對(duì)連續(xù)轉(zhuǎn)換來說,它所謂的“一次轉(zhuǎn)換”可并不是指的一個(gè)通道的轉(zhuǎn)換結(jié)束,而是指的“一組”轉(zhuǎn)換結(jié)束,當(dāng)然,這個(gè)“一組”有可能只有一個(gè)通道而已。再說得明確一些:當(dāng)ADC掃描一次結(jié)束以后,如果CONT位是“1”(設(shè)定為連續(xù)轉(zhuǎn)換方式),那么將繼續(xù)下一輪的轉(zhuǎn)換。 ?。?) EOC什么時(shí)候產(chǎn)生? 我的理解應(yīng)該是每個(gè)通道(Channel)轉(zhuǎn)換結(jié)束時(shí)都會(huì)發(fā)生。但這里有些問題(見下圖): 上面的說明中:該位由硬件在(規(guī)則或注入)通道組換結(jié)束時(shí)設(shè)置…其中有個(gè)“組”字,字面的理解似乎應(yīng)該是指一次轉(zhuǎn)換組的所有通道都結(jié)束后才置1?但如果是這樣,那么又如何進(jìn)行數(shù)據(jù)的傳遞呢?要知道,對(duì)于ADC1來說,它的多個(gè)通道只有一個(gè)用于數(shù)據(jù)何存的寄存器:ADC1-》DR啊。 而這個(gè)問題在其他兩個(gè)地方也沒有說得清楚(見下圖): 我們前面討論了說連續(xù)轉(zhuǎn)換是針對(duì)一組轉(zhuǎn)換而言的,所以這里所謂的:每個(gè)轉(zhuǎn)換后EOC標(biāo)志被設(shè)置,究竟是一組轉(zhuǎn)換結(jié)束后呢還是一個(gè)通道結(jié)束后呢?不明確。 而在掃描模式是這么說的(見下圖): 這里僅說到:如果設(shè)置了DMA位,在每次EOC后…,而并沒有說到什么時(shí)候會(huì)有EOC產(chǎn)生?是所有掃描結(jié)束還是每個(gè)通道轉(zhuǎn)換結(jié)束? 而關(guān)于SCAN位又有這樣的說明(見下圖): 注意最后的注:如果分別設(shè)置了EOCIE或JEOCIE位,只在最后一個(gè)通道轉(zhuǎn)換完畢才會(huì)產(chǎn)生EOC或者JEOC中斷。 對(duì)這一行話的理解同樣會(huì)有歧義:究竟是只在最后一個(gè)通道轉(zhuǎn)換完畢才產(chǎn)生EOC或者JEOC呢,還是每個(gè)通道轉(zhuǎn)換時(shí)都產(chǎn)生EOC或者JEOC,但是僅在最后一個(gè)通道轉(zhuǎn)換完畢時(shí)的EOC/JEOC才會(huì)引發(fā)中斷? 手冊(cè)上說得清楚,手冊(cè)不保證正確,有問題可以找英文原版……可憐我,如果漢語語法也搞不清楚,那么英語語法豈非更頭大?看來非得進(jìn)修個(gè)英文六級(jí)再來學(xué)啦。 還好,我們還能做實(shí)驗(yàn)驗(yàn)證。經(jīng)驗(yàn)證,我認(rèn)為應(yīng)該是每次通道轉(zhuǎn)換時(shí)都有EOC產(chǎn)生,并且這個(gè)EOC可以觸發(fā)DMA事件。但是畢意自己驗(yàn)證的不能保證一定理解正確,所以嘍嘍寫了這么多。 (4)為了要使用內(nèi)置的溫度傳感器,得要先打開溫度傳感器(同時(shí)也打開了內(nèi)部REF測(cè)量通道),數(shù)據(jù)手冊(cè)上說是設(shè)置ADC-》CR2中的TSRVEFF位。這個(gè)位當(dāng)然可以寫個(gè)代碼自行設(shè)置,不過我們現(xiàn)在是用庫編程,那就遵守紀(jì)律,找到相應(yīng)的庫函數(shù)吧。 打開stm32f10x_adc.c,用盡一切手段找,在這里(見下圖): 根據(jù)上次的解讀,我們已知FunctionalState相當(dāng)于是一個(gè)“位”變量,它只能取Enable和Disable兩個(gè)值之一。 所以,main.c中加入這樣一行: ADC_TempSensorVrefintCmd(ENABLE); //開啟溫度傳感器及Vref通道 ?。?)選定待轉(zhuǎn)換組中的通道,并設(shè)定轉(zhuǎn)換順序,轉(zhuǎn)換時(shí)間 ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5); /* 設(shè)置ADC1的Channel15通道在轉(zhuǎn)換序列中第 2 個(gè)進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換時(shí)間設(shè)定為239.5個(gè)周期 */ 這一段中的第一個(gè)參數(shù)是指定由ADC1轉(zhuǎn)換器轉(zhuǎn)換,因?yàn)闇囟葌鞲衅鹘釉谶@個(gè)轉(zhuǎn)換器的第16通道上,第二個(gè)參數(shù)顯然就是選定第16通道了,而第三個(gè)參數(shù)2是說這個(gè)通道第二個(gè)轉(zhuǎn)換;第四個(gè)參數(shù)是設(shè)定采樣時(shí)間。 說到采樣時(shí)間,又要多說幾句了。 ADC1轉(zhuǎn)換器的時(shí)鐘是ADCCLK,這個(gè)時(shí)鐘是由APB2時(shí)鐘經(jīng)過分頻器而得到的,由于代碼中沒有對(duì)預(yù)分頻器進(jìn)行設(shè)置,所以用默認(rèn)值2分頻,所以ADCCLK的時(shí)鐘是36M。 對(duì)于溫度傳感器的使用,數(shù)據(jù)手冊(cè)中這么樣寫(見下圖): 看第2條,即要求采樣時(shí)間大于2.2us,那么我們只能取最大的采樣周期239.5了。因?yàn)樵俚鸵粰n的就是71.5個(gè)周期,這是無法滿足要求的。 但是說到這里,又出來問題了,就在緊挨著這段話的上面有這么一段(見下圖): 也就是它要求采樣時(shí)間是17.1us,這這豈不是明顯不相符? 先標(biāo)志于此,稍后查資料或做實(shí)驗(yàn)來驗(yàn)證。 ?。?)設(shè)置DMA通道,將轉(zhuǎn)換得到的數(shù)據(jù)保存到SRAM中去。 vu16 ADCConvertedValue[2]; //定義一個(gè)2個(gè)字的數(shù)組,用來保存數(shù)據(jù) DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue[0]; //設(shè)定SRAM中的起始地址 DMA_InitStructure.DMA_BufferSize = 2; //2個(gè)字節(jié) DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //使用內(nèi)存地址自增模式 …… 其他的不多寫了。這樣,2個(gè)通道的測(cè)試數(shù)據(jù)分別被保存到ADCConvertedValue[0]和ADCConvertedValue[1]中去了,只要讀出這兩個(gè)單元中的值,就可以分別得到PC5(ADC_Channel15)上外接電位器的分壓值和內(nèi)部溫度傳感器的值了。 ?。?)第17通道Refint 在片內(nèi)有一個(gè)片內(nèi)基準(zhǔn),連接到ADC1的Channel17上,開始我以為,可以利用這個(gè)通道來做校準(zhǔn)工作,但是看一看數(shù)據(jù)手冊(cè),我知道沒戲了。 居然從1.16變到了1.24V。 而我實(shí)測(cè)的結(jié)果更令我嘆息,開空調(diào)吹一下板子,實(shí)測(cè)的數(shù)值是1470,其時(shí)溫度大概是在25度左右,空調(diào)一停,幾度的變化,結(jié)果變成了1475,再試,我拿著板子對(duì)著空調(diào)出風(fēng)口一陣吹,數(shù)值變到了1465.(其時(shí)溫度值為從1700變到1753)雖然基準(zhǔn)電壓值的變化遠(yuǎn)沒有溫度值變化大,可…。一個(gè)是基準(zhǔn),一個(gè)是傳感器啊??磥?,非得用外部基準(zhǔn)不可了。我的板子上VREF并沒有用基準(zhǔn)源,是通過一個(gè)簡(jiǎn)單的濾波電路接到VCC上的,這個(gè)基本上還算穩(wěn)定,說明那個(gè)低壓差穩(wěn)壓集成電路AMS1117的溫度特性還是不錯(cuò)的。 最后,報(bào)告一下測(cè)試結(jié)果 ?。?) 室溫下讀到的溫度傳感器的輸出為1700。 要將其轉(zhuǎn)換成溫度,還要找張表:(見下圖) 由于該表都是用電壓來表示的,所以要將1700轉(zhuǎn)換成電壓值。 (1686/4096)*3.3=1.3583 那么溫度就是: T=(1.43-1.3583)/4.3*1000)+25 =14.03+25 =39度 ?。?)拿電吹風(fēng)來,一陣吹,讀數(shù)變?yōu)?550 電壓值:(1550/4096)*3.3=1.2488V 再次計(jì)算: T=(1.42-1.2488)/4.3*1000+25 =42.1+25 =67.1度 (3)開空調(diào)吹,讀數(shù)變?yōu)?730,這個(gè)就不計(jì)算了,但是可以肯定數(shù)值變化趨勢(shì)是對(duì)的了。 從第一個(gè)39這個(gè)值來看,測(cè)溫的大體范圍是對(duì)的,因?yàn)槲以谑覂?nèi),估計(jì)當(dāng)時(shí)的溫度可能會(huì)有33~34度左右,這個(gè)39差了很多,原因:(1)V25和Avg_Slope都是取的中間值,這個(gè)未必對(duì);(2)測(cè)量值和電壓沒有精確對(duì)照測(cè)量,估計(jì)誤差也比較大。(3)是否與采樣時(shí)間有關(guān)系?這個(gè)還要驗(yàn)證。 因此,如果某個(gè)應(yīng)用中只是單獨(dú)測(cè)溫的話,這兩點(diǎn)都要注意,要在生產(chǎn)后有個(gè)修正的表格,否則誤差會(huì)比較大。
這里寫的是我的學(xué)習(xí)的過程,顯然,很多時(shí)候會(huì)是不全面的,不系統(tǒng)的,感悟式的,甚至有時(shí)會(huì)是錯(cuò)誤的,有些做法會(huì)是不專業(yè)的。那么,為什么我還要寫呢?這是一個(gè)有趣的問題,它甚至涉及到博客為什么要存在的問題。顯然,博客里面的寫的東西,其正確性、權(quán)威性大多沒法和書比,可為什么博客會(huì)存在呢?理由很多,我非專家,只說作為一個(gè)學(xué)習(xí)32位單片機(jī)的工程師角度來分享整個(gè)學(xué)習(xí)過程,整理成一個(gè)學(xué)習(xí)手記,也便于以后文檔備份。
本章節(jié)將學(xué)習(xí)
評(píng)論