
13.1實(shí)驗(yàn)內(nèi)容
本實(shí)驗(yàn)是通過ADC注入組采樣內(nèi)部溫度傳感器和參考電壓,通過本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:
- 內(nèi)部溫度傳感器和參考電壓簡(jiǎn)介
- ADC注入組采樣配合ADC中斷應(yīng)用
13.2實(shí)驗(yàn)原理
13.2.1內(nèi)部溫度傳感器和參考電壓簡(jiǎn)介
GD32F303有兩個(gè)內(nèi)部通道,分別為內(nèi)部溫度傳感器(ADC0_CH16)和內(nèi)部參考電壓Vrefint(ADC0_CH17)。
溫度傳感器可以用來測(cè)量器件周圍的溫度。溫度傳感器的輸出電壓隨溫度線性變化,由于生產(chǎn)過程的多樣化,溫度變化曲線的偏移在不同的芯片上會(huì)有不同(最多相差45°C)。內(nèi)部溫度傳感器更適合于檢測(cè)溫度的變化,而不是測(cè)量絕對(duì)溫度。如果需要測(cè)量精確的溫度,應(yīng)該使用一個(gè)外置的溫度傳感器來校準(zhǔn)這個(gè)偏移錯(cuò)誤。
從 ADC 數(shù)據(jù)寄存器中讀取并計(jì)算溫度傳感器數(shù)據(jù)Vtemperature, 并由下面公式計(jì)算出實(shí)際溫度:

