1、开发环境

RT_Thread Studio 开发编译软件

RT_Thread latest 版本

2、代码配置

2.1 打开stm32f1xx_hal_conf.h中的HAL_ADC_MODULE_ENABLED宏定义注释

#define HAL_ADC_MODULE_ENABLED

2.2 ADC驱动源代码drv_adc.c (基于RT_Thread系统)

#include <rthw.h>
#include <rtdevice.h>
#include <rtthread.h>
#include <board.h>

#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
#include "adc_config.h"

//#define DRV_DEBUG
#define LOG_TAG             "drv.adc"
#include <at_log.h>

static ADC_HandleTypeDef adc_config[] =
{
#ifdef BSP_USING_ADC1
    ADC1_CONFIG,
#endif

#ifdef BSP_USING_ADC2
    ADC2_CONFIG,
#endif

#ifdef BSP_USING_ADC3
    ADC3_CONFIG,
#endif
};

struct stm32_adc
{
    ADC_HandleTypeDef ADC_Handler;
    struct rt_adc_device stm32_adc_device;
};

static struct stm32_adc stm32_adc_obj[sizeof(adc_config) / sizeof(adc_config[0])];

static rt_err_t stm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
{
    ADC_HandleTypeDef *stm32_adc_handler = device->parent.user_data;

RT_ASSERT(device != RT_NULL);

if (enabled)
    {
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
        ADC_Enable(stm32_adc_handler);
#else
        __HAL_ADC_ENABLE(stm32_adc_handler);
#endif
    }
    else
    {
#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
        ADC_Disable(stm32_adc_handler);
#else
        __HAL_ADC_DISABLE(stm32_adc_handler);
#endif
    }

return RT_EOK;
}

static rt_uint32_t stm32_adc_get_channel(rt_uint32_t channel)
{
    rt_uint32_t stm32_channel = 0;

switch (channel)
    {
    case  0:
        stm32_channel = ADC_CHANNEL_0;
        break;
    case  1:
        stm32_channel = ADC_CHANNEL_1;
        break;
    case  2:
        stm32_channel = ADC_CHANNEL_2;
        break;
    case  3:
        stm32_channel = ADC_CHANNEL_3;
        break;
    case  4:
        stm32_channel = ADC_CHANNEL_4;
        break;
    case  5:
        stm32_channel = ADC_CHANNEL_5;
        break;
    case  6:
        stm32_channel = ADC_CHANNEL_6;
        break;
    case  7:
        stm32_channel = ADC_CHANNEL_7;
        break;
    case  8:
        stm32_channel = ADC_CHANNEL_8;
        break;
    case  9:
        stm32_channel = ADC_CHANNEL_9;
        break;
    case 10:
        stm32_channel = ADC_CHANNEL_10;
        break;
    case 11:
        stm32_channel = ADC_CHANNEL_11;
        break;
    case 12:
        stm32_channel = ADC_CHANNEL_12;
        break;
    case 13:
        stm32_channel = ADC_CHANNEL_13;
        break;
    case 14:
        stm32_channel = ADC_CHANNEL_14;
        break;
    case 15:
        stm32_channel = ADC_CHANNEL_15;
        break;
    case 16:
        stm32_channel = ADC_CHANNEL_16;
        break;
    case 17:
        stm32_channel = ADC_CHANNEL_17;
        break;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4)
    case 18:
        stm32_channel = ADC_CHANNEL_18;
        break;
#endif
    }

return stm32_channel;
}

static rt_err_t stm32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
    ADC_ChannelConfTypeDef ADC_ChanConf;
    ADC_HandleTypeDef *stm32_adc_handler = device->parent.user_data;

RT_ASSERT(device != RT_NULL);
    RT_ASSERT(value != RT_NULL);

rt_memset(&ADC_ChanConf, 0, sizeof(ADC_ChanConf));

#if defined(SOC_SERIES_STM32F1)
    if (channel <= 17)
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \
        || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
    if (channel <= 18)
#endif
    {
        /* set stm32 ADC channel */
        ADC_ChanConf.Channel =  stm32_adc_get_channel(channel);
    }
    else
    {
#if defined(SOC_SERIES_STM32F1)
        LOG_E("ADC channel must be between 0 and 17.");
#elif defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) \
        || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32G0)
        LOG_E("ADC channel must be between 0 and 18.");
