久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 16740|回復: 5
打印 上一主題 下一主題
收起左側

STM8L的ADC之測量外部電壓(使用了DMA)

[復制鏈接]
跳轉到指定樓層
樓主
ID:140343 發表于 2016-10-9 23:58 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 51hei小林 于 2016-10-9 23:59 編輯

之前介紹ADC時,是用ADC測量內部1.225V的參考電壓,通過這個參考電壓的轉化值反推參考電壓的實際值.這里要注意,我說的內部參考電壓和參考電壓是兩個不同的概念,內部參考電壓就是內部的一個1.225V基準電壓,這個電壓比較準確,不會受外接干擾,其值也不會改變,一直是1.225V.在STM8L里,這個電壓作為一個獨立的通道,可以連接到ADC中,供ADC采樣,校準自己的參考電壓,也可以連接到STM8L的內部比較器的輸入端作為一個基準電壓,還可以通過引腳輸出這個電壓. 參考電壓,是Vref+和Vref-引腳之間的電壓,這個電壓是外部的,會隨著外部電壓的變化而變化,在ADC采樣時,這個電壓是采樣時的參考電壓. 上次的例程根據比例關系:

(參考電壓/4096)=(內部參考電壓/內部參考電壓轉換值)
已經求出了參考電壓的值為2.99V,好吧上次測的其實是2.98V,今天用萬用表量了下,是2.99V.為了這次程序的采集數據的準確,還是用2.99V.

本例程和上次的ADC測量內部參考電壓例程,并沒有太大卻別,只是增加了DMA部分.原以為,采樣內部通道和外部通道會有很大區別,實際上,只要選擇一下采樣的外部通道,同時關閉對應的施密特觸發器,其余程序和上次一樣就可以了.也不需要去設置引腳的輸入輸出狀態,保持默認就行.
使用DMA將ADC轉換后的數據傳輸到一個數組中,本例程采樣9次數據,傳輸完9次數據后會產生一個傳輸完成中斷,在中斷中求9次的和,計算平均值,同時計算采樣的電壓.
DMA的四個通道都可以作為ADC傳輸數據通道,我們需要使用SYSCFG_RMPCR1這個寄存器來設置具體使用的通道.本例程使用DMA的通道一來傳輸數據.

