<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > STM32學(xué)習手記(5):數據的保存與毀滅!(一)

STM32學(xué)習手記(5):數據的保存與毀滅!(一)

作者: 時(shí)間:2013-01-18 來(lái)源:網(wǎng)絡(luò ) 收藏

從51開(kāi)始,單片機玩了很長(cháng)時(shí)間了,有51,PIC,AVR等等,早就想跟潮流玩玩ARM,但一直沒(méi)有開(kāi)始,原因-----不知道玩了ARM可以做什么(對我自己而言)。如果為,肯定學(xué)不好。然后cortex-m3出來(lái)了,據說(shuō),這東西可以替代單片機,于是馬上開(kāi)始關(guān)注。也在第一時(shí)間開(kāi)始,可惜一開(kāi)始就有點(diǎn)站錯了隊,選錯了型(仍是對我自己而言)。我希望這種芯片應該是滿(mǎn)大街都是,隨便哪里都可以買(mǎi)得到,但我選的第一種顯然做不到。為此,大概浪費了一年多時(shí)間吧,現在,回到對我來(lái)說(shuō)是正確的道路上來(lái)啦,邊學(xué)邊寫(xiě)點(diǎn)東西?! ?/p>本文引用地址:http://dyxdggzs.com/article/170608.htm


  這里寫(xiě)的是我的學(xué)習的過(guò)程,顯然,很多時(shí)候會(huì )是不全面的,不系統的,感悟式的,甚至有時(shí)會(huì )是錯誤的,有些做法會(huì )是不專(zhuān)業(yè)的。那么,為什么我還要寫(xiě)呢?這是一個(gè)有趣的問(wèn)題,它甚至涉及到博客為什么要存在的問(wèn)題。顯然,博客里面的寫(xiě)的東西,其正確性、權威性大多沒(méi)法和書(shū)比,可為什么博客會(huì )存在呢?理由很多,我非專(zhuān)家,只說(shuō)作為一個(gè)學(xué)習32位單片機的工程師角度來(lái)分享整個(gè)學(xué)習過(guò)程,整理成一個(gè)學(xué)習,也便于以后文檔備份。
