2026/1/2 13:24:34
网站建设
项目流程
合肥网站建设哪里好,有没有网址免费的,外贸网站如何换域名,网站功能界面设计本期目标
理清本工程系统框架弄懂CubeMx配置相关原理及设置的背后含义对DMA以及ADC相关的重要API接口使用详解梳理代码设计流程 前置文章链接#xff1a;
Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据#xff08;一#xff09;-CSDN博客
在上一章节完成了对…本期目标理清本工程系统框架弄懂CubeMx配置相关原理及设置的背后含义对DMA以及ADC相关的重要API接口使用详解梳理代码设计流程前置文章链接Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据一-CSDN博客在上一章节完成了对框架的初步探索以及对CubeMx的配置在freertos的task中对buffer进行了一些测试下面继续上一章的内容继续完成本次目标2.启动DMA传输并进入中断此处是使用中断的方式 意为当数据采集完毕后会使用产生中断本篇使用的是下面的方式(##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA()) () Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE() () Configure and enable two DMA streams stream for managing data transfer from peripheral to memory (output stream) () Associate the initialized DMA handle to the CRYP DMA handle using __HAL_LINKDMA() () Configure the priority and enable the NVIC for the transfer complete interrupt on the two DMA Streams. The output stream should have higher priority than the input stream.在启动ADC传输以后 会把数据放到DR寄存器里 如果是中断模式 会产生一个中断去取走DR寄存器里面的值 而是产生一个DMA request 然后启动对应的DMA通道 然后把DR寄存器里面的值搬运到指定的地址buffer1/buffer2上HAL_ADC_Start_DMA()最主要的就是知晓这个函数怎么用/** * brief Enables ADC DMA request after last transfer (Single-ADC mode) and enables ADC peripheral * param hadc pointer to a ADC_HandleTypeDef structure that contains * the configuration information for the specified ADC. * param pData The destination Buffer address. * param Length The length of data to be transferred from ADC peripheral to memory. * retval HAL status */点击函数跳转定义可以看到这个函数的简介“启动DMA request 在每次传输完ADC后 并且启动ADC外设”HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)第一个形参是ADC的句柄于ADC.c文件里面有定义所以我们要使用的时候就要在所使用的文件里extern引用/* USER CODE BEGIN Variables */ extern ADC_HandleTypeDef hadc1; extern DMA_HandleTypeDef hdma_adc1; /* USER CODE END Variables */第二个形参是DMA将要将数据搬运到的地址 就是我们前面定义的buffer1/2第三个形参是要从ADC采集多少次数据HAL_ADC_Start_DMA(hadc1, buffer1, BUFFER_SIZE); HAL_ADC_Start_DMA(hadc1, buffer2, BUFFER_SIZE);void StartDefaultTask(void *argument) { /* USER CODE BEGIN StartDefaultTask */ buffer1 (uint32_t *)malloc((sizeof(uint32_t)* BUFFER_SIZE)); buffer2 (uint32_t *)malloc((sizeof(uint32_t)* BUFFER_SIZE)); if(NULL buffer1) { printf(buffer1 malloc failed \r\n); } if(NULL buffer2) { printf(buffer2 malloc failed \r\n); return; } printf(buffer1 , buffer2 malloc success\r\n ); memset(buffer1, 0xff , (sizeof(uint32_t)* BUFFER_SIZE)); memset(buffer2, 0xff , (sizeof(uint32_t)* BUFFER_SIZE)); printf(Unit test ADC DMA\r\n ); HAL_ADC_Start_DMA(hadc1, buffer1, BUFFER_SIZE); HAL_ADC_Start_DMA(hadc1, buffer2, BUFFER_SIZE); /* Infinite loop */ for(;;) { printf(hello world \r\n); printf(buffer1 data [%d] \r\n , buffer1[0]); printf(buffer2 data [%d] \r\n , buffer2[0]); osDelay(1000); } /* USER CODE END StartDefaultTask */ }为了防止ADC调用出错 应当接收函数的返回值 以观察函数是否异常HAL_StatusTypeDef ret1 HAL_OK; HAL_StatusTypeDef ret2 HAL_OK; ret1 HAL_ADC_Start_DMA(hadc1, buffer1, BUFFER_SIZE); ret2 HAL_ADC_Start_DMA(hadc1, buffer2, BUFFER_SIZE); if(HAL_OK ! ret1) { printf(HAL_ADC1 call failed ); } if(HAL_OK ! ret2) { printf(HAL_ADC2 call failed ); }至此我们的API HAL_ADC_Start_DMA()就调用成功了HAL_ADC_ConvCpltCallback()当DMA输出到Buffer1后 触发DMA中断中断做的第一件事 发送消息队列或任务通知邮箱给线程A 。 涉及函数xTaskNotifyFromISR或xQueueGenericSendFromISR() At The end of data transfer by HAL_ADC_ConvCpltCallback() function is executed and user can add his own code by customization of function pointer HAL_ADC_ConvCpltCallback__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ConvCpltCallback could be implemented in the user file */ }将此函数复制到freertos文件调用void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); printf(buffer1 data [%d] \r\n , buffer1[0]); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ConvCpltCallback could be implemented in the user file */ }打印一串数据到串口验证是否可行可以看到函数被运行了HAL_ADC_ErrorCallback同样的 要设置一个验错机制() In case of transfer Error, HAL_ADC_ErrorCallback() function is executed and user can add his own code by customization of function pointer HAL_ADC_ErrorCallbackvoid HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) { /* Prevent unused argument(s) compilation warning */ UNUSED(hadc); /* NOTE : This function Should not be modified, when the callback is needed, the HAL_ADC_ErrorCallback could be implemented in the user file */ printf(ADC trasfer error \r\n); }下一章节Freertos手把手教STM32CubeMx设置STM32F4芯片DMA发送ADC数据三-CSDN博客