在本例程中,仍然使用IAR強大的查看變量功能,進行數據的顯示,沒有使用板子上的LCD液晶屏,主要原因是為了程序簡單,其實是因為我比較懶.本來對數據的處理應該進行濾波處理的,我也僅僅簡單的算了下9次采樣的平均值,起不到平滑數據的作用,ADC采樣的數據確實每次都不一樣,軟件濾波很重要.
在IAR查看變量,如果變量不是全局變量,在Live Watch窗口或Watch窗口中是看不到數據的,所以只好把這個變量聲明為局部靜態變量,同樣可以顯示出數值.
下圖是實際的硬件連接圖,用來一個電位器,三個腳分別連接到板子的VDD,GND,PD5腳,具體連接是:電位器兩邊的腳接VDD,GND,中間接PD5.


  1. /*硬件連接*/

  2. // PD5(ADC1_IN9) <----

  3. /****************************************************************************************

  4. *開發環境:IAR for stm8 v1.40.1

  5. *硬件平臺:STM8L-DISCOVERY

  6. *功能說明:測量ADC通道9的外部電壓,通道9對應的引腳為PD5,在此引腳接了一個電位器,用于輸出一個

  7. *        可變的電壓,提供給ADC測量

  8. *作    者:茗風

  9. ****************************************************************************************/

  10. #include"iostm8l152c6.h"

  11. #include"stdbool.h"

  12. #include"stdint.h"

  13. #define  ADC_DRH_ADRESS     0x5344

  14. uint16_t  ui16RX_buffer[9]={0};

  15. /******************************************************************************************************

  16. *  名    稱:void delay_10ms(uint8_t x_ms)

  17. *  功    能:延時10ms

  18. *  入口參數:無

  19. *  出口參數:無

  20. *  說    明:

  21. *  范    例:無

  22. ******************************************************************************************************/

  23. void delay_100ms(void)

  24. {

  25.   uint8_t i,j;

  26.   for(i=0;i<255;i++)//2*255個指令周期

  27.     for(j=0;j<255;j++);//2*255個指令周期

  28.   //delay_10ms共消耗 x_ms*2*255+2*x_ms個指令周期  

  29.   //255*2*255+2*255=130610us=130ms

  30.   //此延時函數,延時時間為130ms

  31.   //16M/8/2=1M 一個指令周期為1us

  32. }

  33. /******************************************************************************************************

  34. *  名    稱:void GPIO_Init(void)

  35. *  功    能:初始化PC7為高速推挽輸出

  36. *  入口參數:無

  37. *  出口參數:無

  38. *  說    明:

  39. *  范    例:無

  40. ******************************************************************************************************/

  41. void GPIO_Config(void)

  42. {

  43.    PC_CR1_C17  =1;//推挽輸出

  44.    PC_CR2_C27  =1;//高速輸出

  45.    PC_DDR_DDR7 =1;//PC7輸出

  46.    PC_ODR_ODR7 =0;//輸出低電平

  47. }

  48. /******************************************************************************************************

  49. *  名    稱:void ADC_Init(void)

  50. *  功    能:初始化ADC

  51. *  入口參數:無

  52. *  出口參數:無

  53. *  說    明:ADC1的測量通道為ADC1_IN9,單次轉換模式

  54. *  范    例:無

  55. ******************************************************************************************************/

  56. void ADC_Init(void)

  57. {   

  58.    CLK_PCKENR2_PCKEN20=1; //國際慣例,開啟ADC1外設時鐘


  59.    ADC1_CR1_ADON=1;  //wakes up the ADC from Power down mode.

  60.    ADC1_CR2_PRESC=1;//Select a sample time of 10 μs

  61. //   0: f(ADC_CLK) = CK

  62. //   1: f(ADC_CLK) = CK/2  //系統時鐘此時為默認的16M/8=2M,這里分頻后,fadc=2M/2=1M

  63.    

  64.    ADC1_SQR1_DMAOFF=0;    //使能DMA

  65.    

  66.    ADC1_CR3_SMTP2=0x06;//采樣時間為24 ADC clock cycles,也就是24*1us=24us

  67. //000: 4 ADC clock cycles

  68. //001: 9 ADC clock cycles

  69. //010: 16 ADC clock cycles

  70. //011: 24 ADC clock cycles

  71. //100: 48 ADC clock cycles

  72. //101: 96 ADC clock cycles

  73. //110: 192 ADC clock cycles

  74. //111: 384 ADC clock cycles

  75.    ADC1_SQR3_CHSEL_S9=1; //選擇通道9

  76.    ADC1_TRIGR3_TRIG9=1;  //關閉通道9的施密特觸發器

  77. //   ADC1_CR1_EOCIE=1;

  78. }

  79. /******************************************************************************************************

  80. *  名    稱:void DMA_Config(void)

  81. *  功    能:啟用DMA

  82. *  入口參數:無

  83. *  出口參數:無

  84. *  說    明:

  85. *  范    例:無

  86. ******************************************************************************************************/

  87. void DMA_Config(void)

  88. {

  89.   //------打開DAM時鐘------

  90.   CLK_PCKENR2_PCKEN24=1;

  91.   

  92.   //----設置ADC的DMA通道----

  93.   SYSCFG_RMPCR1_ADC1DMA_REMAP=1;

  94. /*  00: ADC1 DMA request/acknowledge mapped on DMA1 channel 0

  95.     01: ADC1 DMA request/acknowledge mapped on DMA1 channel 1

  96.     10: ADC1 DMA request/acknowledge mapped on DMA1 channel 2

  97.     11: ADC1 DMA request/acknowledge mapped on DMA1 channel 3 */

  98.   

  99.   //------設置傳送的字節數,------

  100.   DMA1_C1NDTR=9;  

  101.   

  102.   //------設置通道優先級------

  103.   DMA1_C1SPR_PL0=0;DMA1_C1SPR_PL1=1;


  104.   //------設置傳送方向------

  105.   DMA1_C1CR_DIR=0;  

  106. /*  0: Transfer from the peripheral to the memory.

  107.    1: Transfer from the memory to the peripheral.*/



  108.   //------設置模式------  

  109.   DMA1_C1CR_CIRC=1;

  110. /* Auto-reload mode

  111.    0: Circular mode disabled.

  112.    1: Circular mode enabled.   */


  113.   //------設置增還是減地址------   

  114.   DMA1_C1CR_MINCDEC=1;

  115. /*  0: Decrement mode.

  116.     1: Increment mode.*/


  117.   //------設置傳送數據位數------

  118.   DMA1_C1SPR_TSIZE=1;

  119. /*  0: 8-bit mode

  120.     1: 16-bit mode */

  121.   

  122.   // DMA1_C3CR_HTIE=1;

  123.     DMA1_C1CR_TCIE=1;//使能DMA傳輸完一組數據中斷

  124.    

  125.     //------設置DMA通道1外設地址------

  126.   DMA1_C1PARH=(uint8_t)((uint16_t)ADC_DRH_ADRESS >> (uint8_t)8);

  127.   DMA1_C1PARL=(uint8_t)ADC_DRH_ADRESS;

  128.    

  129.   //------設置DMA通道1內存地址------

  130.   DMA1_C1M0ARH=(uint8_t)((uint16_t)&ui16RX_buffer >> (uint8_t)8);

  131.   DMA1_C1M0ARL=(uint8_t)&ui16RX_buffer;

  132.   


  133.   

  134.   DMA1_C1CR_EN=1;

  135.   

  136.   DMA1_GCSR_GEN=1;

  137. }

  138. void main(void)

  139. {

  140.   GPIO_Config();

  141.   ADC_Init();

  142.   DMA_Config();

  143.   asm("rim");               //enable interrupts

  144.   while(1)

  145.   {

  146.     delay_100ms();

  147.     ADC1_CR1_START=1;

  148.   }

  149. }

  150. /******************************************************************************************************

  151. * 名    稱: DMA中斷

  152. * 功    能: DMA事件處理函數

  153. * 入口參數:無

  154. * 出口參數:無

  155. * 說   明:

  156. * 范   例:無

  157. ******************************************************************************************************/

  158. #pragma vector=DMA1_CH1_TC_vector

  159. __interrupt void DMA1_CH1_TC_ISR(void)

  160. {

  161.    static uint16_t tmp=0,voltage=0;//static是為了便于使用調試窗口查看變量值

  162.    uint8_t i=0;

  163.    tmp=0;

  164.    voltage=0;

  165.    if(DMA1_C1SPR_TCIF==1)

  166.    {

  167.      PC_ODR_ODR7 ^=0x01;//反轉藍燈電平,僅僅是為了指示ADC和DMA在工作,可去掉

  168.      DMA1_C1SPR_TCIF=0;//不軟件清除此中斷標志位,會導致無法退出此中斷

  169.      for(i=0;i<9;i++)tmp+=ui16RX_buffer[i];

  170.      tmp /=9;//求九次采樣平均值     

  171.      voltage=(uint32_t)299*tmp/4096;//計算最終輸出的電壓,結果擴大了100倍

  172.      //299是2.99V參考電壓,擴大了100倍

  173.      asm("nop");

  174.    }

  175. }

  176. /******************************************************************************************************

  177. * 名               稱: ADC中斷

  178. * 功         能: EOC事件處理函數

  179. * 入口           參數:無

  180. * 出口           參數:無

  181. * 說               明:

  182. * 范              例:無

  183. ******************************************************************************************************/

  184. //#pragma vector=COMP_EF2_vector

  185. //__interrupt void ADC1_ISR(void)

  186. //{

  187. //   static uint16_t tmp=0;

  188. //   if(ADC1_SR_EOC==1)

  189. //   {

  190. //     PC_ODR_ODR7 ^=0x01;

  191. //     ADC1_SR_EOC=0;

  192. //     tmp = ADC1_DRH;

  193. //     tmp = (tmp<<8)+ADC1_DRL;

  194. //     tmp=(uint32_t)299*tmp/4096;

  195. ////     VDD_Value=(uint32_t)1225*4096/temp;//得到的數值單位為mv

  196. //     asm("nop");

  197. //   }

  198. //}