#endif
        return -RT_ERROR;
    }
    ADC_ChanConf.Rank = 1;
#if defined(SOC_SERIES_STM32F0)
    ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
#elif defined(SOC_SERIES_STM32F1)
    ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
    ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_112CYCLES;
#elif defined(SOC_SERIES_STM32L4)
    ADC_ChanConf.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
#endif
#if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4)
    ADC_ChanConf.Offset = 0;
#endif
#ifdef SOC_SERIES_STM32L4
    ADC_ChanConf.OffsetNumber = ADC_OFFSET_NONE;
    ADC_ChanConf.SingleDiff = LL_ADC_SINGLE_ENDED;
#endif
    HAL_ADC_ConfigChannel(stm32_adc_handler, &ADC_ChanConf);

/* start ADC */
    HAL_ADC_Start(stm32_adc_handler);

/* Wait for the ADC to convert */
    HAL_ADC_PollForConversion(stm32_adc_handler, 100);

/* get ADC value */
    *value = (rt_uint32_t)HAL_ADC_GetValue(stm32_adc_handler);

return RT_EOK;
}

static const struct rt_adc_ops stm_adc_ops =
{
    .enabled = stm32_adc_enabled,
    .convert = stm32_get_adc_value,
};

void MX_ADC_Init(void)
{
    RCC_PeriphCLKInitTypeDef ADC_CLKInit;
    ADC_CLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;            //ADC外设时钟
    ADC_CLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;            //分频因子6时钟为72M/6=12MHz
    HAL_RCCEx_PeriphCLKConfig(&ADC_CLKInit);                    //设置ADC时钟
    __HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟
}

int stm32_adc_init(void)
{
    int result = RT_EOK;
    /* save adc name */
    char name_buf[5] = {'a', 'd', 'c', '0', 0};
    int i = 0;

for (i = 0; i < sizeof(adc_config) / sizeof(adc_config[0]); i++)
    {
        /* ADC init */
        name_buf[3] = '0';
        stm32_adc_obj[i].ADC_Handler = adc_config[i];
#if defined(ADC1)
        if (stm32_adc_obj[i].ADC_Handler.Instance == ADC1)
        {
            name_buf[3] = '1';
        }
#endif
#if defined(ADC2)
        if (stm32_adc_obj[i].ADC_Handler.Instance == ADC2)
        {
            name_buf[3] = '2';
        }
#endif
#if defined(ADC3)
        if (stm32_adc_obj[i].ADC_Handler.Instance == ADC3)
        {
            name_buf[3] = '3';
        }
#endif
        MX_ADC_Init();

if (HAL_ADC_Init(&stm32_adc_obj[i].ADC_Handler) != HAL_OK)
        {
            LOG_E("%s init failed", name_buf);
            result = -RT_ERROR;
        }
        else
        {
            /* register ADC device */
            if (rt_hw_adc_register(&stm32_adc_obj[i].stm32_adc_device, name_buf, &stm_adc_ops, &stm32_adc_obj[i].ADC_Handler) == RT_EOK)
            {
                LOG_D("%s init success", name_buf);
              
            }
            else
            {
                LOG_E("%s register failed", name_buf);
              
                result = -RT_ERROR;
            }
        }
    }

return result;
}

INIT_APP_EXPORT(stm32_adc_init);

#endif /* BSP_USING_ADC */

2.3 ADC的HAL库源代码drv_adc_hal.c

(注:HAL库源代码,不限制RT_Thread嵌入式实时操作系统)

#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "board.h"

#define DBG_TAG "drv_adc_hal"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

ADC_HandleTypeDef hadc1;

