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

审核编辑 黄宇

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

    关注

    463

    文章

    54417

    浏览量

    469210
  • adc
    adc
    +关注

    关注

    100

    文章

    7946

    浏览量

    556878
  • 模拟信号
    +关注

    关注

    8

    文章

    1236

    浏览量

    54792
  • 开源
    +关注

    关注

    3

    文章

    4344

    浏览量

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

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    零基础玩转Linux+Ubuntu实战视频课程

    ” -> 升华认知:抛弃鼠标的依赖,用“文件寻址”和“命令组合”的思维重塑对计算机的操控。 按这个框架去读,这篇看似晦涩枯燥的零基础长文,就会立刻化作你通往后端开发、运维部署、甚至极客高薪领域的“万能钥匙”。
    发表于 04-18 16:16

    2小时搞定鸿蒙应用!零基础做出你的鸿蒙“处女作”

    当下,低门槛开发正成为生态扩张的最强推力,而鸿蒙生态的快速壮大,也让越来越多零基础小白蠢蠢欲动,想加入开发大军。但繁琐的配置流程、深奥的代码,也让很多人打起了退堂鼓。近日,鸿蒙开发者官
    的头像 发表于 04-17 14:04 90次阅读
    2小时搞定鸿蒙应用!<b class='flag-5'>零基</b>础做出你的鸿蒙“处女作”

    ADC141S628-Q1 14 位微功耗汽车级 ADC 产品总结

    。信号路径由内部采样保持电路贯穿ADC保持,以提供卓越的共模噪声抑制。ADC141S628-Q1 采用功耗轨道模式,ADC 消耗最小的供电,内部采样电容跟踪施加的模拟输入电压。
    的头像 发表于 11-19 11:27 830次阅读
    <b class='flag-5'>ADC141S628-Q1</b> 14 位微功耗汽车级 <b class='flag-5'>ADC</b> 产品总结

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

    小安-Eyes-R2,但是一直没什么时间好好的研究一下。近期学习了一下相关例程,感觉用的很难受,大概是因为屏幕排线比较短且板子和屏幕不好固定,以及烧录两个按键必须要俩手按,于是考虑做外壳固定一下。  
    的头像 发表于 09-09 17:20 1010次阅读
    <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 913次阅读
    【开源硬件】<b class='flag-5'>小安</b><b class='flag-5'>派</b>AiPi-<b class='flag-5'>Eyes</b>-R2详细测评+DIY天气时钟

    上手体验安信可小安AI开发板,如何接入Home Assistant?

    以下作品由安信可社区用户 无垠的广袤 制作 感谢安信可社区的支持,免费领到了安信可的最新产品 小安AI - AiPi-PalChatV1 语音开发板。 原贴地址: 【AiPi-PalChatV
    的头像 发表于 07-08 10:34 4968次阅读
    上手体验安信可<b class='flag-5'>小安</b><b class='flag-5'>派</b>AI<b class='flag-5'>开发</b>板,如何接入Home Assistant?

    【教程】零基础!手把手教你使用STM32F4进行E22-400T22S编程通信

    通过本文带大家零基础使用STM32F407VET6单片机进行E22-400T22S模块编程并进行简单的通信,当然如果学会了,也可以举一反三应用于E22、E220、E32所有模块上。一STM32环境
    的头像 发表于 07-03 19:32 1812次阅读
    【教程】<b class='flag-5'>零基</b>础!手把手教你使用STM32F4进行E22-400T22<b class='flag-5'>S</b>编程通信

    零基础学习LuatOS编程:快速上手开发实战教程!

    无论你是刚接触物联网编程的新手,还是希望拓展技能的技术爱好者,本教程将为零基础的读者提供一条清晰的LuatOS学习路径。从安装开发工具到编写第一个程序,我们将通过实例讲解核心概念,助你快速实现从理论
    的头像 发表于 06-13 17:27 743次阅读
    <b class='flag-5'>零基</b>础学习LuatOS编程:快速上手<b class='flag-5'>开发</b>实战教程!

    树莓RP2350 - 桌面动态温湿度计

    )) utime.sleep(1) 保存代码,连接开发板,配置解释器并运行。 效果 终端打印 ADC 采集的电池电压值以及电量百分比 电量显示 OLED 显示 ADC 采集的电量
    发表于 05-26 02:02

    死角玩转STM32——系统

    本文共4册,由于资料内存过大,分开上传,有需要的朋友可以去主页搜索下载哦~ 《死角玩转 STM32》系列教程由初级、中级、高级、系统
    发表于 05-21 14:08

    死角玩转STM32——高级

    本文共4册,由于资料内存过大,分开上传,有需要的朋友可以去主页搜索下载哦~ 《死角玩转 STM32》系列教程由初级、中级、高级、系统
    发表于 05-21 14:02

    死角玩转STM32——中级

    ,从裸奔到系统,让您死角玩转 STM32。 目录内容: 1、调试必备-串口(USART1) 2、ADC(DMA 模式) 3、Temperature(芯片温度) 4、RTC(万年
    发表于 05-21 13:56

    死角玩转STM32——初级

    本文共4册,由于资料内存过大,分开上传,有需要的朋友可以去主页搜索下载哦~ 《死角玩转 STM32》系列教程由初级、中级、高级、系统
    发表于 05-21 13:48

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

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

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

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