復制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發
ID:281905 發表于 2018-2-3 11:35 | 只看該作者
請教一個問題:我用的STM8L151K4 查看配置資料和STM8L152C6大概一致,我用AIN0測熱敏電子電壓,發現DMA1_CH1_TC_vector中斷始終進不來,而你的另一份文檔測內部VDD電壓運行正常,請教問題可能是哪里。我用的是IAR for STM8,中斷向量表已經對過,沒問題
回復

使用道具 舉報

板凳
ID:281905 發表于 2018-2-3 11:37 | 只看該作者
請教STM8L151K4 使用DMA ,按照你的文檔COPY的,進不了中斷
回復

使用道具 舉報

地板
ID:281905 發表于 2018-2-6 14:56 | 只看該作者
謝謝!測量次數不夠沒進中斷,非常感謝分享
回復

使用道具 舉報

5#
ID:18591 發表于 2019-3-2 14:28 | 只看該作者
按照你的文檔COPY的,進不了中斷
你說,測量次數不夠沒進中斷,不懂你的意思
可以說清處一點?
回復

使用道具 舉報

6#
ID:646563 發表于 2019-11-21 15:34 | 只看該作者
你好!請問我copy你這個程序在IAR上為什么進入不了中斷?謝謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日操操| 日韩在线播放中文字幕 | 殴美成人在线视频 | 国产综合久久 | 欧美日韩在线一区 | 成人免费大片黄在线播放 | 亚洲精选一区 | 成人午夜免费视频 | 亚洲精品小视频在线观看 | 中文字幕在线一区二区三区 | 麻豆a级片| 久久久久久国产精品免费免费 | 久久久www成人免费精品 | 午夜视频精品 | 91精品国产色综合久久 | 日韩精品1区2区3区 爱爱综合网 | 九九热精品视频在线观看 | 亚洲天堂中文字幕 | 国产四虎 | 欧美久久久电影 | 中文字幕日韩欧美 | 一区二区三区四区免费在线观看 | 国产成人精品一区二区三区在线 | 欧美日韩久久精品 | 精品国产欧美一区二区三区成人 | 欧美精品一区二区三区在线 | 午夜影院污 | 高清av一区 | 国产一区中文字幕 | 成人午夜网站 | 色姑娘av| 久久亚洲天堂 | 精品国产免费人成在线观看 | 国产精品久久久久久久三级 | 久久久久久久久久性 | 亚洲一区毛片 | 日本免费黄色 | 夜夜骑首页 | 亚洲一区二区中文字幕 | 久久看精品 | 91精品国产综合久久久久久 |