int MX_ADC1_Init(void)
{

/* USER CODE BEGIN ADC1_Init 0 */

RCC_PeriphCLKInitTypeDef ADC_CLKInit;
    ADC_CLKInit.PeriphClockSelection=RCC_PERIPHCLK_ADC;            //ADC外设时钟
    ADC_CLKInit.AdcClockSelection=RCC_ADCPCLK2_DIV6;            //分频因子6时钟为72M/6=12MHz
    HAL_RCCEx_PeriphCLKConfig(&ADC_CLKInit);                    //设置ADC时钟

__HAL_RCC_ADC1_CLK_ENABLE();            //使能ADC1时钟

hadc1.Instance=ADC1;
    hadc1.Init.DataAlign=ADC_DATAALIGN_RIGHT;             //右对齐
    hadc1.Init.ScanConvMode=DISABLE;                      //不扫描模式
    hadc1.Init.ContinuousConvMode=DISABLE;                //不连续转换
    hadc1.Init.NbrOfConversion=1;                         //一个规则通道转换
    hadc1.Init.DiscontinuousConvMode=DISABLE;             //禁止不连续采样模式
    hadc1.Init.NbrOfDiscConversion=0;                     //不连续采样通道数为0
    hadc1.Init.ExternalTrigConv=ADC_SOFTWARE_START;       //软件触发
    HAL_ADC_Init(&hadc1);                                 //初始化

HAL_ADCEx_Calibration_Start(&hadc1);                     //校准ADC

GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_GPIOB_CLK_ENABLE();            //开启GPIOB时钟
    GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_0;            //PA1和PA0
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     //模拟输入
    GPIO_Initure.Pull=GPIO_NOPULL;          //不带上下拉
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);

return 0;
}

static rt_uint32_t adc_get_channel(rt_uint32_t channel)
{
    rt_uint32_t stm32_channel = 0;

switch (channel)
    {
    case  0:
        stm32_channel = ADC_CHANNEL_0;
        break;
    case  1:
        stm32_channel = ADC_CHANNEL_1;
        break;
    case  2:
        stm32_channel = ADC_CHANNEL_2;
        break;
    case  3:
        stm32_channel = ADC_CHANNEL_3;
        break;
    case  4:
        stm32_channel = ADC_CHANNEL_4;
        break;
    case  5:
        stm32_channel = ADC_CHANNEL_5;
        break;
    case  6:
        stm32_channel = ADC_CHANNEL_6;
        break;
    case  7:
        stm32_channel = ADC_CHANNEL_7;
        break;
    case  8:
        stm32_channel = ADC_CHANNEL_8;
        break;
    case  9:
        stm32_channel = ADC_CHANNEL_9;
        break;
    case 10:
        stm32_channel = ADC_CHANNEL_10;
        break;
    case 11:
        stm32_channel = ADC_CHANNEL_11;
        break;
    case 12:
        stm32_channel = ADC_CHANNEL_12;
        break;
    case 13:
        stm32_channel = ADC_CHANNEL_13;
        break;
    case 14:
        stm32_channel = ADC_CHANNEL_14;
        break;
    case 15:
        stm32_channel = ADC_CHANNEL_15;
        break;
    case 16:
        stm32_channel = ADC_CHANNEL_16;
        break;
    case 17:
        stm32_channel = ADC_CHANNEL_17;
        break;
#if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4)
    case 18:
        stm32_channel = ADC_CHANNEL_18;
        break;
#endif
    }

return stm32_channel;
}

rt_uint32_t get_adc_value(rt_uint8_t channel)
{
    ADC_ChannelConfTypeDef ADC1_ChanConf;
    ADC1_ChanConf.Channel= adc_get_channel(channel);                       //通道
    ADC1_ChanConf.Rank=1;                                       //第1个序列,序列1
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_55CYCLES_5;      //采样时间
    HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf);        //通道配置
    HAL_ADC_Start(&hadc1);                               //开启ADC
    HAL_ADC_PollForConversion(&hadc1, 10);

return (rt_uint32_t)HAL_ADC_GetValue(&hadc1);
}

