说明:
这次先介绍下ADC设备的操作方法,然后一步一步完成ADC设备的BSP过程。
该BSP主要实现使用ADC设备管理接口
管理ADC采集电压信号
,其中硬件图下图:
应用程序通过RT-Thred提供的adc设备管理接口操作adc设备,相关函数接口如下表:
方法名称 | 方法描述 |
---|---|
rt_device_find() | 根据 ADC 设备名称查找设备获取设备句柄 |
rt_adc_enable() | 使能ADC设备 |
rt_adc_read() | 读取adc设备数据 |
rt_adc_disable() | 关闭adc设备 |
在使用adc设备之前需要先查找adc设备句柄,通过下面函数完成:
rt_device_t rt_device_find(const char* name);
参数 | 描述 |
---|---|
name | adc设备名字 |
返回 | 描述 |
设备句柄 | 无查找到正确的设备后返回对应的设备句柄 |
RT_NULL | 没有查找到设备 |
根据 rt-thread 设备注册格式,一般注册到设备块的 adc 设备名字为adc0
、adc1
等等。
跟我们前面使用pin设备一样,具体操作之前都得先使能,使能adc设备用如下函数完成:
rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel);
参数 | 描述 |
---|---|
dev | ADC设备句柄 |
channel | ADC设备所使用的通道 |
返回 | 描述 |
RT_EOK | 使能成功 |
-RT_ENOSYS | 使能失败,设备操作方法为空 |
其他值 | 使能失败 |
读取adc设备通道值使用如下函数完成:
rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_uint32_t channel);
参数 | 描述 |
---|---|
dev | ADC设备句柄 |
channel | ADC设备所使用的通道 |
返回 | 描述 |
读取到的值 | ADC设备通道读取到值 |
如果不再使用adc设备,则可以关闭adc设备,关闭adc设备用如下函数完成:
rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel);
参数 | 描述 |
---|---|
dev | ADC设备句柄 |
channel | ADC设备所使用的通道 |
返回 | 描述 |
RT_EOK | 关闭成功 |
-RT_ENOSYS | 关闭失败,设备操作方法为空 |
其他值 | 关闭失败 |
说明: 关闭之后可再次打开,也可再次关闭。即可以多次打开、关闭。一般我们如果非特殊要求,可以在FinSH终端来进行操作,随时打开或者关闭adc设备,所有支持的指令请看adc设备驱动的源码,已导出至FinSH终端。
下面介绍几种adc设备通过FinSH终端操作的指令:
adc probe adcx
,其中adcx
为注册adc设备的名字,如adc0
,adc1
,adc2
等。adc probe adc1 /* 查看名字为adc1的adc设备是否存在 */
adc enable channel
,其中channel为adc设备所在的通道号。adc enable 13 /* 使能通道13的adc设备 */
adc read channel
,其中channel为adc设备所在的通道号。adc read 13 /* 读取通道13的adc设备的数据 */
adc disable channel
,其中channel为adc设备所在的通道号。adc disable 13 /* 关闭通道13的adc设备 */
在前面的rt-thread:_001STM32F429IGT BSP前期准备过程中,我们建立模版,模版中已经通过STM32CubeMX
默认完成了GPIO设备
和UART设备
所对应的外设及引脚配置。,所以在rt-thread:_002STM32F429IGT BSP的PIN设备应用里面我们都是直接用GPIO设备
去管理led
和key
。
但是这次的adc设备
的bsp,就需要使用STM32CubeMX
先开启ADC外设
,才能再通过adc设备驱动去操作完成应用功能。
下面开始ADC设备的BSP:
打开stm32f429-hlg-v1.0\board\CubeMX_Config
下面的CubeMX_Config.ioc
工程,依次配置如下图所示:
注意: 一定要点击序号3
生成代码,不然配置没起作用。
这样adc外设片上外设就配置好了。
这下步骤又跟rt-thread:_002STM32F429IGT BSP的PIN设备应用基本一样了,也是在模板rt-thread:_001STM32F429IGT BSP前期准备的基础上加入新的bsp应用程序即可。
首先新建两个文件bsp_adc.c
和bsp_adc.h
;然后把bsp_adc.c
放入bsp_src
文件夹里,bsp_adc.h
放入bsp_inc
文件夹里。同时在
main.h
里面添加bsp_adc的头文件,如下:
#include "bsp_inc/bsp_adc.h"
其中bsp_adc.h
里面的代码如下:
#ifndef __BSP_ADC_H
#define __BSP_ADC_H
#include "applications/main.h"
#define ADC_DEV_NAME "adc1" /* 定义adc设备的名字 */
#define ADC_DEV_CHANNEL 13 /* 定义adc设备的通道 */
#define REFER_VOLTAGE 330 /* 定义adc设备的参考电压,比真实的硬件电压扩大了十倍,方便计算处理 */
#define CONVERT_BITS (1 << 12) /* 定义adc设备的转换精度 */
#define BSP_ADC_PRIORITY 9 /* 定义bsp_key线程的优先级 */
/* 声明函数 */
static void bsp_adc_thread_entry(void *parameter);
static void bsp_adc_sample(int arc, char *argv[]);
#endif
其中bsp_adc.c
里面的代码如下:
#include "bsp_adc.h"
/* 定义adc设备控制块 */
static rt_adc_device_t bsp_adc_dev = RT_NULL;
/***************************************************************
* 函数: static void bsp_adc_thread_entry(void *parameter)
* 参数: 空指针
* 返回值:无
* 功能: adc线程,实现adc设备通道数据读取、转换以及打印
*****************************************************************/
static void bsp_adc_thread_entry(void *parameter)
{
volatile rt_uint32_t adc_value = 0;
rt_uint32_t vol = 0;
while (1)
{
/* 隔10s读一次adc设备所在通道数据,并进行处理 */
rt_thread_mdelay(10000);
adc_value = rt_adc_read(bsp_adc_dev, ADC_DEV_CHANNEL);
rt_kprintf("the value is: %d\n", adc_value);
vol = adc_value * REFER_VOLTAGE / CONVERT_BITS;
rt_kprintf("the voltage is : %d.%02d\n", vol / 100, vol % 100);
}
}
/***************************************************************
* 函数: static void bsp_adc_sample(int arc, char *argv[])
* 参数: int argc, char *argv[]
* 返回值:无
* 功能: 查找adc设备、使能adc设备、创建并启动adc线程
*****************************************************************/
static void bsp_adc_sample(int arc, char *argv[])
{
static rt_thread_t bsp_adc_tid = RT_NULL;
bsp_adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
if (bsp_adc_dev != RT_NULL)
{
rt_kprintf("adc device fined!\n");
}
rt_adc_enable(bsp_adc_dev, ADC_DEV_CHANNEL);
bsp_adc_tid = rt_thread_create("bsp_adc_tid", bsp_adc_thread_entry, RT_NULL, 512, BSP_ADC_PRIORITY, 10);
if (bsp_adc_tid != RT_NULL)
{
rt_thread_startup(bsp_adc_tid);
}
}
/* 导出bsp_adc_sample命令至FinSH终端 */
MSH_CMD_EXPORT(bsp_adc_sample, bsp adc device sample);
打开stm32f429-hlg-v1.0\board
下面的Kconfig
文件,在该文件的 menu "BSP module"
配置模块下面添加如下图内容:
并在menu "On-chip Peripheral Drivers"
配置下面添加下图内容:
有了这两个宏,那么在env
工具里面就可以很方便的开启或者关闭该宏,如果开启该宏,则在rtconfig.h
里面就会生成该宏,同时keil工程
自动增加bsp_adc.c
文件。
打开stm32f429-hlg-v1.0\applications
下面的SConscript
编译链接脚本文件,在里面添加如下图内容:
在env
里输入menuconfig
打开工程配置,开启Enable adc
,如下图:
然后一直按Esc
至保存界面,选Yes
保存退出。
说明: 如果是先去开启ADC1 channel13
,然后再开启enable adc
,那么会发现enable adc
已经自动开启了。因为这两个使能项的配置宏都是RT_USING_ADC
。
在env
输入scons --target=mdk5
重新生成keil5
工程;输入scons --target=mdk4
重新生成keil4
工程;输入scons --target=iar
重新生成iar
工程;输入scons --target=vsc
更新VSCode
头文件路径。
打开keil5
工程,然后就可以看到现在的工程目录结构如下图:
然后编译之后看看是否有错误或者警告。只要前面步骤没有出错,这里肯定不会要问题。
下载程序到开发板。然后打开终端工具。在中断输入例程的导出命令bsp_adc_sample
,便可以看到采集的电压信息。
再输入查看线程指令list_thread
,便可以看到bsp_adc线程
的运行基本信息,如下图:
再输入查看设备指令list_device
,便可以看到adc设备
的挂载的基本信息,如下图:
到此,一个adc设备操作adc硬件,读取电压的bsp就彻底完成了。
该bsp同样是在rt-thread:_001STM32F429IGT BSP前期准备的基础上增加adc的bsp。再结合env工具,可以快速实现工程配置。
rt-thread:_001STM32F429IGT BSP前期准备
rt-thread:_002STM32F429IGT BSP的PIN设备应用
RT-Thread ADC设备管理-官网连接