V25:溫度傳感器在25°C下的電壓,從datasheet中可以查到典型值為1.45V。
Avg_Slope:溫度與溫度傳感器電壓曲線的均值斜率,從datasheet中可以查到典型值為4.1mV/℃。
內(nèi)部電壓參考(VREFINT)提供了一個(gè)穩(wěn)定的(帶隙基準(zhǔn))電壓輸出給ADC和比較器,典型值為1.2V。
13.3硬件設(shè)計(jì)
本實(shí)驗(yàn)使用兩個(gè)內(nèi)部ADC通道,無需要硬件設(shè)計(jì)。
13.4代碼解析
13.4.1中斷使能函數(shù)
在driver_adc.c中定義了開啟中斷的函數(shù)ADC_int_enable。
C /*ADC中斷使能函數(shù)*/ void ADC_int_enable(typdef_adc_ch_general *ADC) { /*規(guī)則組中斷使能*/ if(ADC->adc_channel_group == ADC_REGULAR_CHANNEL) { adc_interrupt_enable(ADC->adc_port,ADC_INT_EOC); adc_interrupt_flag_clear(ADC->adc_port,ADC_INT_EOC); } /*注入組中斷使能*/ else if(ADC->adc_channel_group == ADC_INSERTED_CHANNEL) { adc_interrupt_enable(ADC->adc_port,ADC_INT_EOIC); adc_interrupt_flag_clear(ADC->adc_port,ADC_INT_EOIC); } } |
13.4.2ADC中斷函數(shù)
在driver_adc.c中定義了ADC的中斷函數(shù)driver_adc_int_handler
C void driver_adc_int_handler(typdef_adc_ch_general *ADC,void *buffer) { uint8_t i; if(ADC->adc_channel_group == ADC_REGULAR_CHANNEL) { if(SET == adc_interrupt_flag_get(ADC->adc_port,ADC_INT_FLAG_EOC)) { adc_interrupt_flag_clear(ADC->adc_port,ADC_INT_FLAG_EOC); if(ADC->adc_mode == ADC_DAUL_REGULAL_PARALLEL) { REG32(buffer) = (uint32_t)(ADC_RDATA(ADC->adc_port)); } else { REG16(buffer) = (uint16_t)(ADC_RDATA(ADC->adc_port)); } } } else if(ADC->adc_channel_group == ADC_INSERTED_CHANNEL) { if(SET == adc_interrupt_flag_get(ADC->adc_port,ADC_INT_FLAG_EOIC)) { adc_interrupt_flag_clear(ADC->adc_port,ADC_INT_FLAG_EOIC); if(ADC->adc_mode == ADC_DAUL_INSERTED_PARALLEL) { for(i = 0; ich_count ; i++) { REG32(buffer) = REG32((ADC->adc_port) + 0x3C+(i*4)); buffer += 4; } } else { for(i = 0; ich_count ; i++) { REG16(buffer) = REG16((ADC->adc_port) + 0x3C+(i*4)); buffer += 2; } } } } } |
13.4.3內(nèi)部ADC通道結(jié)構(gòu)體定義
ADC的初始化在前兩章已經(jīng)講述過,這里就介紹下ADC和兩個(gè)通道的結(jié)構(gòu)體定義:
C typdef_adc_ch_general VRef_VTem_ADC = { .rcu_adc = RCU_ADC0,//ADC0的時(shí)鐘 .adc_psc = RCU_CKADC_CKAPB2_DIV6,//ADC0設(shè)置為APB2 6分頻 .adc_port = ADC0,//ADC口為ADC0 .adc_mode = ADC_MODE_FREE,//ADC模式為獨(dú)立模式 .adc_channel_group = ADC_INSERTED_CHANNEL,//使用注入組 .adc_scan_function = ENABLE,//開啟掃描模式 .adc_continuous_function = DISABLE,//關(guān)閉循環(huán)模式,因?yàn)槭褂玫氖亲⑷虢M,故該參數(shù)實(shí)際無效 .ch_count = 2,//轉(zhuǎn)換長(zhǎng)度為2 .trigger_source = ADC0_1_2_EXTTRIG_INSERTED_NONE, .DMA_mode = DISABLE//不使用DMA }; typdef_adc_ch_parameter VRef_VTem_ch_parameter[2] = { { .rcu_port = NULL, .port = NULL, .pin = NULL, .gpio_speed = NULL, .adc_channel = ADC_CHANNEL_16,//通道16 .sample_time = ADC_SAMPLETIME_55POINT5//設(shè)置采樣周期為55.5 } , { .rcu_port = NULL, .port = NULL, .pin = NULL, .gpio_speed = NULL, .adc_channel = ADC_CHANNEL_17,//通道17 .sample_time = ADC_SAMPLETIME_55POINT5,//設(shè)置采樣周期為55.5 } }; |
需要說明的是,由于使用的是內(nèi)部通道,無需配置外部IO口,所以rcu_port參數(shù)等無需設(shè)置,這里是為了方便讀者閱讀將這幾個(gè)參數(shù)設(shè)置為了NULL。
13.4.4內(nèi)部通道ADC配置
在bsp_adc.c中定義了內(nèi)部通道ADC配置的函數(shù)bsp_Vref_Vtemp_ADC_config
C void bsp_Vref_Vtemp_ADC_config() { /*ADC配置*/ driver_adc_config(&VRef_VTem_ADC,VRef_VTem_ch_parameter); /*ADC中斷打開*/ ADC_int_enable(&VRef_VTem_ADC); /*NVIC設(shè)置*/ nvic_irq_enable(ADC0_1_IRQn,0,0); } |
13.4.5中斷入口函數(shù)
在gd32f30x_interrupt.c中定義了中斷入口函數(shù):
C uint16_t Vref_Vtemp_data[2] ; void ADC0_1_IRQHandler() { driver_adc_int_handler(&VRef_VTem_ADC,(uint16_t *)Vref_Vtemp_data); } |
13.4.6main函數(shù)實(shí)現(xiàn)
C int main(void) { delay_init();//delay函數(shù)初始化 bsp_uart_init(&BOARD_UART);//BOARD_UART串口初始化 bsp_Vref_Vtemp_ADC_config();//內(nèi)部通道ADC配置和中斷使能 while (1) { driver_adc_software_trigger_enable(&VRef_VTem_ADC); //軟件觸發(fā)ADC delay_ms(1000); temperature = (1.45 - Vref_Vtemp_data[0]*3.3/4095) * 1000 / 4.1 + 25; /*內(nèi)部溫度ADC轉(zhuǎn)換值轉(zhuǎn)換為實(shí)際溫度值*/ vref_value = (Vref_Vtemp_data[1] * 3.3 / 4095); /*內(nèi)部參考電壓ADC轉(zhuǎn)換值轉(zhuǎn)換為實(shí)際電壓值*/ printf(" the temperature data is %2.0f degrees Celsius\r\n", temperature); /*打印實(shí)際溫度值*/ printf(" the reference voltage data is %5.3fV \r\n", vref_value); /*打印內(nèi)部參考實(shí)際電壓值*/ } } |
本例程main函數(shù)首先進(jìn)行了延時(shí)函數(shù)初始化,為了演示實(shí)驗(yàn)結(jié)果,這里初始化了BOARD_UART串口,關(guān)于串口的使用,請(qǐng)讀者參考串口章節(jié),然后是內(nèi)部通道ADC的配置和中斷使能。在主循環(huán)中,先出發(fā)一次內(nèi)部通道ADC,然后延時(shí)1s,在延時(shí)過程中ADC轉(zhuǎn)換結(jié)束會(huì)進(jìn)入ADC中斷函數(shù),中斷函數(shù)將兩個(gè)注入組通道數(shù)據(jù)賦給Vref_Vtemp_data數(shù)組,延時(shí)結(jié)束后,對(duì)溫度和內(nèi)部電壓進(jìn)行計(jì)算并將計(jì)算結(jié)果打印出來。
13.5實(shí)驗(yàn)結(jié)果
使用USB-TypeC線,連接電腦和板上USB to UART口后,配置好串口調(diào)試助手,即可看到內(nèi)部溫度傳感器測(cè)到的溫度值以及內(nèi)部參考電壓值了。
![]() | ![]() |
本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)
-
單片機(jī)
+關(guān)注
關(guān)注
6065文章
44940瀏覽量
647932 -
adc
+關(guān)注
關(guān)注
99文章
6656瀏覽量
548484 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5576瀏覽量
102981 -
GD32
+關(guān)注
關(guān)注
7文章
419瀏覽量
25228
發(fā)布評(píng)論請(qǐng)先 登錄
【星空派GD32F303開發(fā)板試用體驗(yàn)】開發(fā)記錄匯總
【星空派GD32F303開發(fā)板試用體驗(yàn)】開箱+環(huán)境搭建
【星空派GD32F303開發(fā)板試用體驗(yàn)】開箱+環(huán)境搭建
【星空派GD32F303開發(fā)板試用體驗(yàn)】+板卡概覽
星空派GD32F303開發(fā)板的相關(guān)資料下載
第十三講 施密特觸發(fā)器

STM32CUBEMX開發(fā)GD32F303(14)----IIC之配置OLED

GD32F303固件庫(kù)開發(fā)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二講 GPIO-流水燈實(shí)驗(yàn)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第三講 GPIO-按鍵查詢檢測(cè)實(shí)驗(yàn)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第五講 FMC-片內(nèi)Flash擦寫讀實(shí)驗(yàn)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第十二講 ADC-雙軸按鍵搖桿多通道循環(huán)采樣實(shí)驗(yàn)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第十六講 USART-DMA串口收發(fā)實(shí)驗(yàn)

【GD32F303紅楓派開發(fā)板使用手冊(cè)】第二十講 SPI-SPI NAND FLASH讀寫實(shí)驗(yàn)

評(píng)論