ADC_HandleTypeDef ADC1_Handler;//ADC句柄 ADC_HandleTypeDef ADC2_Handler; ADC_HandleTypeDef ADC3_Handler; ADC_MultiModeTypeDef multimode; ADC_ChannelConfTypeDef ADC1_ChanConf,ADC2_ChanConf,ADC3_ChanConf; DMA_HandleTypeDef ADC1DMA2; DMA_HandleTypeDef ADC2DMA2; DMA_HandleTypeDef ADC3DMA2; //初始化ADC //ch: ADC_channels //通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16 void MY_ADC_Init_1(void) { ADC1_Handler.Instance=ADC1; ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/8=90/8=11.25MHZ ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式 ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐 ADC1_Handler.Init.ScanConvMode=ENABLE; //非扫描模式 ADC1_Handler.Init.EOCSelection=DISABLE; //开启EOC中断 ADC1_Handler.Init.ContinuousConvMode=ENABLE; //樟? ADC1_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列4 ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式 ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0 ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //软件触发 ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发 ADC1_Handler.Init.DMAContinuousRequests=ENABLE; //DMA请求 HAL_ADC_Init(&ADC1_Handler); //初始化 multimode.Mode =ADC_TRIPLEMODE_REGSIMULT; // multimode.DMAAccessMode=ADC_DMAACCESSMODE_1; multimode.TwoSamplingDelay=ADC_TWOSAMPLINGDELAY_5CYCLES; HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handler, &multimode); } void MY_ADC_Init_2(void) { ADC2_Handler.Instance=ADC2; ADC2_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ ADC2_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式 ADC2_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐 ADC2_Handler.Init.ScanConvMode=ENABLE; //非扫描模式 ADC2_Handler.Init.EOCSelection=DISABLE; //关闭EOC中断 ADC2_Handler.Init.ContinuousConvMode=ENABLE; //关闭连续转换 ADC2_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列1 ADC2_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式 ADC2_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0 ADC2_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1; //软件触发 ADC2_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发 ADC2_Handler.Init.DMAContinuousRequests=DISABLE; //关闭DMA请求 HAL_ADC_Init(&ADC2_Handler); //初始化 multimode.Mode =ADC_TRIPLEMODE_REGSIMULT; multimode.DMAAccessMode=ADC_DMAACCESSMODE_1; // multimode.TwoSamplingDelay=ADC_TWOSAMPLINGDELAY_5CYCLES; HAL_ADCEx_MultiModeConfigChannel(&ADC2_Handler, &multimode); } void MY_ADC_Init_3(void) { ADC3_Handler.Instance=ADC3; ADC3_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ ADC3_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式 ADC3_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐 ADC3_Handler.Init.ScanConvMode=ENABLE; //非扫描模式 ADC3_Handler.Init.EOCSelection=DISABLE; //EOC中断 ADC3_Handler.Init.ContinuousConvMode=ENABLE; //连续转换 ADC3_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列1 ADC3_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式 ADC3_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0 ADC3_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIGCONV_T1_CC1; //软件触发 ADC3_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发 ADC3_Handler.Init.DMAContinuousRequests=DISABLE; //关闭DMA请求 HAL_ADC_Init(&ADC3_Handler); //初始化 multimode.Mode =ADC_TRIPLEMODE_REGSIMULT; multimode.DMAAccessMode=ADC_DMAACCESSMODE_1; // multimode.TwoSamplingDelay=ADC_TWOSAMPLINGDELAY_5CYCLES; HAL_ADCEx_MultiModeConfigChannel(&ADC3_Handler, &multimode); } //ADC底层驱动,引脚配置,时钟使能 //此函数会被HAL_ADC_Init()调用 //hadc:ADC句柄 void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟 __HAL_RCC_ADC2_CLK_ENABLE(); __HAL_RCC_ADC3_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 // __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能 GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5; //|GPIO_PIN_6; //PA5和PA4 PA4 GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟 GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_8; //PF8 GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟 GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOF,&GPIO_Initure); ADC1DMA2.Instance =DMA2_Stream0; ADC1DMA2.Init.Direction = DMA_PERIPH_TO_MEMORY; ADC1DMA2.Init.PeriphInc = DMA_PINC_DISABLE; ADC1DMA2.Init.MemInc = DMA_MINC_ENABLE; ADC1DMA2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; ADC1DMA2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; ADC1DMA2.Init.Mode = DMA_CIRCULAR; ADC1DMA2.Init.Priority = DMA_PRIORITY_HIGH; HAL_DMA_DeInit(&ADC1DMA2); HAL_DMA_Init(&ADC1DMA2); __HAL_LINKDMA(hadc,DMA_Handle,ADC1DMA2); } void MY_ADC1_ChanConf() { ADC1_ChanConf.Channel=ADC_CHANNEL_4; //通道 PA4 ADC1_ChanConf.Rank=1; //第1个序列,序列1 ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_3CYCLES; //采样时间 ADC1_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置*/ } void MY_ADC2_ChanConf() { ADC2_ChanConf.Channel=ADC_CHANNEL_5; //通道 ADC2_ChanConf.Rank=1; //第1个序列,序列1 ADC2_ChanConf.SamplingTime=ADC_SAMPLETIME_3CYCLES; //采样时间 ADC2_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_ChanConf); //通道配置 } void MY_ADC3_ChanConf() { ADC3_ChanConf.Channel=ADC_CHANNEL_6; //通道 ADC3_ChanConf.Rank=1; //第1个序列,序列1 ADC3_ChanConf.SamplingTime=ADC_SAMPLETIME_3CYCLES; //采样时间 ADC3_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC3_Handler,&ADC3_ChanConf); //通道配置 } |
1、在原有的电机控制算法中ADC双重同步模式(同时测量两相电流)下,增加一路测量线电压采样。
考虑到stm32f407有三个ADC,故配置ADC3来采样线电压,但是在实验过程会导致ADC12无法正常使用。
仔细分析:原来在ADC3配置会修改多个ADC的运行方式,双重模式下为ADC_DualMode_RegSimult,但假如ADC3配置后,独立模式ADC_Mode_Independent会使得之前ADC12配置的ADC_DualMode_RegSimult模式失败,从而导致AD12无法使用。因此,考虑利用stm32f407的三重模式来实现同时测量两相电流和线电压。
2、参考了STM32F4xx_StdPeriph_Examples中ADC的ADC_TripleModeInterleaved,为交替模式;为保证电机控制算法中电流为同步采样,应为同步模式;
之后参考STM32论坛的帖子:https://www.stmcu.org.cn/module/forum/thread-603974-1-2.html
3、具体实现:
其中在ADC配置中,有几个需要特别注意:
ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;// 三重同步模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;// 4分频,84/4=21M<36M
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;//
//ADC_DMAAccessMode 模式的选择,参考手册,选择模式1
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//
ADC_CommonInit(&ADC_CommonInitStructure);
以及以下资料参考
stm32f405/407的三重 ADC同步触发模式+DMA 配置
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=603974&fromuid=2091055
评分
查看全部评分