0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

零基础开发小安派-Eyes-S1外设篇——ADC

AIoT行业洞察 来源: AIoT行业洞察 作者: AIoT行业洞察 2024-11-27 16:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

AiPi-Eyes-S1是安信可开源团队专门为Ai-M61-32S设计的一款开发板,支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口,具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SPI、UARTI2C、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 如下:

wKgZO2dG26iAU49WAACKa3-cOIA915.jpg

此外,还具有 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;
};

wKgZPGdG26iAYNM8AABcrcIM9Qk711.jpg

扫描模式:可按照用户指定通道个数和顺序逐个转换,结果推入 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;
};

wKgZO2dG26iASZCHAAAurtun7TA777.jpg

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;
};

wKgZO2dG26mAeiVCAABDhS8-KFE513.jpg

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);

wKgZPGdG26mAB9PzAAAnpLjrPOs269.jpg

bflb_adc_deinit

说明: 反初始化 adc。

void bflb_adc_deinit(struct bflb_device_s *dev);

wKgZO2dG26mAKCvIAAANT31F5oA323.jpg

bflb_adc_link_rxdma

说明: adc dma 功能开关。

void bflb_adc_link_rxdma(struct bflb_device_s *dev, bool enable);

wKgZO2dG26qAIxCyAAAoMn2lOAw772.jpg

bflb_adc_channel_config

说明: 配置 adc 通道。

int bflb_adc_channel_config(struct bflb_device_s *dev, struct bflb_adc_channel_s *chan, uint8_t channels);

wKgZPGdG26qARi9nAAA08zRIwuc521.jpg

bflb_adc_start_conversion

说明: 启动 adc 转换。连续转换模式下只需要调用一次。

void bflb_adc_start_conversion(struct bflb_device_s *dev);

wKgZO2dG26uAXfS2AAAM22C5UR4151.jpg

bflb_adc_stop_conversion

说明: 停止 adc 转换。

void bflb_adc_stop_conversion(struct bflb_device_s *dev);

wKgZPGdG26uAWVoKAAANMmHi4s4067.jpg

bflb_adc_get_count

说明: 获取 adc 转换个数。

uint8_t bflb_adc_get_count(struct bflb_device_s *dev);

wKgZO2dG26yANY1YAAAplaSUgB0901.jpg

bflb_adc_read_raw

说明: 读取一次 adc 转换值。

uint32_t bflb_adc_read_raw(struct bflb_device_s *dev);

wKgZPGdG26yACRF0AAAmEHGPOBw679.jpg

bflb_adc_rxint_mask

说明: adc 转换完成中断开关。

void bflb_adc_rxint_mask(struct bflb_device_s *dev, bool mask);

wKgZO2dG262AY6o_AAAlqG3F6Qs515.jpg

bflb_adc_errint_mask

说明: adc 错误中断开关。

void bflb_adc_errint_mask(struct bflb_device_s *dev, bool mask);

wKgZPGdG262AXasnAAAni2EgIps897.jpg

bflb_adc_get_intstatus

说明: adc 中断标志。

uint32_t bflb_adc_get_intstatus(struct bflb_device_s *dev);

wKgZO2dG262AQuYjAAAnUO2VkYY322.jpg

返回值如下:

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);

wKgZPGdG266AcCTOAAAnZm9P1Y8718.jpg

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);

wKgZO2dG266AB5jeAAA5nrVYQFg218.jpg

bflb_adc_tsen_init

说明: 初始化 adc tsen 模块。

void bflb_adc_tsen_init(struct bflb_device_s *dev, uint8_t tsen_mod);

wKgZO2dG26-ADmzQAAAn2avgO8E073.jpg

bflb_adc_tsen_get_temp

说明: 获取 adc tsen 模块采集的温度。

float bflb_adc_tsen_get_temp(struct bflb_device_s *dev);

wKgZPGdG26-AV2-kAAAmlqrczkc748.jpg

bflb_adc_vbat_enable

说明: 开启 vbat 。

void bflb_adc_vbat_enable(struct bflb_device_s *dev);

wKgZO2dG27CAIXlNAAAPDDEZkpU600.jpg

bflb_adc_vbat_disable

说明: 关闭 vbat。

void bflb_adc_vbat_disable(struct bflb_device_s *dev);

wKgZPGdG27CAZ3aiAAAOj1drrTw165.jpg

三、示例——连续读取 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值并转化为电压
}
}

四、效果

