首页 > 其他分享 >STM32CubeMX ADC+DMA

STM32CubeMX ADC+DMA

时间:2022-08-19 20:12:18浏览次数:89  
标签:DMA convert HAL STM32CubeMX ADC ADC1 ADC3

1. 选择使用的通道

 

 2. 参数配置 独立模式、数据右对齐、扫描转换(多通道默认配置)、连续扫描、使能常规转换组、6通道、软件触发、Rank单独配置,否则全部默认一样的,到时候采样值全是第一个通道的

 

 3.DMA

 

 

 

 F103板子12位AD,半字足够了。

同样的配置,配置了ADC3的3个通道。

4. 中断配置(看一眼,全局中断是否开启是否影响DMA中断,待测试(反正开启没问题))

 

 5.代码修改:在生成的代码中

main.c 初始化:

    HAL_ADCEx_Calibration_Start(&hadc1);//ADC校准
    HAL_UARTEx_ReceiveToIdle_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开DMA接收
    HAL_ADCEx_Calibration_Start(&hadc3);//ADC校准
    HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC1_convert,adc1_convert_num);

adc.h 添加:

#define adc1_convert_num 30  //ADC1转化数据量,,每转换30个数据 DMA进行一次数据转移
#define adc1_channel 6            //ADC1使用的通道数 6个
#define adc3_convert_num 9    //ADC3转化数据量,每转换9个数据 DMA进行一次数据转移
#define adc3_channel 3            //ADC3使用的通道数 6个

//extern uint32_t ADC1_convert[10][6];//转换数据缓存,定义60个,用了一半
extern uint16_t ADC1_convert[10][6];//转换数据缓存
//extern uint32_t ADC3_convert[6][3];//转换数据缓存,定义18个,只用了一半
extern uint16_t ADC3_convert[6][3];//转换数据缓存

adc.c 添加:

/* 对应CUbemx里DMA设置的转存数据位宽
** Word: uint32_t
** HalfWord: uint16_t, 在开启ADC_DMA时,只需强制转化地址指针,例如/
** HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC1_convert,24);
*/
//uint32_t ADC1_convert[10][6] = {0};//ADC1数据转存,每次可存储10组X6通道数据,每次刷新定义的数据量adc1_convert_num 个数
uint16_t ADC1_convert[10][6] = {0};//ADC1数据转存,每次可存储10组X6通道数据,每次刷新定义的数据量adc1_convert_num 个数

//uint32_t ADC3_convert[6][3];//ADC3数据转存,每次可存储6组X3通道数据,每次刷新定义的数据量adc3_convert_num 个数
uint16_t ADC3_convert[6][3];//ADC3数据转存,每次可存储6组X3通道数据,每次刷新定义的数据量adc3_convert_num 个数
/* USER CODE END 0 */

添加标志位与转存区域:

uint8_t ADC1_Rec_Flag;//ADC1转换完成标志
uint8_t ADC2_Rec_Flag;//ADC2转换完成标志
uint8_t ADC3_Rec_Flag;//ADC3转换完成标志

uint16_t ADC1_temp[10][6] = {0};//ADC1转化数据转存
//uint32_t ADC1_temp[10][6] = {0};//
uint16_t ADC3_temp[6][3] = {0};//ADC3转化数据转存
//uint32_t ADC3_temp[6][3] = {0};//

重定义AD转换完成回调函数:void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{    
    if((hadc == &hadc1)&&(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)))
    {
        ADC1_Rec_Flag = 1;
    }
    if((hadc == &hadc3)&&(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc3),HAL_ADC_STATE_REG_EOC)))
    {
        ADC3_Rec_Flag = 1;
    }
}

任务函数添加:

