AiPi-Eyes-S1是安信可開源團隊專門為Ai-M61-32S設計的一款開發板,支持WiFi6、BLE5.3。所搭載的Ai-M61-32S 模組具有豐富的外設接口,具體包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太網 (EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。
AiPi-Eyes-S1集成了SPI屏幕接口,DVP攝像頭接口,外置ES8388音頻編解碼芯片以及預留TF卡座,并且引出USB接口,可接入USB攝像頭。
從零開始學習小安派:
1、零基礎開發小安派-Eyes-S1【入門篇】——初識小安派-Eyes-S1
2、零基礎開發小安派-Eyes-S1【入門篇】——安裝VMware與Ubuntu
3、入門篇:零基礎開發小安派-Eyes-S1——新建工程并燒錄調試
4、零基礎開發小安派-Eyes-S1入門篇——Win下SSH連接Linux
5、零基礎開發小安派-Eyes-S1【入門篇】——Samba共享文件夾
6、零基礎開發小安派-Eyes-S1【入門篇】——工程文件架構
7、零基礎開發小安派-Eyes-S1【外設篇】——GPIO 輸入輸出
8、零基礎開發小安派-Eyes-S1【外設篇】——GPIO中斷編程
9、零基礎開發小安派-Eyes-S1【外設篇】——PWM
10、零基礎開發小安派-Eyes-S1【外設篇】——UART
11、零基礎開發小安派-Eyes-S1【外設篇】——I2C
ADC 指的是模數轉換器(Analog-to-Digital Converter),它是一種用于將模擬信號轉換為數字信號的電子設備或電路。
模擬信號是連續變化的信號,可以取無限個可能的值,而數字信號則是離散的,只能表示有限個數值。ADC 的作用就是將模擬信號轉換為離散的數字信號,以便數字電子系統進行處理、存儲和傳輸。
ADC 的基本工作原理是通過一系列的采樣和量化過程來實現模擬到數字的轉換:
1.采樣(Sampling):ADC 根據一定的時間間隔,從模擬信號中獲取一系列離散的采樣點。采樣率決定了采樣點的密度,較高的采樣率可以更精確地表示原始模擬信號。
2.量化(Quantization):采樣得到的模擬信號樣本通常是連續的,量化則將每個采樣點映射為一個特定的數字值。量化過程將連續的模擬信號離散化,并分配給每個樣本一個數字值。
3.編碼(Encoding):編碼將量化后的數字值表示為二進制形式,以便于數字系統處理。常見的編碼方式包括無符號二進制、補碼和格雷碼等。
總的來說,生活中會有許多“模擬量”,如一段從低音到高音的音頻,在數字信號中,不能簡單的把低音表示 0,高音表示 1,這樣歌曲中間的音頻變化是空的,沒有小數點這些概念來顯示他們從 0 到 0.5 到 1 的過程。所以需要有個模數轉換的過程,稱為 ADC。比如用 12 位精度的 ADC 來表示這段音頻,低音就 0,高音就是 2^12 次也就是 4096,那么在這段音頻中我們就可以通過 0-4096 的過程來判斷音頻的高和低,具體到高到有多高,低到有多低,而 ADC 的精度越高,如 16 位,就可達到 0-65535 的范圍。
一、了解小安派-Eyes-S1 的 ADC
芯片內置一個 12bits 的逐次逼近式模擬數字轉換器 (ADC),支持 12 路外部模擬輸入和若干內部模擬信號選擇。ADC 可以工作在 4 種模式下,轉換結果為 12/14/16bits 左對齊模式。
ADC 擁有深度為 32 字節的 FIFO,支持多種中斷,支持 DMA 操作。ADC 除了用于普通模擬信號測量外,還可以用于測量供電電壓,此外 ADC 還可以通過測量內/外部二極管電壓用于溫度檢測。
具有 12 路外部模擬通道,對應的 GPIO 如下:
此外,還具有 2 路 DAC 內部通道,1 路 VBAT/2 通道,1 路 TSEN 通道
adc clock div
對 adc 時鐘再一次進行分頻。分頻后的時鐘必須小于等于 500K。
ADC CLK = CLK_SOURCE/CLK_DIV/adc_clk_div
#define ADC_CLK_DIV_4 1
#define ADC_CLK_DIV_8 2
#define ADC_CLK_DIV_12 3
#define ADC_CLK_DIV_16 4
#define ADC_CLK_DIV_20 5
#define ADC_CLK_DIV_24 6
#define ADC_CLK_DIV_32 7
adc resolution
adc 位數,可以選擇 12B、14B、16B。其中 14B 和 16B 自帶過采樣處理
#define ADC_RESOLUTION_12B 0
#define ADC_RESOLUTION_14B 2
#define ADC_RESOLUTION_16B 4
adc vref
adc 內置參考電壓選擇,可以選擇 2.0 V 或者 3.2V
#define ADC_VREF_3P2V 0
#define ADC_VREF_2P0V 1
二、結構體與 API
struct bflb_adc_config_s
說明:adc 初始化配置結構體。
struct bflb_adc_config_s {
uint8_t clk_div;
uint8_t scan_conv_mode;
uint8_t continuous_conv_mode;
uint8_t differential_mode;
uint8_t resolution;
uint8_t vref;
};
掃描模式:可按照用戶指定通道個數和順序逐個轉換,結果推入 ADC 的 FIFO
連續轉換模式:允許 ADC 連續不斷地執行模數轉換,只需要調用一次 ADC 啟動
差分模式:ADC 支持單端輸入模式和差分模式,選擇單端時負極輸入通道選擇 GND
struct bflb_adc_channel_s
說明:配置 adc 通道時使用。
struct bflb_adc_channel_s {
uint8_t pos_chan;
uint8_t neg_chan;
};
struct bflb_adc_result_s
說明:adc 標準轉換結果
struct bflb_adc_result_s {
int8_t pos_chan;
int8_t neg_chan;
int32_t value;
int32_t millivolt;
};
bflb_adc_init
說明: 初始化 adc。adc 使用之前需要開啟 adc ip 時鐘、設置 adc 時鐘源和分頻值、選擇使用的 gpio 為 analog 模式。
void bflb_adc_init(struct bflb_device_s *dev, const struct bflb_adc_config_s *config);
bflb_adc_deinit
說明: 反初始化 adc。
void bflb_adc_deinit(struct bflb_device_s *dev);
bflb_adc_link_rxdma
說明: adc dma 功能開關。
void bflb_adc_link_rxdma(struct bflb_device_s *dev, bool enable);
bflb_adc_channel_config
說明: 配置 adc 通道。
int bflb_adc_channel_config(struct bflb_device_s *dev, struct bflb_adc_channel_s *chan, uint8_t channels);
bflb_adc_start_conversion
說明: 啟動 adc 轉換。連續轉換模式下只需要調用一次。
void bflb_adc_start_conversion(struct bflb_device_s *dev);
bflb_adc_stop_conversion
說明: 停止 adc 轉換。
void bflb_adc_stop_conversion(struct bflb_device_s *dev);
bflb_adc_get_count
說明: 獲取 adc 轉換個數。
uint8_t bflb_adc_get_count(struct bflb_device_s *dev);
bflb_adc_read_raw
說明: 讀取一次 adc 轉換值。
uint32_t bflb_adc_read_raw(struct bflb_device_s *dev);
bflb_adc_rxint_mask
說明: adc 轉換完成中斷開關。
void bflb_adc_rxint_mask(struct bflb_device_s *dev, bool mask);
bflb_adc_errint_mask
說明: adc 錯誤中斷開關。
void bflb_adc_errint_mask(struct bflb_device_s *dev, bool mask);
bflb_adc_get_intstatus
說明: adc 中斷標志。
uint32_t bflb_adc_get_intstatus(struct bflb_device_s *dev);
返回值如下:
ADC_INTSTS_NEG_SATURATIONADC_INTSTS_NEG_SATURATION
ADC_INTSTS_FIFO_UNDERRUN
ADC_INTSTS_FIFO_OVERRUN
ADC_INTSTS_ADC_READY
bflb_adc_int_clear
說明: 清除 adc 中斷標志。
void bflb_adc_int_clear(struct bflb_device_s *dev, uint32_t int_clear);
int_clear 可以填入以下參數:
ADC_INTCLR_NEG_SATURATIONADC_INTCLR_POS_SATURATION
ADC_INTCLR_FIFO_UNDERRUN
ADC_INTCLR_FIFO_OVERRUN
ADC_INTCLR_ADC_READY
bflb_adc_parse_result
說明: 對 adc 轉換結果進行解析。
void bflb_adc_parse_result(struct bflb_device_s *dev, uint32_t *buffer, struct bflb_adc_result_s *result, uint16_t count);
bflb_adc_tsen_init
說明: 初始化 adc tsen 模塊。
void bflb_adc_tsen_init(struct bflb_device_s *dev, uint8_t tsen_mod);
bflb_adc_tsen_get_temp
說明: 獲取 adc tsen 模塊采集的溫度。
float bflb_adc_tsen_get_temp(struct bflb_device_s *dev);
bflb_adc_vbat_enable
說明: 開啟 vbat 。
void bflb_adc_vbat_enable(struct bflb_device_s *dev);
bflb_adc_vbat_disable
說明: 關閉 vbat。
void bflb_adc_vbat_disable(struct bflb_device_s *dev);
三、示例——連續讀取 IO 的 ADC 值,ADC 轉換完成中斷
Main
#include "bflb_adc.h"
#include "bflb_mtimer.h"
#include "board.h"
#include "bflb_gpio.h"
//頭文件
struct bflb_device_s *adc;
//外設結構體設置
void My_adc_gpio_init()
{
struct bflb_device_s *gpio;
gpio = bflb_device_get_by_name("gpio");
bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
}
//設置需要AD采集的IO腳,對應的通道和IO要匹配
volatile uint32_t raw_data;
//接收AD值變量
void adc_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_adc_get_intstatus(adc);
if (intstatus & ADC_INTSTS_ADC_READY) {
bflb_adc_int_clear(adc, ADC_INTCLR_ADC_READY);
raw_data= bflb_adc_read_raw(adc);
}
}
//中斷函數,清除中斷標志位,將讀取的AD變量賦給raw_data
int main(void)
{
board_init();
My_adc_gpio_init();
adc = bflb_device_get_by_name("adc");
/* adc clock = XCLK / 2 / 32 */
struct bflb_adc_config_s cfg;
cfg.clk_div = ADC_CLK_DIV_32;
cfg.scan_conv_mode = false;
cfg.continuous_conv_mode = false;
cfg.differential_mode = false;
cfg.resolution = ADC_RESOLUTION_16B;
cfg.vref = ADC_VREF_3P2V;
//adc結構體配置
struct bflb_adc_channel_s chan;
chan.pos_chan = ADC_CHANNEL_9;
chan.neg_chan = ADC_CHANNEL_GND;
//通道配置,單端模式下neg選擇GND,pos注意對應IO口的通道
bflb_adc_init(adc, &cfg);
bflb_adc_channel_config(adc, &chan, 1);
bflb_adc_rxint_mask(adc, false);
bflb_irq_attach(adc->irq_num, adc_isr, NULL);
bflb_irq_enable(adc->irq_num);
//中斷使能配置
while (1) {
struct bflb_adc_result_s result;
bflb_adc_start_conversion(adc);
bflb_adc_parse_result(adc, (uint32_t *)&raw_data, &result, 1);
printf("rnpos chan %drnADC Value = %drnCurrent Voltage = %d mvrn", result.pos_chan, result.value, result.millivolt);
bflb_adc_stop_conversion(adc);
bflb_mtimer_delay_ms(1000);
//主函數讀取AD值并轉化為電壓
}
}
四、效果
審核編輯 黃宇
-
芯片
+關注
關注
454文章
50444瀏覽量
421922 -
adc
+關注
關注
98文章
6443瀏覽量
544129 -
模擬信號
+關注
關注
8文章
1119瀏覽量
52406 -
開源
+關注
關注
3文章
3256瀏覽量
42412
發布評論請先 登錄
相關推薦
評論