本章節將學(xué)習

  一、認識ADC兼進(jìn)一步看懂STM的庫

  ADC是多少位的?

  12位

  ADC有多少個(gè)?

  1個(gè)、2個(gè)或多至3個(gè),視不同的器件而不同;每個(gè)又有多個(gè)通道。

  關(guān)于通道的名堂:

  10.3.3 通道選擇

  有16個(gè)多路通道??梢园艳D換分成兩組:規則的和注入的。在任意多個(gè)通道上以任意順序進(jìn)行的一系列轉換構成成組轉換。例如,可以如下順序完成轉換:通道3、通道8、通道2、通道2、通道0、通道2、通道2、通道15。

  ● 規則組由多達16個(gè)轉換組成。規則通道和它們的轉換順序在A(yíng)DC_SQRx寄存器中選擇。規則組中轉換的總數寫(xiě)入ADC_SQR1寄存器的L[3:0]位中。

  ● 注入組由多達4個(gè)轉換組成。注入通道和它們的轉換順序在A(yíng)DC_JSQR寄存器中選擇。注入組里的轉換總數目必須寫(xiě)入ADC_JSQR寄存器的L[1:0]位中。

  它們有什么區別:

  l 不同的組轉換后的地方不一樣,產(chǎn)生的中斷標志不一樣。

  l 在掃描模式下,規則組會(huì )有能力把各通道通過(guò)DMA傳給SRAM,而注入組的總是存在在A(yíng)DC_JDRx中。

  還有其他的一些區別,這里暫不一一羅列。

  ST為什么這么樣來(lái)設計AD轉換,肯定是有理由的,但是我不知道,因此,我也就難以深入地理解AD轉換的各種模式。這也就是說(shuō),對于知識的理解,要把它放在其應用背景中去學(xué)習才能學(xué)得好。因此,其他知識積累得越多,學(xué)起來(lái)也就越快,這也就是所謂的“功底”問(wèn)題。某人功底深厚,意味著(zhù)他見(jiàn)多識廣,遇到的事情多,能夠很快找到處理某件事情的“原型”。當然,也有一些人抽象學(xué)習能力極強,就算找不到“原型”,他也能學(xué)得很好?;旧?,這類(lèi)人的科學(xué)素養更高一些,在工程師、工科類(lèi)學(xué)生中并不多見(jiàn)。

  閑話(huà)少說(shuō),下面來(lái)看怎么樣來(lái)使用AD轉換器?

  以一段源程序為例分別來(lái)解讀,同時(shí)進(jìn)一步理解中有關(guān)符號的含義,相信以后再讀庫源程序,定能更上一層樓。

  為看得清楚一些,以下代碼用一種顏色表示。

  /* ADC1 開(kāi)始準備配置*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  /*設置ADC-》CR1的19:16,確定ADC工作模式,一共有10種工作模式

  #define ADC_Mode_Independent ((uint32_t)0x00000000) 0000:獨立模式

  #define ADC_Mode_RegInjecSimult ((uint32_t)0x00010000) 0001:混合的同步規則+注入同步模式

  #define ADC_Mode_RegSimult_AlterTrig ((uint32_t)0x00020000) 0010:混合的同步規則+交替觸發(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:規則同步模式

  #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è)參數用來(lái)指定轉換是掃描(多通道模式)還是單個(gè)轉換(單通道模式),該參數可以被設置為DISABLE或者ENABLE。

  在數據手冊中,SCAN位是這樣描述的:掃描模式

  該位由軟件設置和清除,用于開(kāi)啟或關(guān)閉掃描模式。在掃描模式中,由ADC_SQRx或ADC_JSQRx寄存器選中的通道被轉換。

  0:關(guān)閉掃描模式

  1:使用掃描模式

  注:如果分別設置了EOCIE或JEOCIE位,只在最后一個(gè)通道轉換完畢才會(huì )產(chǎn)生EOC或JEOC中斷。

  這樣,如果一次需要對多個(gè)通道進(jìn)行轉換,這位就必須設置為ENABLE。

  */

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  /* FunctionalState ADC_ContinuousConvMode;

  這個(gè)參數用來(lái)指定轉換是連續進(jìn)行還是單次進(jìn)行,它可以設置為ENABLE或者DISABLE。

  這兩個(gè)參數中出現了FunctionalState數據類(lèi)型,那么它是什么呢,順滕摸瓜,可以看到它的的定義如下:

  typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;

  因此,它相當于是一個(gè)位變量,我的理解,DISPABLE=0這個(gè)沒(méi)有問(wèn)題,ENABLE=!DISABLE是否應該確切的是1??否則下面的設置就會(huì )有問(wèn)題。

  用這兩個(gè)符號來(lái)對寄存器中的位進(jìn)行設置的話(huà),還需要提供位置信息,如下面的代碼所示:

  tmpreg1 |= (uint32_t)(ADC_InitStruct-》ADC_DataAlign | ADC_InitStruct-》ADC_ExternalTrigConv |

 ?。ǎ╱int32_t)ADC_InitStruct-》ADC_ContinuousConvMode 《《 1));

  這個(gè)《《1就是位置信息,CONT是CON2寄存器的位1

  這樣,我們看的庫又能多看懂一點(diǎn)了。

  用于設定CON2的CONT位(位1):是否連續轉換

  該位由軟件設置和清除。如果設置了此位,則轉換將連續進(jìn)行直到該位被清除。

  0:?jiǎn)未无D換模式 1:連續轉換模式

  */

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  /* uint32_t ADC_ExternalTrigConv;

  定義如何來(lái)觸發(fā)AD轉換,一共有8個(gè)可選項,以下給出兩個(gè)來(lái)解釋一下:

  #define ADC_ExternalTrigConv_T1_CC3 ((uint32_t)0x00040000)

  將0x00040000寫(xiě)成二進(jìn)制,就是:

  0000 0000 0000 0100 0000 0000 0000 0000

  對照下面的說(shuō)明,不難看出,第19:17位是 010,即定時(shí)器1的CC3事件觸發(fā)。

  #define ADC_ExternalTrigConv_None ((uint32_t)0x000E0000)

  將0x000E0000寫(xiě)成二進(jìn)制,就是:

  0000 0000 0000 1110 0000 0000 0000 0000

  對照下面的說(shuō)明,是SWSTART方式,即用軟件標志來(lái)啟動(dòng)轉換。

關(guān)于EXTSEL[2:0]的說(shuō)明:

  位19:17 EXTSEL[2:0]:選擇啟動(dòng)規則通道組轉換的外部事件

  這些位選擇用于啟動(dòng)規則通道組轉換的外部事件

  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線(xiàn)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è)是用來(lái)設定數據對齊模式的,有兩種可能:

  #define ADC_DataAlign_Right ((uint32_t)0x00000000)

  #define ADC_DataAlign_Left ((uint32_t)0x00000800)

  找到數據手冊上的相關(guān)說(shuō)明:

  位11:ALIGN:數據對齊

  該位由軟件設置和清除。

  0:右對齊 1:左對齊

  */

  ADC_InitStructure.ADC_NbrOfChannel = 1;

  /* ADC_NbrOfChannel的定義如下:

  uint8_t ADC_NbrOfChannel;

  指定有多少個(gè)通道會(huì )被轉換,它的值可以是1~16,這個(gè)數據將會(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è)值的低位將在A(yíng)DC_SQR1的20位,而它的值是1~16,從代碼中可以看到這里又減去1,則其設置值為:0~15,即4bit就夠了,那么從20往前數,也就是[23:20],那么SQR1中這幾位的用途是什么呢?順這條線(xiàn)索我們去找SQR1中的23:20位,看它是怎么用的。

  位23:20 L[3:0]:規則通道序列長(cháng)度

  這些位定義了在規則通道轉

  0000:1個(gè)轉換

  0001:2個(gè)轉換

  ……

  1111:16個(gè)轉換

  也就是設置一次進(jìn)行幾個(gè)通道的轉換,看來(lái)我們的理解完全正確。

  */

  ADC_Init(ADC1, ADC_InitStructure);

  //通過(guò)前面一系列的設置,可以執行ADC_Init函數了。

  /* ADC1 規則通道15(Channel15)配置(規則通道見(jiàn)文章開(kāi)頭)*/

  ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_55Cycles5);

  /* 這個(gè)函數一共有4個(gè)參數,第一個(gè)是指定轉換器,根據所采用的器件的不同,可以是ADC1,ADC2,ADC3;第二個(gè)參數是指定通道號;第三個(gè)參數是指定該通道在轉換序列中第幾個(gè)開(kāi)始轉換,第四個(gè)參數是指定轉換時(shí)間

  第一、二個(gè)參數不難理解,這里就不再多說(shuō)了,看一看第三個(gè)參數。

  先看一看這個(gè)函數的內容,它在stm32f10x_adc.c中,這是STM庫提供的一個(gè)函數:

  void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)

  { 。。.。。.前面的不寫(xiě)了

  /* For Rank 1 to 6 */

  if (Rank 《 7) //這個(gè)Rand就是第三個(gè)參數

  {

  /* 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,依此類(lèi)推。

  /* Clear the old SQx bits for the selected rank */

  tmpreg1 = ~tmpreg2;

  /* tmpreg2取反再與,即清掉tmpreg1中相應的5位*/

  tmpreg2 = (uint32_t)ADC_Channel 《《 (5 * (Rank - 1));

  /*這次tmpreg2取的是通道值了,然后同相根據Rank的值左移5、10或更多位 */

  tmpreg1 |= tmpreg2;

  /* Store the new register value */

  ADCx-》SQR3 = tmpreg1;

  }

  */

  1.jpg

  第四個(gè)參數是采樣時(shí)間設定,代碼如下:

  tmpreg2 = (uint32_t)ADC_SampleTime 《《 (3 * ADC_Channel);

  /* 設定新的采樣時(shí)間,這里為什么用3,理由和上面的5一樣,看下圖。*/

  tmpreg1 |= tmpreg2;

  /* Store the new register value */

  ADCx-》SMPR2 = tmpreg1;

  2.jpg

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  至此一次ADC轉換配置完畢。很麻煩。。.。。.也許功能強大的副產(chǎn)品就是麻煩吧,沒(méi)有辦法。