void Start_Task2(void const * argument)
{
  /* USER CODE BEGIN Start_Task2 */
    uint16_t task2_ram_availa =0;
    uint8_t loop1 = 0,loop2 = 0;//循环次数计数
  /* Infinite loop */
  for(;;)
  {
        if(ADC1_Rec_Flag ==1)
        {
            ADC1_Rec_Flag = 0;
            /*停止DMA转存    HAL_ADC_Stop_DMA();
            ** 1. 用于将采样数据从缓冲区转移至指定区域,后再开启DMA,期间数据不更新,避免同时读写
            ** 2. 处理数据错位问题(经测试,不停止DMA对数据连续性没有影响,该用法保留)
            */
            HAL_ADC_Stop_DMA(&hadc1);
            for(loop1 = 0;loop1<adc1_convert_num/adc1_channel;loop1++)
            {
                for(loop2 =0;loop2<adc1_channel;loop2++)
                {
                    ADC1_temp[loop1][loop2] = ADC1_convert[loop1][loop2];
                }                
            }
            /* HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
            ** hadc: 当前使用的ADC编号
            ** pData:ADC采样后,DMA转存采样值的保存地址,
            ** Length:数据量,为配置的通道数n的倍数,假设为K,每次完成Length=N*k个数据的转换后,调用回调函数/
            ** void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
            */
            HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ADC1_convert,adc1_convert_num);
        }
        if(ADC3_Rec_Flag ==1)
        {
            ADC3_Rec_Flag = 0;
                
            /*停止DMA转存    HAL_ADC_Stop_DMA();
            ** 1. 用于将采样数据从缓冲区转移至指定区域,后再开启DMA,期间数据不更新,避免同时读写
            ** 2. 处理数据错位问题(经测试,不停止DMA对数据连续性没有影响,该用法保留)
            */
            HAL_ADC_Stop_DMA(&hadc3);
            for(loop1 = 0;loop1<adc3_convert_num/adc3_channel;loop1++)
            {
                for(loop2 =0;loop2<adc3_channel;loop2++)
                {
                    ADC3_temp[loop1][loop2] = ADC3_convert[loop1][loop2];
                }                
            }
            /* HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
            ** hadc: 当前使用的ADC编号
            ** pData:ADC采样后,DMA转存采样值的保存地址,
            ** Length:数据量,为配置的通道数n的倍数,假设为K,每次完成Length=N*k个数据的转换后,调用回调函数/
            ** void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);
            */
            HAL_ADC_Start_DMA(&hadc3,(uint32_t *)ADC3_convert,adc3_convert_num);
        }
        count_task2++;
        task2_ram_availa = uxTaskGetStackHighWaterMark(Task2Handle);//获取最高任务栈剩余量        
        printf("TASK2!__ %d,task2_ram_availa: %d\r\n",count_task2,task2_ram_availa);
    osDelay(5000);
  }
  /* USER CODE END Start_Task2 */
}

 

标签:DMA,convert,HAL,STM32CubeMX,ADC,ADC1,ADC3
From: https://www.cnblogs.com/ysyyrps-hhl/p/16603196.html

相关文章

  • podman基础命令
    podman基础命令podmancp在容器和本地文件系统之间复制文件/文件夹//将本地文件传输到容器中[root@localhost~]#podmanps-aC0ONTAINERIDIMAGECOMMANDCREATE......
  • SortedMap
    SortedMap/**Copyright(c)1998,2011,Oracleand/oritsaffiliates.Allrightsreserved.*ORACLEPROPRIETARY/CONFIDENTIAL.Useissubjecttolicenseter......
  • stm32的ADC采样(基于HAL库)
    什么是ADC转换? CUBEMX配置ADC时需要注意的几个点:1.   adc采样的精度最高位数是16位。 这个设置是微秒级别的。所以不影响。 ......
  • 无根用户管理podman
    无根用户管理podman目录无根用户管理podman基础设置用户配置文件卷使用卷在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配......
  • podman(无根用户管理podman)
    用户操作在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置cgroupV2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgrou......
  • 在无根的环境中基本设置和使用podman
    在无根的环境中基本设置和使用podman基本设置cgroupV2Linux内核功能允许用户限制普通用户容器可以使用的资源,如果使用cgroupV2启用了运行Podman的Linux发行版,则可能需要......
  • podman无根模式
    目录podman无根模式卷podman无根模式在允许没有root特权的用户运行Podman之前,管理员必须安装或构建Podman并完成以下配置cgroupV2Linux内核功能允许用户限制普通用户......
  • podman的基本设置和使用
    podman的基本设置和使用目录podman的基本设置和使用运行httpd示例容器列出和检查正在运行的容器测试httpd服务器查看容器日志查看容器的进程对容器执行检查操作还原容器......
  • podman的基本用法
    目录podman的基本设置和使用运行示例容器列出正在运行的容器检查正在运行的容器测试httpd服务器查看容器的日志查看容器的pid检查点容器恢复容器迁移容器停止容器删除容......
  • Podman基础用法
    Podman基础1、什么是Podman?Podman是一种开源的Linux原生工具,旨在根据开放容器倡议(OpenContainerInitiative,OCI)标准开发、管理和运行容器和Pod。Podman是RedHat开发......