使用RT-Thread studio IDE开发stm32F407(实现adc多通道采集)

本文介绍了如何使用IDE快捷配置RT-Thread项目,特别是针对STM32的ADC设置。通过选择芯片,启用ADC框架,利用CubMX配置时钟和外设,然后移植生成的初始化代码到工程中,创建线程进行ADC采样。最后展示了编译、下载和测试过程。
摘要由CSDN通过智能技术生成

注意:使用这个IDE配置工程特别简单( only   10  minutes )

step1:选择对应的芯片或开发板创建RT-Thread项目

 step2:配置RT-Thread Settings(按我的步骤顺序进行)

由于要用到ADC,所以我们使能这个框架,直接把它选上就ok

是不是特别简单?接下来第三步,要难一点了

step3

注意:这一步要配置cubmx(配置与stm32时钟,外设相关的东西,其实借助cubmx图形化配置工具这一步也变得十分简单)

ok,按下面的顺序来

 

 

 

 

然后把串口收发的引脚配置一下(是个人应该都会)

 

 接下来是时钟,只需要在下图两个位置输入数字然后enter,系统会自动帮你计算分频系数

 

最后一步,生成代码就可以直接关闭cubmx了,返回studio

 

 step3:以上准备工作做完了(实际操作起来很快的,你这是不熟悉而已),下面就可以愉快的码代码了,不多废物,直接看图

在编写主函数之前,先改一下工程(相当于移植工程),我们之前在配置好cubmx之后,会在studio 里面的cubmx文件夹生成相应的初始化代码,我们只需移植即可食用。

将cubmx->src->msp.下的这两个函数剪切到divers->board.c里面(最好放在最下面)

 

 

 然后在cubmx->conf.h里面把adc的这个使能注释可去掉(一般是已经帮你弄好了的,不过最好还是看一眼)

 最后一步将drivers->board.h下的BSP USING ADC注释取消掉(看你用哪一个或者是那几个adc)

然后就是main.c部分(开始编写业务逻辑代码)


#include <rtthread.h>
#include <rtdbg.h>
#include <board.h>
#include <rtdevice.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#define ADC_DEV_NAME        "adc1"      /* ADC 设备名称 */
#define REFER_VOLTAGE       330         /* 参考电压 3.3V,数据精度乘以100保留2位小数*/
#define CONVERT_BITS        (1 << 12)   /* 转换位数为12位 */

rt_thread_t Adc_thread1= RT_NULL;
rt_thread_t Adc_thread2= RT_NULL;
static void Adc_entry(void* paremeter);

int main(void)
{   /*创建第一个线程,用于采集IN8的值*/
    Adc_thread1 = rt_thread_create("adc1",
            Adc_entry,
            (void*)8,
            512,
            16,
            20);
    if(Adc_thread1 != RT_NULL)
        rt_thread_startup(Adc_thread1);
    else
        return -1;
    /*创建第二个线程,用于采集IN9的值*/
    Adc_thread2= rt_thread_create("adc1",
                Adc_entry,
               (void*)9,
                512,
                16,
                20);
        if(Adc_thread2 != RT_NULL)
            rt_thread_startup(Adc_thread2);
        else
            return -1;
}

static void Adc_entry(void* paremeter)
{
    rt_adc_device_t adc_dev;
    rt_uint32_t value,vol;
    rt_err_t ret = RT_NULL;
    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
    }
    /* 使能设备 */
    ret = rt_adc_enable(adc_dev, paremeter);
    while(1)
    {
        /* 读取采样值 */
        value = rt_adc_read(adc_dev,paremeter);
        /* 转换为对应电压值 */
        vol = value * REFER_VOLTAGE / CONVERT_BITS;
        rt_kprintf("the  ch%d value is :%d.%02d \n", paremeter,vol/ 100, vol % 100);
        rt_thread_delay(500);
    }
}



 最后编译,下载,烧录注入灵魂(我用的是ST-LINK)

 编译是这个小锤子(没有问题)

 

 

 这是测试结果,接3.3和gnd都没有问题,chl8我接的压力传感器,没有动它就默认高电阻3.3v,存在少许漂移现象和工频干扰。(后续可以加入DMA和滤波算法)

