ADC——電壓采集
25.1. ADC簡介
ADC即模擬數字轉換器,ADC英文全稱(Analog-to-digital converter), 是一種用于將模擬電壓的連續信號轉換為離散的數字信號。 就比如我們可以將我們生活中的溫度、壓力、聲音這樣的模擬信號通過ADC轉化為我們可以通過單片機處理的數字信號。
RA6M5 有2個ADC單元,每個ADC單元有12位、10位、8位讀取數據的格式可以選擇,在單元0上有13個ADC通道,而在單元1上有16個ADC通道。 ADC單元具有三種掃描方式分別為:單次描模式、連續掃描模式和分組掃描模式, 對于RA6M5來說ADC單元具有強大的功能,具體我們可以通過ADC特性和ADC的結構框圖中分析每個部分的功能。
25.1.1. ADC特性
- 2 個ADC轉換單元。
- 可以進行TrustZone安全設置。
- 支持內部溫度檢測,內部參考電壓。
- 逐次逼近型ADC,支持的分辨率:12-bit, 10-bit, 8-bit。
- 轉換時間短:0.4 μs/每通道(12-bit ADC、時鐘PCLKC (ADCLK)等于50 MHz的條件下)。
- 可啟用A/D 數據存儲緩沖區是一個環形緩沖區,由16個緩沖區組成,用于順序存儲A/D轉換后的數據。
- 自診斷在每次掃描開始時執行一次,在ADC執行生成中的三個參考電壓值中選擇一個A/D轉換值。
25.2. ADC的結構框圖
### 25.2.1. 電壓輸入范圍
ADC輸入范圍為:VREFL- ≤ VIN ≤ VREFH+。 RA6M5的參考電壓是由VREFL、VREFH 、AVCC0 、AVSS0 這四個外部引腳決定,且每個單元可以設置不同的參考電壓,具體我們可以通過設置不同通道的VREFL、VREFH進行改變。
我們在設計原理圖的時候一般把AVSS0和VREFL接地,把AVCC0和VREFH接3V3,得到ADC的輸入電壓范圍為:0-3.3V。 如果我們想讓輸入的電壓范圍變寬,可以測試負電壓或者更高的正電壓,我們可以在外部加一個電壓調理電路, 把需要轉換的電壓抬升或者降壓到0~3.3V,這樣ADC就可以測量了,為了測量的準確性我們還可以加上磁珠進行濾波。
25.2.2. 工作模式
在ADC單元0中有多達13個模擬輸入通道,而在ADC單元1中有多達16個模擬輸入通道以及內部的溫度傳感器輸出, 兩個ADC單元加起來總共就擁有了29個ADC通道,這么多的ADC通道我們該如何使用它們呢? 在這里我們就可以引入工作模式的概念, 我的單片機上的ADC處在什么樣的工作模式進行ADC轉換以及我們該如何進行設置。
- 單次掃描模式:在單次掃描下,一次掃描一個或多個指定通道。
- 連續掃描模式:在連續掃描下,一個或多個指定的通道被重復掃描,直到軟件設置寄存器ADCSR.ADST位為0。
- 分組掃描模式:將所選擇的模擬輸入通道上分為A組和b組,然后按組對所選擇的模擬輸入通道進行一次A/D轉換。 A、B組可獨立選擇掃描啟動條件,可獨立啟動A、B組的A/D轉換。
在單次掃描模式下和在連續掃描模式下,都會從最小的掃描通道開始從低到高進行A/D轉換。 如果開啟了自診斷模式,在每次掃描開始時執行一次, 并轉換三個參考電壓中選擇一個。 每一種轉換都有著它的優點和缺點,但具體使用什么模式進行ADC轉換,就需要通過我們的項目的需求需要什么樣的效果來決定。
25.2.3. 轉換過程順序
有三種掃描轉換模式分別為:單次掃描模式、連續掃描模式、組掃描模式。 在掃描中,A/D轉換是按順序對指定通道的模擬輸入進行的。
單次掃描模式 :
在單次掃描模式轉換期間,我們可以通過ADST為來判斷ADC是否處在工作狀態,在ADC轉換的期間ADST為將一直保持為1,當所有選定通道的ADST轉換完成時,將自動設置為0。 然后ADC將進入一個等待狀態。
- 當ADCSR.ADST位通過軟件觸發器、同步觸發器輸入(ELC)和異步觸發器輸入被置1的時候,ADC轉換開始。 對在ADANSA0和ADANSA1寄存器中選擇的ANn通道進行A/D轉換,從編號最小的n的通道開始。
- 每當單個信道的A/D轉換完成時,A/D轉換結果都被存儲在關聯的A/D數據寄存器(ADDRy)中。
- 當所有選定通道的A/D轉換完成時,將生成一個ADC12i_ADI(i = 0,1)中斷請求。
連續掃描模式 :
在連續掃描模式下,對指定信道的模擬輸入重復執行A/D轉換。 這里的ADCSR.ADST位不會自動清除,只要ADCSR.ADST位保持1時就會一直的重復步驟2、步驟3、步驟4,直到ADCSR.ADST位通過軟件被置0時ADC單元轉換才會停止,之后ADC單元進入等待狀態。
- 當ADCSR.ADST位通過軟件觸發器、同步觸發器輸入(ELC)和異步觸發器輸入被置1的時候,ADC轉換開始。 對在ADANSA0和ADANSA1寄存器中選擇的ANn通道進行A/D轉換,從編號最小的n的通道開始。
- 每當單個信道的A/D轉換完成時,A/D轉換結果都被存儲在關聯的A/D數據寄存器(ADDRy)中。
- 當所有選定通道的A/D轉換完成時,將生成一個ADC12i_ADI(i = 0,1)中斷請求。
- 對在ADANSA0和ADANSA1寄存器中選擇的ANn通道進行A/D轉換,從編號最小的n的通道開始。
組掃描模式 :
在群組掃描模式下,請選擇A、B兩組,分別選擇A、B兩組的開始掃描條件,并在不同的時間開始掃描。 另外我們還可以設置優先級,假設我們設置A組優先級高于B組優先級操作時,就可以在B組A/D轉換時打斷它, 使得A組進行A/D轉換,而B組暫停A/D轉換。
我們以ELC為列例子:使用GPT作為A組的觸發源,并使用A組作為B組的觸發源。
- 當ELC0上的GPT觸發ELC_ADC(A組)時,A組的ADC開始轉換。
- 當組A掃描完成時,將生成一個ADC12i_ADI(i = 0,1)中斷。
- B組的掃描由ELC_ADC(A組)開始。
- 當B組掃描完成時,如果ADCSR.GBADIE位為1時將生成一個ADC12i_GBADI(i = 0,1)中斷。
25.2.4. 觸發源
通道選好了,工作模式也設置好了,那么接下來就需要設置我們的觸發源了。 我們可以設置軟件來觸發ADC、或者通過使用ELC進行觸發、甚至我們還可以使用外部中斷進行觸發。 最終我們的目的是為了使得ADCSR.ADST位被置1,以至于我們可以使用不同的方式進行觸發。
下圖為我們可以在FSP里選擇的模式:
25.2.5. ADC轉換時間
25.2.5.1. ADC時鐘
ADC輸入時鐘(轉換時鐘)ADCLK由PCLKC經過分頻產生,最大值是四分頻50MHz,ADC允許的最大值是50MHz,當我們使用50 MHz的時候12-bit轉換時間為0.4 μs。 PCLKA 和 PCLKC (ADCLK) 的分頻比可以設置為 1:1, 2:1, 4:1, 8:1, 1:2, 1:4。
25.2.5.2. 采樣時間
掃描轉換時間(tSCAN)包括:掃描開始時間(tD)、斷開檢測輔助處理時間(tDIS)*1、自診斷A/D轉換處理時間(tDIAG和tDSD)*2、A/D轉換處理時間(tCONV)、掃描結束時間(tED)。
A/D轉換處理時間(tCONV)由輸入采樣時間(tSPL)和逐次逼近轉換時間(tSAM)組成。 采樣時間(tSPL)用于在A/D轉換器中對采樣和保持電路充電。 如果由于模擬輸入信號源的高阻抗而沒有足夠的采樣時間,或者如果A/ D轉換時鐘(ADCLK)很慢,可以使用ADSSTRn寄存器來調整采樣時間。
由逐次逼近(tSAM)轉換的時間如下
- 12位精度需要13個ADCLK
- 狀態10位精度需要11個ADCLK
- 狀態8位精度需要9ADCLK
選擇通道數為n的單次描模式下的掃描轉換時間(tSCAN)可確定為:
連續掃描模式下第一個周期的掃描轉換時間為單次掃描減去tED的tSCAN。 連續掃描模式下第二次及后續周期的掃描轉換時間固定如下:
25.2.6. 數據寄存器
在RA6M5的ADC中的數據寄存器有很多種,用來保存不同描模式下的數據 比如:ADDRn寄存器是16位只讀寄存器(n=0~15),用來存儲A/D轉換結果、ADTSDR寄存器用來保存內部的溫度傳感器數據寄存器、 ADRD寄存器是用來自動診斷數據寄存器、ADOCDR寄存器是ADC內部參考電壓數據寄存器。
我們還可以通過一些寄存器來設置數據的格式比如: ADC轉換精度選擇由ADCER.ADPRC[1:0]位設置(12位、10位、8位可選)、 ADC數據寄存器格式選擇位ADCER.ADRFMT位設置(左對齊或右對齊)
25.2.7. 電壓轉換
模擬電壓經過ADC轉換后,是一個12位的數字值,如果通過串口以16進制打印出來的話,可讀性比較差,那么有時候我們就需要把數字電壓轉換成模擬電壓,也可以跟實際的模擬電壓(用萬用表測)對比,看看轉換是否準確。
我們一般在設計原理圖的時候會把ADC的輸入電壓范圍設定在:0~3.3v,因為ADC是12位的,那么12位滿量程對應的就是3.3V,12位滿量程對應的數字值是:2^12。 數值0對應的就是0V。 如果轉換后的數值為 X ,X對應的模擬電壓為Y,那么會有這么一個等式成立: 2^12 / 3.3 = X / Y,=> Y = (3.3 * X ) / 2^12。
25.3. ADC程序設計
25.3.1. 硬件設計
ADC引腳 [](https://doc.embedfire.com/mcu/renesas/fsp_ra/zh/latest/doc/chapter25/chapter25.html#id22 "永久鏈接至表格")| ADC引腳 | P000 |
| ----------------- | ------ |
25.3.2. 軟件設計
25.3.2.1. 新建工程
因為本章節的 ADC 相關實驗例程需要用到板子上的串口功能,因此我們可以直接以前面的“19_UART_Receive_Send”工程為基礎進行修改。
對于 e2 studio 開發環境:拷貝一份我們之前的 e2s 工程模板 “19_UART_Receive_Send” , 然后將工程文件夾重命名為 “25_ADC” ,最后再將它導入到我們的 e2 studio 工作空間中。
對于 Keil 開發環境:拷貝一份我們之前的 Keil 工程模板 “19_UART_Receive_Send” , 然后將工程文件夾重命名為 “25_ADC” ,并進入該文件夾里面雙擊 Keil 工程文件, 打開該工程。
25.3.2.2. FSP配置
我們先打開e2 studio軟件里面的 Smart Configurator 配置FSP。
雙擊 configuration.xml 打開配置界面: 然后點開依次點擊 Stacks -> New Stack -> Analog -> ADC(r_adc) 來配置ADC模塊。
ADC頁面的屬性介紹
ADC 屬性介紹 [](https://doc.embedfire.com/mcu/renesas/fsp_ra/zh/latest/doc/chapter25/chapter25.html#id23 "永久鏈接至表格")| ADC屬性 | 描述 |
| - | - |
| ----------------------------- |
烏因特 | 指定要使用的ADC單元 |
---|---|
再接 | 指定轉換分辨率 |
對準 | 指定轉換結果對齊方式 |
閱讀后清除 | 讀取轉換結果后自動清除 |
模式 | 模式 |
雙扳機裝置 | 雙觸發 |
正常/A 組觸發器 | A的觸發模式 |
回調 | 回調函數 |
掃描結束中斷優先級 | 掃描完成中斷優先級 |
模數轉換器環形緩沖器 | ADC環形緩沖區 |
配置完成之后可以按下快捷鍵“Ctrl + S”保存, 最后點右上角的 “Generate Project Content” 按鈕,讓軟件自動生成配置代碼即可。
25.3.2.3. ADC初始化
void adc_Init(void)
{
fsp_err_t err;
err = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg);
err = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
assert(FSP_SUCCESS == err);
}
- R_ADC_Open()為整個外設設置操作模式、觸發源、中斷優先級和配置。 如果啟用了中斷,該函數將注冊一個回調函數指針,以便在掃描完成時通知用戶。
- R_ADC_ScanCfg()配置ADC掃描參數。 通道特定設置是在這個函數中設置的。
25.3.2.4. ADC回調函數
volatile bool scan_complete_flag = false;
void adc_callback(adc_callback_args_t * p_args)
{
FSP_PARAMETER_NOT_USED(p_args);
scan_complete_flag = true;
}
在FSP配置頁面注冊回調函數以及優先級,我們就可以使用來自ADC的中斷回調函數了。
注解
我們通過ADC的中斷回調函數來判斷ADC是否轉換完成。 我們需要定義了一個布爾類型的數據scan_complete_flag來當做ADC讀取完成的標志位。 當沒有轉換完成的時候scan_complete_flag的值一直為false,單ADC觸發中斷的時候將scan_complete_flag的值變為true。
25.3.2.5. 如果未啟用中斷
如果未啟用中斷,則可使用R_ADC_StatusGet() API 用于輪詢 ADC 以確定掃描何時完成。 讀取 API 函數用于訪問轉換后的 ADC 結果。 這適用于支持校準的MCU的普通掃描和校準掃描。
25.3.2.6. ADC讀取轉換后的數值
ADC讀取思路,我們在這里調用R_ADC_ScanStart觸發相應的adc通道轉換,當ADC轉換完成之后會將scan_complete_flag標志位變為true。 當我們判斷到標志位變為true后我們使用R_ADC_Read()或R_ADC_Read32()讀取轉換完成的數值。
double adc_read(void)
{
uint16_t adc_data;
double a0;
(void)R_ADC_ScanStart(&g_adc0_ctrl);
scan_complete_flag = false;
while (!scan_complete_flag)
{
;
}
R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc_data);
a0 = (double)(adc_data*3.3/4095);
return a0;
}
- R_ADC_ScanStart()啟動軟件掃描或啟用掃描的硬件觸發器,具體取決于觸發器在R_ADC_Open調用中的配置方式。 如果該單元被配置為ELC或外部硬件觸發,那么該功能允許觸發信號到達ADC單元。 該函數不能控制觸發器本身的生成。 如果該單元被配置為軟件觸發,則該功能啟動軟件觸發掃描。
- R_ADC_Read()從單通道或傳感器寄存器讀取轉換結果,返回的數據為uint16_t型。
- R_ADC_Read32()從單通道或傳感器寄存器讀取轉換結果,返回的數據為uint32_t型。
25.3.2.7. hal_entry函數
void hal_entry(void)
{
err = R_SCI_UART_Open(&g_uart4_ctrl, &g_uart4_cfg);
printf("開始讀取ADC的數值\\r\\n");
adc_Init();
while(1){
printf("a0=%f\\r\\n",adc_read());
R_BSP_SoftwareDelay(1000,BSP_DELAY_UNITS_MILLISECONDS); //大概1秒鐘讀取一次
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
25.3.3. 下載驗證
用USB線連接開發板“USB TO UART”接口跟電腦,在電腦端打開串口調試助手,把編譯好的程序下載到開發板。 在串口調試助手可看到ADC引腳讀出的模擬數值。
評論