问题描述
RT-Thread 提供的 ADC 设备管理接口来访问 ADC 硬件,
【1】可以直接通过 rt-thread/src/device.c提供的以下相关接口实现。
rt_device_find() | 根据 ADC 设备名称查找设备获取设备句柄 |
rt_adc_enable() | 使能 ADC 设备 |
rt_adc_read() | 读取 ADC 设备数据 |
rt_adc_disable() | 关闭 ADC 设备 |
【2】 可以通过 stm32cubemx生成的源码board/src/main.c以及libraries/../Inc/stm32l4xx_hal_adc.h、libraries/../Src/stm32l4xx_hal_adc.c提供的HAL_ADC_Start、HAL_ADC_Stop等相关接口实现。
案例实现:
一、前期配置
【1】stm32cubemx配置板卡
完成配置,生成代码 。
【2】开启ADC驱动支持,工程目录启动RT-Thread的EVN工具命令窗口,启动menuconfig命令完成配置。
或者,采用RT-Thread Studio的rt-thread settings的开启ADC驱动支持。
【3】在board/../Inc/stm32l4xx_hal_conf.h文件中取消ADC宏定义的注销,启用ADC模块
#define HAL_ADC_MODULE_ENABLED
二、代码实现
【1】方法一
1)将stm32cubemx生成的源码文件board\CubeMX_Config\Src\main.c文件中的static void MX_ADC1_Init(void)函数定义拷贝到自行编译源码中,实现ADC初始化。代码案例如下:
#include <rtthread.h>
#include "board.h"
#include "stm32l4xx_hal_adc.h"
ADC_HandleTypeDef hadc1;
/* ADC1 初始化函数 */
void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;//第3通道
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
rt_uint32_t get_adc_value(void)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);
return (rt_uint32_t)HAL_ADC_GetValue(&hadc1);
}
/*线程函数*/
void adc_entry(void *parameter)
{
int count = 1;
rt_uint32_t read_value = 0;
MX_ADC1_Init();
while ((count++)<10)
{
read_value = get_adc_value();
rt_thread_mdelay(1000);
rt_kprintf("adc value = %d\r\n", read_value);
}
}
/* 创建线程 */
int adc_sample(void)
{
rt_thread_t tid; //线程句柄
tid = rt_thread_create("adc_sample",
adc_entry,
RT_NULL,
512,
9,
10);
if(tid != RT_NULL)
{
//线程创建成功,启动线程
rt_thread_startup(tid);
}
return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_sample, adc test example);
【2】方法二,采用device.c的IO设备访问接口实现,先开启ADC1宏定义
可以在rtconfig.h或board.h头文件中添加宏定义:#define BSP_USING_ADC1
示例代码如下:
#include <rtthread.h>
#include "board.h"
rt_adc_device_t dev;
void adc1_entry(void *parameter)
{
int count = 0;
rt_uint32_t read_value = 0;
while((count++)<10)
{
read_value = rt_adc_read(dev, 5);
rt_kprintf("adc value = %d\r\n", read_value);
rt_thread_mdelay(1000);
}
}
/* 创建线程 */
int adc_sample1(void)
{
dev = (rt_adc_device_t)rt_device_find("adc1");
if(RT_NULL==dev)
{
rt_kprintf("rt_device_find adc1 failed!\n");
return RT_ERROR;
}
rt_err_t ret = rt_adc_enable(dev, 5);//第5通道
if(ret<0)
{
rt_kprintf("rt_adc_enable adc1 failed!\n");
}
rt_thread_t tid; //线程句柄
tid = rt_thread_create("adc_sample1",
adc1_entry,
RT_NULL,
512,
9,
10);
if(tid != RT_NULL)
{
//线程创建成功,启动线程
rt_thread_startup(tid);
}
return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(adc_sample1, adc test example);
三、编译及测试
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)