1. 配置开发环境 首先需要下载安装RT-Thread StudioSTM32CubeMX两个软件,并且安装好STM32F407芯片的支持包。 2. 创建工程 在RT-Thread Studio中创建一个新的RT-Thread工程,并选择STM32F407芯片作为目标平台。接着在工程配置界面中选择“生成Makefile”选项,并保存工程。 3. 配置STM32CubeMX 打开STM32CubeMX软件,选择STM32F407芯片,并进行以下配置: (1)配置时钟:根据实际需求设置时钟频率和分频系数。 (2)配置ADC:选择多通道模式,设置采样通道和采样时间。 (3)配置DMA:将ADC数据通过DMA传输到内存中。 (4)生成代码:在“Project Manager”界面中点击“Generate Code”按钮生成代码并保存。 4. 编写应用程序 在RT-Thread Studio中打开生成的工程,在应用程序中编写代码,实现多通道ADC采集功能。以下是示例代码: #include <rtthread.h> #include "stm32f4xx_hal.h" #define ADC_BUFFER_SIZE 10 static ADC_HandleTypeDef hadc1; static DMA_HandleTypeDef hdma_adc1; static uint16_t adc_buffer[ADC_BUFFER_SIZE]; static void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ENABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 2; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = 2; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } } static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA interrupt init */ /* DMA2_Stream0_IRQn interrupt configuration */ HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(adcHandle->Instance==ADC1) { /* USER CODE BEGIN ADC1_MspInit 0 */ /* USER CODE END ADC1_MspInit 0 */ /* ADC1 clock enable */ __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**ADC1 GPIO Configuration PA0-WKUP ------> ADC1_IN0 PA1 ------> ADC1_IN1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* ADC1 DMA Init */ /* ADC1 Init */ hdma_adc1.Instance = DMA2_Stream0; hdma_adc1.Init.Channel = DMA_CHANNEL_0; hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc1.Init.Mode = DMA_CIRCULAR; hdma_adc1.Init.Priority = DMA_PRIORITY_LOW; hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1); } } void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) { if(adcHandle->Instance==ADC1) { /* USER CODE BEGIN ADC1_MspDeInit 0 */ /* USER CODE END ADC1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_ADC1_CLK_DISABLE(); /**ADC1 GPIO Configuration PA0-WKUP ------> ADC1_IN0 PA1 ------> ADC1_IN1 */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1); /* ADC1 DMA DeInit */ HAL_DMA_DeInit(adcHandle->DMA_Handle); } } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* USER CODE BEGIN HAL_ADC_ConvCpltCallback 0 */ /* USER CODE END HAL_ADC_ConvCpltCallback 0 */ /* DMA2_Stream0_IRQn interrupt user code */ /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */ /* USER CODE END DMA2_Stream0_IRQn 0 */ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15); /* USER CODE BEGIN HAL_ADC_ConvCpltCallback 1 */ /* USER CODE END HAL_ADC_ConvCpltCallback 1 */ } static void adc_thread_entry(void *parameter) { /* Configure ADC and DMA */ MX_ADC1_Init(); MX_DMA_Init(); /* Start ADC conversion */ HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_SIZE); while (1) { rt_thread_mdelay(100); } } int adc_init(void) { rt_thread_t thread = rt_thread_create("adc", adc_thread_entry, RT_NULL, 1024, 25, 5); if (thread != RT_NULL) { rt_thread_startup(thread); } return RT_EOK; } INIT_APP_EXPORT(adc_init); 5. 编译和下载 在RT-Thread Studio中编译工程,并将程序下载到STM32F407芯片中。启动程序后,就可以通过多通道ADC采集模拟信号。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值