安信可小安派【Analog to digital】 ADC 基于AI-M6x

发布时间 2023-10-24 19:14:50作者: 站在山顶的人
今天来分享一下我的ADC学习心得,首先说明当前的教程适用于所有的搭载AI-m61或者m62芯片的小安派。

需要的库文件如
库文件 说明
bflb_adc.h ADC功能
log.h 用来打印日志
bflb_gpio.h 初始化GPIO
bflb_mtimer.h 延时
board.h 初始化系统

重要的方法如下:



/**
* @brief 初始化GPIO端口作为analog
*
* @param [in] dev device handle
* @param [in] pin gpio pin, use @ref GPIO_PIN
* @param [in] cfgset gpio config mask
*/
void bflb_gpio_init(struct bflb_device_s *dev, uint8_t pin, uint32_t cfgset);


/**
* @brief 初始化ADC功能
*
* @param [in] ADC外设
* @param [in] ADC 配置结构体
*/
void bflb_adc_init(struct bflb_device_s *dev, const struct bflb_adc_config_s *config);



/**
* @brief ADC配置结构体
*
* @param clk_div                adc时钟频率是否分频,频率越高精度越差,相反精度越高
* @param scan_conv_mode         ADC scan mode enable, ADC扫描模式,我不清楚干什么用的
* @param continuous_conv_mode   ADC continuous conversion enable ,Adc持续转换,不清楚干嘛额
* @param differential_mode      ADC differential mode enable , adc 差异区分模式, 不清楚干嘛的
* @param resolution             ADC resolution, use @ref ADC_RESOLUTION  adc转换精度
* @param vref                   ADC reference select, use @ref ADC_VREF  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;
};



/**
* @brief 绑定ADC和对用的通道
*
* @param [in] dev device handle
* @param [in] 所有的通道
* @param [in] 你所要使用的通道
* @return Zero on success; a negated errno value on failure
*/
int bflb_adc_channel_config(struct bflb_device_s *dev, struct bflb_adc_channel_s *chan, uint8_t channels);


这里定义的是所有的ADC通道,我这里只定义了 0 通道,就是gpio20
struct bflb_adc_channel_s chan[] = {
#if TEST_ADC_CHANNEL_0
    {.pos_chan = ADC_CHANNEL_0,
     .neg_chan = ADC_CHANNEL_GND},
#endif
};



/**
* @brief 开始转换ADC
*
* @param [in] dev device handle
*/
void bflb_adc_start_conversion(struct bflb_device_s *dev);



/**
* @brief 获取ADC转换结果
*
* @param [in] dev device handle
* @return conversion value
*/
uint32_t bflb_adc_read_raw(struct bflb_device_s *dev);



/**
* @brief 结束转换ADC
*
* @param [in] dev device handle
*/
void bflb_adc_stop_conversion(struct bflb_device_s *dev);


/**
* @brief 解析raw adc转换结果到毫伏, 以数字形式展示
*
* @param [in] dev device handle
@param [inbflb_adc_read_raw 方法转换的结果
* @param [out] result pointer to save parse result, 转换后保存的结果,需要自己定义
* @param [in] count count to parse。 不清楚干什么用的 传递0 即可
*/
void bflb_adc_parse_result(struct bflb_device_s *dev, uint32_t *buffer, struct bflb_adc_result_s *result, uint16_t count);

#include "bflb_mtimer.h"
#include "board.h"
#include "bflb_adc.h"
#define DBG_TAG "MAIN"
#include "log.h"
#include "bflb_gpio.h"

struct bflb_device_s *adc;
struct bflb_device_s *gpio;

#define TEST_ADC_CHANNEL_0 0

// 定义所有的adc通道
struct bflb_adc_channel_s chan[] = {
#if TEST_ADC_CHANNEL_0
    {.pos_chan = ADC_CHANNEL_0,
     .neg_chan = ADC_CHANNEL_GND},
#endif
};

int main(void)
{
    board_init();

    gpio = bflb_device_get_by_name("gpio");
    // 初始化IO 20 作为 analog
    bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
    adc = bflb_device_get_by_name("adc");
    // 原始转换数据
    volatile uint32_t raw_data;
    // adc 配置
    struct bflb_adc_config_s cfg;
    // 始终分频, 分频约低速度越快,精度越低。 当前为最高分频,速度最快精度最低
    cfg.clk_div = ADC_CLK_DIV_32;

    // 剩下这三个参数没有搞明白实际作用
    cfg.scan_conv_mode = true;
    cfg.continuous_conv_mode = false;
    cfg.differential_mode = false;
    // 设置adc精度
    cfg.resolution = ADC_RESOLUTION_16B;
    // adc参考电压
    cfg.vref = ADC_VREF_3P2V;
    // 初始化ADC
    bflb_adc_init(adc, &cfg);
    // 绑定ADC通道
    bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNEL_0);

    while (1)
    {
        // 转换
        bflb_adc_start_conversion(adc);
        // 结束转换
        bflb_adc_stop_conversion(adc);
        //获取原生转换结果
        raw_data = bflb_adc_read_raw(adc);
        struct bflb_adc_result_s result;
        printf("raw data:%08x\r\n", raw_data);
        //解析raw 转换结果
        bflb_adc_parse_result(adc, (uint32_t *)&raw_data, &result, 1);
        printf("postive values is %d, negative is : %d  mv is %d \r\n", result.pos_chan, result.neg_chan, result.millivolt);
        //适当的延时
        bflb_mtimer_delay_ms(20);
    }
}

  转换结果如下: