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