二、使用內置溫度傳感器測量溫度

  學(xué)習使用ADC多通道轉換方式,驗證溫度測量的準確性,為以后的工程實(shí)踐打好基礎。

 ?。?) ADC的單次與連續轉換

  ADC轉換可以在一次轉換后停止,然后再次觸發(fā)后進(jìn)行下一次轉換;也可以是持續不斷地轉換下去。這個(gè)是通過(guò)設定ADC_CR2的CONT位來(lái)確定。

  而在ST提供的庫里面,是這樣來(lái)設定的:

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

 ?。?) ADC的掃描模式

  ADC的掃描模式是用來(lái)掃描一組選定的通道的,它們將會(huì )被依次轉換。這個(gè)在上一份筆記中已說(shuō)明過(guò)。

  那么連續轉換和掃描轉換之間又是什么關(guān)系呢?字面上理解,似乎它們都是持續不斷地轉換啊。

  答案是:連續轉換的層次比掃描更高,它管著(zhù)掃描呢。也就是說(shuō),對連續轉換來(lái)說(shuō),它所謂的“一次轉換”可并不是指的一個(gè)通道的轉換結束,而是指的“一組”轉換結束,當然,這個(gè)“一組”有可能只有一個(gè)通道而已。再說(shuō)得明確一些:當ADC掃描一次結束以后,如果CONT位是“1”(設定為連續轉換方式),那么將繼續下一輪的轉換。

 ?。?) EOC什么時(shí)候產(chǎn)生?

  我的理解應該是每個(gè)通道(Channel)轉換結束時(shí)都會(huì )發(fā)生。但這里有些問(wèn)題(見(jiàn)下圖):

  1.jpg

  上面的說(shuō)明中:該位由硬件在(規則或注入)通道組換結束時(shí)設置…其中有個(gè)“組”字,字面的理解似乎應該是指一次轉換組的所有通道都結束后才置1?但如果是這樣,那么又如何進(jìn)行數據的傳遞呢?要知道,對于A(yíng)DC1來(lái)說(shuō),它的多個(gè)通道只有一個(gè)用于數據何存的寄存器:ADC1-》DR啊。

  而這個(gè)問(wèn)題在其他兩個(gè)地方也沒(méi)有說(shuō)得清楚(見(jiàn)下圖):

  2.jpg

  我們前面討論了說(shuō)連續轉換是針對一組轉換而言的,所以這里所謂的:每個(gè)轉換后EOC標志被設置,究竟是一組轉換結束后呢還是一個(gè)通道結束后呢?不明確。

  而在掃描模式是這么說(shuō)的(見(jiàn)下圖):

  3.jpg

  這里僅說(shuō)到:如果設置了DMA位,在每次EOC后…,而并沒(méi)有說(shuō)到什么時(shí)候會(huì )有EOC產(chǎn)生?是所有掃描結束還是每個(gè)通道轉換結束?

  而關(guān)于SCAN位又有這樣的說(shuō)明(見(jiàn)下圖):

  4.jpg

  注意最后的注:如果分別設置了EOCIE或JEOCIE位,只在最后一個(gè)通道轉換完畢才會(huì )產(chǎn)生EOC或者JEOC中斷。

  對這一行話(huà)的理解同樣會(huì )有歧義:究竟是只在最后一個(gè)通道轉換完畢才產(chǎn)生EOC或者JEOC呢,還是每個(gè)通道轉換時(shí)都產(chǎn)生EOC或者JEOC,但是僅在最后一個(gè)通道轉換完畢時(shí)的EOC/JEOC才會(huì )引發(fā)中斷?

  手冊上說(shuō)得清楚,手冊不保證正確,有問(wèn)題可以找英文原版……可憐我,如果漢語(yǔ)語(yǔ)法也搞不清楚,那么英語(yǔ)語(yǔ)法豈非更頭大?看來(lái)非得進(jìn)修個(gè)英文六級再來(lái)學(xué)啦。

  還好,我們還能做實(shí)驗驗證。經(jīng)驗證,我認為應該是每次通道轉換時(shí)都有EOC產(chǎn)生,并且這個(gè)EOC可以觸發(fā)DMA事件。但是畢意自己驗證的不能保證一定理解正確,所以嘍嘍寫(xiě)了這么多。

 ?。?)為了要使用內置的溫度傳感器,得要先打開(kāi)溫度傳感器(同時(shí)也打開(kāi)了內部REF測量通道),數據手冊上說(shuō)是設置ADC-》CR2中的TSRVEFF位。這個(gè)位當然可以寫(xiě)個(gè)代碼自行設置,不過(guò)我們現在是用庫編程,那就遵守紀律,找到相應的庫函數吧。

  打開(kāi)stm32f10x_adc.c,用盡一切手段找,在這里(見(jiàn)下圖):

  5.jpg

  根據上次的解讀,我們已知FunctionalState相當于是一個(gè)“位”變量,它只能取Enable和Disable兩個(gè)值之一。

  所以,main.c中加入這樣一行:

  ADC_TempSensorVrefintCmd(ENABLE); //開(kāi)啟溫度傳感器及Vref通道

 ?。?)選定待轉換組中的通道,并設定轉換順序,轉換時(shí)間

  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);

  /* 設置ADC1的Channel15通道在轉換序列中第 2 個(gè)進(jìn)行轉換,轉換時(shí)間設定為239.5個(gè)周期

  */

  這一段中的第一個(gè)參數是指定由ADC1轉換器轉換,因為溫度傳感器接在這個(gè)轉換器的第16通道上,第二個(gè)參數顯然就是選定第16通道了,而第三個(gè)參數2是說(shuō)這個(gè)通道第二個(gè)轉換;第四個(gè)參數是設定采樣時(shí)間。

  說(shuō)到采樣時(shí)間,又要多說(shuō)幾句了。

  ADC1轉換器的時(shí)鐘是ADCCLK,這個(gè)時(shí)鐘是由APB2時(shí)鐘經(jīng)過(guò)分頻器而得到的,由于代碼中沒(méi)有對預分頻器進(jìn)行設置,所以用默認值2分頻,所以ADCCLK的時(shí)鐘是36M。