基于 RT_Thread 的ADC驱动源代码 drv_adc.c相关推荐

  1. s3c2410多通道adc驱动及测试程序

    网上流行很多基于2410的ADC驱动及测试程序.本文所使用的是开发板光盘中带有了经过修改后的adc驱动.笔者在这个基础上再作一点修改.由于那个文件已经删除了版权信息,这里也不知道如何添加了,可以肯定的 ...

  2. MG995舵机工作原理及基于STM32的驱动源代码

    MG995舵机工作原理及基于STM32的驱动源代码 一·MG995舵机工作原理 1.MG995舵机简介 产品型号 MG995 产品尺寸 40.7*19.7*42.9mm 产品重量 55g 工作扭矩 1 ...

  3. 基于HI3516/HI3518/HI3559内部ADC驱动实现

    提示:除了以上三种SOC,海思HI35XX其他SOC实现流程也应该类似,本篇文章以HI3516为主体进行实现. 文章目录 前言 一.相关资料 二.实现原理及步骤 1.原理 2.步骤 三.代码实现 前言 ...

  4. 基于linux的驱动设计,《基于LINUX的虚拟驱动设计》-毕业论文.doc

    PAGE 40 l 摘 要 驱动程序是当前最热门.最有发展前途的IT应用技术之一.目前的驱动程序的开发主要应用在包括键盘 .鼠标.扫描仪.打印机以及存储设备等日益普及的设备之间的通讯上.但是要使这些设 ...

  5. USB学习5---android usb驱动源代码目录说明

    kernel\msm-3.18\drivers\usb下目录内容 我们msm8937+android7.1平台编译out目录下usb目录下有编译到的目录如下: 我们先参考kernel\msm-3.18 ...

  6. 基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ

    基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ 0. 导语 学习进入到了下一个阶段,还是以AD9833为例,这次学习是向设备申请中断,实现触发,在未来很多场景,比如做用 ...

  7. 基于MTD的NAND驱动开发(二)

    基于MTD的NAND驱动开发(二) 基于MTD的NAND驱动开发(三) http://blog.csdn.net/leibniz_zsu/article/details/4977853 http:// ...

  8. ServerSuperIO Designer IDE 发布,打造物联网通讯大脑,随心而联。附:C#驱动源代码。

    1.概况 注:ServerSuperIO Designer IDE 同行业网友随便使用,不涉及到软件使用限制的问题. 从2015年到现在的将近两年的时间,一直在开发.完善ServerSuperIO(S ...

  9. 基于Linux操作系统的底层驱动技术

    5.3 基于Linux操作系统的底层驱动技术 这里的底层驱动是指Linux下的底层设备驱动,这些驱动通常都是加载在内核态的,可以提供给上层用户态的应用程序访问底层设备的能力.也就是说,上层应用程序通过 ...

最新文章

  1. opencv otsu二值化
  2. java代码编译之后是如何运行的?不知道这些,面试官问你jvm问题,你只能懵圈
  3. 边缘计算、区块链、5G,哪个能走的更远
  4. 企业架构规划及服务器优化参数
  5. C#.NET 消息机制
  6. win7卡在正在启动windows界面_win7开机一直卡在欢迎界面如何解决?
  7. linux如何卸载telnet命令,linux安装telnet命令
  8. 21年最新-李沐-动手学深度学习第二版
  9. AD18单位mm和mil切换
  10. Flink大声说,丢数据这个锅,我们不背!
  11. 某蒟蒻无聊竟用UNO做了个复读机?
  12. 【读书摘录】《沉默的大多数》(王小波)
  13. linux git版本更新
  14. 扫码支付 (基于微信)
  15. Filter过滤器基本内容
  16. 中国音乐史记•黄家驹列传
  17. MacBook Air老本重装系统
  18. 关于二分查找及其上下界问题的一些思考
  19. Linux实战技巧--文件系统操作(一)--文件查看(pwd/ls/cd)
  20. python中的方法

热门文章

  1. mysql linq any查询_LINQ标准查询操作符详解(转)
  2. Angular 小专题:玩转注射器
  3. ArcgisDestop提示修复许可问题解决
  4. K-均值聚类算法的原理与实现
  5. 昨夜无眠 转自科学网程代展博文] (2012-11-13 21:09:13)
  6. linux电脑声音手机播放,如何将电脑声音用手机扬声器播放?
  7. 使用iperf进行局域网内测速
  8. 交流电、交流信号、直流电、直流信号
  9. 上海物联网共享实验室揭牌
  10. arcgis js平滑线工具_ArcGIS For JavaScript API Drawing Tool —— 绘图工具