Closed CJT1111 closed 5 months ago
First I read an article @fpistm gave me: https://www.stm32duino.com/viewtopic.php?t=110 Then I wrote the following code according to the article:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Arduino库调用
//HAL库调用 extern "C" {
}
// 串口调用 HardwareSerial Serial1(PA10, PA9); // RX,TX/硬件串口调用(void setup()前)
//HAL模块声明 ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1;
//ADC转换完成标志 volatile bool adc_conversion_complete = false;
// 定义ADC通道和DMA缓冲区 const uint32_t ADC_BUFFER_LENGTH = 2048; //ADC的BUFFER长度 uint16_t adc_buffer[ADC_BUFFER_LENGTH]; //ADC数组
void setup() { // 初始化串口 Serial1.begin(9600); Serial1.println("ADC&DMA测试"); delay(1000);
// 初始化HAL库 HAL_Init();
// 启动ADC和DMA的时钟使能 HAL_RCC_ADC1_CLK_ENABLE(); HAL_RCC_DMA1_CLK_ENABLE();
// 配置ADC hadc1.Instance = ADC1; // 使用ADC1 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // 多通道扫描模式 hadc1.Init.ContinuousConvMode = ENABLE; // 连续转换模式 hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁用非连续转换模式 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发ADC开始 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // ADC数据右对齐 hadc1.Init.NbrOfConversion = 1; // 转换序列中的转换数(单通道) HAL_ADC_Init(&hadc1); // 配置ADC通道 ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_1; //通道设置 sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 配置DMA hdma_adc1.Instance = DMA1_Channel1; //通道配置(DMA1_Channel1) 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; //设置外设数据对齐为半字对齐(16位ADC) hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; //设置内存数据对齐为半字对齐 hdma_adc1.Init.Mode = DMA_CIRCULAR; //设置DMA工作在循环模式 hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; //设置DMA通道的优先级为高 HAL_DMA_Init(&hdma_adc1); //DMA配置
//ADC和DMA链接 __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1); //ADC和DMA链接
// 检查DMA中断 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); //配置DMA中断优先级 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); //使能DMA1通道1的中断,允许其响应
// 开始DMA传输 HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_LENGTH); //开始使用DMA进行ADC数据的传输,数据会被传输到adc_buffer数组,长度为ADC_BUFFER_LENGTH }
//分布调数助手 // Serial1.println("ADC&DMA测试分布调试断点[0]"); // delay(1000);
void loop() { // 检查是否完成了一次ADC转换 if (adc_conversion_complete) { adc_conversion_complete = false;
// 选择性地打印部分数据以避免过慢的串口通信 for (int i = 0; i < ADC_BUFFER_LENGTH; i += ADC_BUFFER_LENGTH / 10) { // 举例:仅打印部分数据点 Serial1.print("ADC Data ["); Serial1.print(i); Serial1.print("]: "); Serial1.println(adc_buffer[i]); }
} else { Serial1.println("E"); } }
// DMA中断服务程序 void DMA1_Channel1_IRQHandler() { HAL_DMA_IRQHandler(&hdma_adc1); }
// DMA传输完成回调函数 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { adc_conversion_complete = true; }` ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Then this program can be compiled, but I passed the breakpoint test, found that he will be stuck in “*HAL_ADC_Start_DMA(&hadc1, (uint32_t)adc_buffer, ADC_BUFFER_LENGTH);**” here, please see what the problem, thank you.
First I read an article @fpistm gave me: https://www.stm32duino.com/viewtopic.php?t=110 Then I wrote the following code according to the article:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Arduino库调用
include
//HAL库调用 extern "C" {
include "stm32f1xx_hal_dma.h"
include "stm32f1xx_hal_adc.h"
include "stm32f1xx_hal.h"
include "stm32f1xx_hal_adc_ex.h"
}
// 串口调用 HardwareSerial Serial1(PA10, PA9); // RX,TX/硬件串口调用(void setup()前)
//HAL模块声明 ADC_HandleTypeDef hadc1; DMA_HandleTypeDef hdma_adc1;
//ADC转换完成标志 volatile bool adc_conversion_complete = false;
// 定义ADC通道和DMA缓冲区 const uint32_t ADC_BUFFER_LENGTH = 2048; //ADC的BUFFER长度 uint16_t adc_buffer[ADC_BUFFER_LENGTH]; //ADC数组
void setup() { // 初始化串口 Serial1.begin(9600); Serial1.println("ADC&DMA测试"); delay(1000);
// 初始化HAL库 HAL_Init();
// 启动ADC和DMA的时钟使能 HAL_RCC_ADC1_CLK_ENABLE(); HAL_RCC_DMA1_CLK_ENABLE();
// 配置ADC hadc1.Instance = ADC1; // 使用ADC1 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // 多通道扫描模式 hadc1.Init.ContinuousConvMode = ENABLE; // 连续转换模式 hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁用非连续转换模式 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发ADC开始 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // ADC数据右对齐 hadc1.Init.NbrOfConversion = 1; // 转换序列中的转换数(单通道) HAL_ADC_Init(&hadc1); // 配置ADC通道 ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = ADC_CHANNEL_1; //通道设置 sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig);
// 配置DMA hdma_adc1.Instance = DMA1_Channel1; //通道配置(DMA1_Channel1) 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; //设置外设数据对齐为半字对齐(16位ADC) hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; //设置内存数据对齐为半字对齐 hdma_adc1.Init.Mode = DMA_CIRCULAR; //设置DMA工作在循环模式 hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; //设置DMA通道的优先级为高 HAL_DMA_Init(&hdma_adc1); //DMA配置
//ADC和DMA链接 __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1); //ADC和DMA链接
// 检查DMA中断 HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); //配置DMA中断优先级 HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); //使能DMA1通道1的中断,允许其响应
// 开始DMA传输 HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, ADC_BUFFER_LENGTH); //开始使用DMA进行ADC数据的传输,数据会被传输到adc_buffer数组,长度为ADC_BUFFER_LENGTH }
//分布调数助手 // Serial1.println("ADC&DMA测试分布调试断点[0]"); // delay(1000);
void loop() { // 检查是否完成了一次ADC转换 if (adc_conversion_complete) { adc_conversion_complete = false;
} else { Serial1.println("E"); } }
// DMA中断服务程序 void DMA1_Channel1_IRQHandler() { HAL_DMA_IRQHandler(&hdma_adc1); }
// DMA传输完成回调函数 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { adc_conversion_complete = true; }` ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Then this program can be compiled, but I passed the breakpoint test, found that he will be stuck in “*HAL_ADC_Start_DMA(&hadc1, (uint32_t)adc_buffer, ADC_BUFFER_LENGTH);**” here, please see what the problem, thank you.