ST意法半导体
直播中

golabs

9年用户 960经验值
擅长:可编程逻辑 电源/新能源 MEMS/传感技术 测量仪表
私信 关注
[问答]

怎样使用STM32H743ZI的ADC通道进行顺序扫描呢

我正在尝试将STM32H743ZI的 ADC 设置为 5 通道连续扫描。5 次扫描将用于
输入电压 - 通道 0
输入电流 - 通道 1
输出电压 - 通道 2
输出电流 - 通道 3
内部温度传感器 - 通道 18
本质上,我只是希望 ADC 连续扫描这 5 个通道,并让 DMA 将其传输到缓冲区中,以便软件可以读取它。我想读取缓冲区的方式是通过轮询,因为我正在使用 RTOS。
我遇到的问题是 ADC 的 EOS 标志和 DMA1 TC4 标志正在设置,但数据没有传输到 DMA 缓冲区。然而,我看到数据在 ADC3 的 DR 寄存器中移动。
我仔细检查了 DMA,内存地址在 DMA 可以查看的正确内存区域内。我不知道发生了什么,因为我以前从未真正使用过 ADC 进行顺序扫描。
如果有人能看到我是否设置错误或者我是否必须做某事,我很期待。例如,我没有使用中断,因为我提到我正在使用轮询,但是我正在使用 DMA。我还需要启用 DMA4 TC 中断吗?等等等等。我只想让 ADC 在 DMA 传输数据的同时永远扫描,我随时都可以轮询。
任何建议表示赞赏
设置 GPIO、DMA、ADC 的低电平寄存器
  • void ADC_helper_function::enable(int * RxBuffer) {
  •         LL_DMA_InitTypeDef     ADC_Config_DMA;
  •         LL_GPIO_InitTypeDef    ADC_Config_GPIO;
  •         LL_ADC_InitTypeDef     ADC_Config_init;
  •         LL_ADC_REG_InitTypeDef ADC_Config_REG;
  •         LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC);
  •         LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOF);
  •         LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_ADC3);
  •         LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
  •         LL_ADC_StructInit(&ADC_Config_init);
  •         LL_ADC_REG_StructInit(&ADC_Config_REG);
  •         LL_GPIO_StructInit(&ADC_Config_GPIO);
  •         LL_DMA_StructInit(&ADC_Config_DMA);
  •         //Configure GPIOA
  •         ADC_Config_GPIO.Mode       = LL_GPIO_MODE_ANALOG;
  •         ADC_Config_GPIO.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  •         ADC_Config_GPIO.Pin        = LL_GPIO_PIN_2 | LL_GPIO_PIN_3;
  •         ADC_Config_GPIO.Pull       = LL_GPIO_PULL_UP;
  •         ADC_Config_GPIO.Speed      = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  •         LL_GPIO_Init(GPIOC, &ADC_Config_GPIO);
  •         //Configure GPIOC
  •         ADC_Config_GPIO.Mode       = LL_GPIO_MODE_ANALOG;
  •         ADC_Config_GPIO.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  •         ADC_Config_GPIO.Pin        = LL_GPIO_PIN_9 | LL_GPIO_PIN_7;
  •         ADC_Config_GPIO.Pull       = LL_GPIO_PULL_UP;
  •         ADC_Config_GPIO.Speed      = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  •         LL_GPIO_Init(GPIOF, &ADC_Config_GPIO);
  •         ADC_Config_DMA.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  •         ADC_Config_DMA.FIFOMode = LL_DMA_FIFOMODE_DISABLE;
  •         ADC_Config_DMA.MemBurst = LL_DMA_MBURST_SINGLE;
  •         ADC_Config_DMA.MemoryOrM2MDstAddress = (uint32_t)RxBuffer;
  •         ADC_Config_DMA.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD;
  •         ADC_Config_DMA.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
  •         ADC_Config_DMA.Mode = LL_DMA_MODE_CIRCULAR;
  •         ADC_Config_DMA.NbData = 5;
  •         ADC_Config_DMA.PeriphBurst = LL_DMA_PBURST_SINGLE;
  •         ADC_Config_DMA.PeriphOrM2MSrcAddress = (uint32_t)&ADC1->DR;
  •         ADC_Config_DMA.PeriphOrM2MSrcDataSize = LL_DMA_MDATAALIGN_WORD;
  •         ADC_Config_DMA.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
  •         ADC_Config_DMA.PeriphRequest = LL_DMAMUX1_REQ_ADC3;
  •         ADC_Config_DMA.Priority = LL_DMA_PRIORITY_LOW;
  •         //Interrupt: DMA
  •         LL_DMA_Init(DMA1, LL_DMA_STREAM_4, &ADC_Config_DMA);
  •         //Configure ADC
  •         ADC_Config_init.LeftBitShift    = LL_ADC_LEFT_BIT_SHIFT_NONE;
  •         ADC_Config_init.LowPowerMode    = LL_ADC_LP_MODE_NONE;
  •         ADC_Config_init.Resolution      = LL_ADC_RESOLUTION_16B;
  •         LL_ADC_Init(ADC3, &ADC_Config_init);
  •         ADC_Config_REG.ContinuousMode   = LL_ADC_REG_CONV_CONTINUOUS;
  •         ADC_Config_REG.DataTransferMode = LL_ADC_REG_DMA_TRANSFER_UNLIMITED;
  •         ADC_Config_REG.Overrun          = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
  •         ADC_Config_REG.SequencerLength  =  LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS;
  •         ADC_Config_REG.TriggerSource    =  LL_ADC_REG_TRIG_SOFTWARE;
  •         LL_ADC_REG_Init(ADC3, &ADC_Config_REG);
  •         LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_0);
  •         LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_1);
  •         LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_2);
  •         LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_3);
  •         LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_TEMPSENSOR);
  •         LL_ADC_SetChannelSingleDiff(ADC3, LL_ADC_CHANNEL_1 | LL_ADC_CHANNEL_2 | LL_ADC_CHANNEL_3, LL_ADC_SINGLE_ENDED);
  •         LL_ADC_SetChannelSamplingTime(ADC3, LL_ADC_CHANNEL_0 | LL_ADC_CHANNEL_1 | LL_ADC_CHANNEL_2 | LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_1CYCLE_5);
  •         LL_ADC_SetChannelSamplingTime(ADC3, LL_ADC_CHANNEL_TEMPSENSOR, LL_ADC_SAMPLINGTIME_387CYCLES_5);
  •         LL_ADC_SetCommonPathInternalCh(ADC3_COMMON, LL_ADC_PATH_INTERNAL_TEMPSENSOR);
  •         LL_ADC_DisableDeepPowerDown(ADC3);
  •         LL_RCC_PLL2_SetM(4);
  •         LL_RCC_PLL2_SetN(9);
  •         LL_RCC_PLL2_SetP(4);
  •         LL_RCC_PLL2_SetFRACN(6144);
  •         LL_RCC_PLL2_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
  •         LL_RCC_PLL2_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
  •         LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLL2P);
  •         LL_RCC_PLL2FRACN_Enable();
  •         LL_RCC_PLL2P_Enable();
  •         LL_RCC_PLL2_Enable();
  •         while ((LL_RCC_PLL2_IsReady == 0)) {
  •         }
  •         LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_4);
  •         LL_ADC_EnableInternalRegulator(ADC3);
  •         LL_ADC_Enable(ADC3);
  •         LL_ADC_REG_StartConversion(ADC3);
  • }
轮询 ADC 缓冲区的任务
  • void ADC::ADC_Daemon(void * parameter) {
  •         int tempSensor = 0;
  •         while(1) {
  •                 vTaskDelay(ADC_Checkin_Interval/portTICK_PERIOD_MS);
  •                 if ((LL_ADC_IsActiveFlag_EOS(ADC3)) && (LL_DMA_IsActiveFlag_TC4(DMA1))) {
  •                         tempSensor = dataStructure->getRxBuffer()[3];
  •                         LL_ADC_ClearFlag_EOS(ADC3);
  •                         LL_DMA_ClearFlag_TC4(DMA1);
  •                 }
  •         }
  • }

回帖(1)

王冬梅

2022-12-23 15:53:19
发现错误。ADC 不再是 OVR,DMA 正在传输数据。但是温度传感器的值是完全错误的
问题:
ADC_Config_DMA.PeriphOrM2MSrcAddress = (uint32_t)&ADC1->DR;
使固定:
ADC_Config_DMA.PeriphOrM2MSrcAddress = (uint32_t)&ADC3->DR;
举报

更多回帖

发帖
×
20
完善资料,
赚取积分