對于溫度傳感器的使用,數據手冊中這么樣寫(xiě)(見(jiàn)下圖):

  1.jpg

  看第2條,即要求采樣時(shí)間大于2.2us,那么我們只能取最大的采樣周期239.5了。因為再低一檔的就是71.5個(gè)周期,這是無(wú)法滿(mǎn)足要求的。

  但是說(shuō)到這里,又出來(lái)問(wèn)題了,就在緊挨著(zhù)這段話(huà)的上面有這么一段(見(jiàn)下圖):

  2.jpg

  也就是它要求采樣時(shí)間是17.1us,這這豈不是明顯不相符?

  先標志于此,稍后查資料或做實(shí)驗來(lái)驗證。

 ?。?)設置DMA通道,將轉換得到的數據到SRAM中去。

  vu16 ADCConvertedValue[2]; //定義一個(gè)2個(gè)字的數組,用來(lái)數據

  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue[0];

  //設定SRAM中的起始地址

  DMA_InitStructure.DMA_BufferSize = 2; //2個(gè)字節

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  //使用內存地址自增模式

  ……

  其他的不多寫(xiě)了。這樣,2個(gè)通道的測試數據分別被保存到ADCConvertedValue[0]和ADCConvertedValue[1]中去了,只要讀出這兩個(gè)單元中的值,就可以分別得到PC5(ADC_Channel15)上外接電位器的分壓值和內部溫度傳感器的值了。

 ?。?)第17通道Refint

  在片內有一個(gè)片內基準,連接到ADC1的Channel17上,開(kāi)始我以為,可以利用這個(gè)通道來(lái)做校準工作,但是看一看數據手冊,我知道沒(méi)戲了?!?/p>

  居然從1.16變到了1.24V。

  而我實(shí)測的結果更令我嘆息,開(kāi)空調吹一下板子,實(shí)測的數值是1470,其時(shí)溫度大概是在25度左右,空調一停,幾度的變化,結果變成了1475,再試,我拿著(zhù)板子對著(zhù)空調出風(fēng)口一陣吹,數值變到了1465.(其時(shí)溫度值為從1700變到1753)雖然基準電壓值的變化遠沒(méi)有溫度值變化大,可…。一個(gè)是基準,一個(gè)是傳感器啊??磥?lái),非得用外部基準不可了。我的板子上VREF并沒(méi)有用基準源,是通過(guò)一個(gè)簡(jiǎn)單的濾波電路接到VCC上的,這個(gè)基本上還算穩定,說(shuō)明那個(gè)低壓差穩壓集成電路AMS1117的溫度特性還是不錯的。

  最后,報告一下測試結果

 ?。?) 室溫下讀到的溫度傳感器的輸出為1700。

  要將其轉換成溫度,還要找張表:(見(jiàn)下圖)

  4.jpg

  由于該表都是用電壓來(lái)表示的,所以要將1700轉換成電壓值。

 ?。?686/4096)*3.3=1.3583

  那么溫度就是:

  T=(1.43-1.3583)/4.3*1000)+25

  =14.03+25

  =39度

 ?。?)拿電吹風(fēng)來(lái),一陣吹,讀數變?yōu)?550

  電壓值:(1550/4096)*3.3=1.2488V

  再次計算:

  T=(1.42-1.2488)/4.3*1000+25

  =42.1+25

  =67.1度

 ?。?)開(kāi)空調吹,讀數變?yōu)?730,這個(gè)就不計算了,但是可以肯定數值變化趨勢是對的了。

  從第一個(gè)39這個(gè)值來(lái)看,測溫的大體范圍是對的,因為我在室內,估計當時(shí)的溫度可能會(huì )有33~34度左右,這個(gè)39差了很多,原因:(1)V25和Avg_Slope都是取的中間值,這個(gè)未必對;(2)測量值和電壓沒(méi)有精確對照測量,估計誤差也比較大。(3)是否與采樣時(shí)間有關(guān)系?這個(gè)還要驗證。

  因此,如果某個(gè)應用中只是單獨測溫的話(huà),這兩點(diǎn)都要注意,要在生產(chǎn)后有個(gè)修正的表格,否則誤差會(huì )比較大。

分頻器相關(guān)文章:分頻器原理


評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>