wKgZO2dG27CAYVZdAAB9M3wUA7g121.jpg

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 芯片
    +关注

    关注

    462

    文章

    53582

    浏览量

    459751
  • adc
    adc
    +关注

    关注

    100

    文章

    7452

    浏览量

    553915
  • 模拟信号
    +关注

    关注

    8

    文章

    1225

    浏览量

    54418
  • 开源
    +关注

    关注

    3

    文章

    4047

    浏览量

    45596
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    小安立式桌摆外壳设计制作

    小安-Eyes-R2,但是一直没什么时间好好的研究一下。近期学习了一下相关例程,感觉用的很难受,大概是因为屏幕排线比较短且板子和屏幕不好固定,以及烧录两个按键必须要俩手按,于是考虑做外壳固定一下。  
    的头像 发表于 09-09 17:20 608次阅读
    <b class='flag-5'>小安</b><b class='flag-5'>派</b>立式桌摆外壳设计制作

    【开源硬件】小安AiPi-Eyes-R2详细测评+DIY天气时钟

    接口-130W像素 1 显示器-4.0寸-RGB接口40寸-像素480x480 1 咪头-2pin-1.25mm间距-交叉绞线100mm 2 具体开箱流程照片如下: 环境搭建 因为之前笔者已经用过Windows开发
    的头像 发表于 08-12 16:23 615次阅读
    【开源硬件】<b class='flag-5'>小安</b><b class='flag-5'>派</b>AiPi-<b class='flag-5'>Eyes</b>-R2详细测评+DIY天气时钟

    【「零基开发AI Agent」阅读体验】+读《零基开发AI Agent》掌握扣子平台开发智能体方法

    收到发烧友网站寄来的《零基开发AI Agent》这本书已经有好些天了,这段时间有幸拜读了一下全书,掌握了一个开发智能体的方法。 该书充分从零基础入手,先阐述了Agent是什么,它的基
    发表于 05-14 19:51

    【「零基开发AI Agent」阅读体验】+ 入门学习

    很高兴又有机会学习ai技术,这次试读的是「零基开发AI Agent」,作者叶涛、管锴、张心雨。 大模型的普及是近三年来的一件大事,万物皆可大模型已成为趋势。作为大模型开发应用中重要组成部分,提示词
    发表于 05-02 09:26

    【「零基开发AI Agent」阅读体验】+初品Agent

    期待中的《零基开发AI Agent——手把手教你用扣子做智能体》终于寄到了,该书由叶涛、 管锴、张心雨完成,并由电子工业出版社出版发行。 全书分为三个部分,即入门、工具及实践
    发表于 04-22 11:51

    基于小凌RK2206开发板:OpenHarmony如何使用IoT接口控制ADC外设

    1、案例简介本案例主要讲解如何在小凌-RK2206开发板上使用IoT库的ADC接口,进行ADC编程开发
    的头像 发表于 04-10 16:00 723次阅读
    基于小凌<b class='flag-5'>派</b>RK2206<b class='flag-5'>开发</b>板:OpenHarmony如何使用IoT接口控制<b class='flag-5'>ADC</b><b class='flag-5'>外设</b>

    功德+1,用小安-Eyes-S1做一个电子木鱼

    2024积德累功,心想事成!接下来看看如何用小安-Eyes-S1做一个电子木鱼。01GUI-Guider页面设计先新建一个工程。直接进入UI设计界面,这里用到了两个
    的头像 发表于 04-09 18:38 804次阅读
    功德+<b class='flag-5'>1</b>,用<b class='flag-5'>小安</b><b class='flag-5'>派</b>-<b class='flag-5'>Eyes-S1</b>做一个电子木鱼

    基于小安的可爱摆件

    小安摆件   前言 不知道有多少人和笔者一样,被一首“萝莉摇”洗脑过?打开短视频总会看到这首BGM和MV的二创。   于是笔者萌生了制作一个相关摆件的想法,这些就用小安派来做个“萝莉摇”摆件,让
    的头像 发表于 02-18 14:57 603次阅读
    基于<b class='flag-5'>小安</b><b class='flag-5'>派</b>的可爱摆件

    零基开发小安-Eyes-S1 进阶 ——通过屏幕输入连接 Wi-Fi

    等。 AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。 从开始学习小安
    的头像 发表于 01-16 09:47 765次阅读
    <b class='flag-5'>零基</b>础<b class='flag-5'>开发</b><b class='flag-5'>小安</b><b class='flag-5'>派</b>-<b class='flag-5'>Eyes-S1</b> 进阶<b class='flag-5'>篇</b> ——通过屏幕输入连接 Wi-Fi

    零基开发AiPi-Eyes-S1——通过屏幕输入连接Wi-Fi

    等。 AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。 从开始学习小安
    的头像 发表于 01-15 09:27 1017次阅读
    <b class='flag-5'>零基</b>础<b class='flag-5'>开发</b>AiPi-<b class='flag-5'>Eyes-S1</b>——通过屏幕输入连接Wi-Fi

    小安 DSL做一个天气站

    前言 小安-DSL(AiPi-DSL) 是安信可开源团队专门为Ai-M61-32S设计的一款屏幕驱动开发板,支持2.8/3.5寸等30Pin SPI显示屏、2.4寸及1.28寸等18
    的头像 发表于 01-06 16:44 891次阅读
    用<b class='flag-5'>小安</b><b class='flag-5'>派</b> DSL做一个天气站

    零基开发小安-Eyes-S1【进阶】——初识 LVGL 并搭建最小工程

    等。 AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。 从开始学习小安
    的头像 发表于 01-06 16:14 1361次阅读
    <b class='flag-5'>零基</b>础<b class='flag-5'>开发</b><b class='flag-5'>小安</b><b class='flag-5'>派</b>-<b class='flag-5'>Eyes-S1</b>【进阶<b class='flag-5'>篇</b>】——初识 LVGL 并搭建最小工程

    零基开发小安-Eyes-S1——初识LVGL并搭建最小工程

    等。 AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。 从开始学习小安
    的头像 发表于 01-03 14:09 1365次阅读

    使用小安DSL制作天气站

    小安 DSL做天气站 用户分享DIY   前言 小安-DSL(AiPi-DSL) 是安信可开源团队专门为Ai-M61-32S设计的一款
    的头像 发表于 01-03 11:18 863次阅读
    使用<b class='flag-5'>小安</b><b class='flag-5'>派</b>DSL制作天气站

    零基开发小安-Eyes-S1 外设——DAC

    等。 AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。 从开始学习小安
    的头像 发表于 12-27 10:55 1622次阅读
    <b class='flag-5'>零基</b>础<b class='flag-5'>开发</b><b class='flag-5'>小安</b><b class='flag-5'>派</b>-<b class='flag-5'>Eyes-S1</b> <b class='flag-5'>外设</b><b class='flag-5'>篇</b>——DAC