你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于stm32f302的AD采样

[复制链接]
alisa123 提问时间:2015-6-3 13:45 /
因为采样多个通道的AD转换,所以我用了ADC+DMA的方式进行的,定时器TIM4的上升沿触发AD转换(定时50us转换一次),但是始终无法进入AD转换完成中断中,求各位高手帮忙分析是什么原因导致的,谢谢。程序如下:
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* Enable  ADC1 DMA1_Channel1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;       //ÓÃÓÚADC1 DMA²ÉÑùÊý¾Ý¶ÁÈ¡
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void ADC1_DMA_Configuration(void)    //ADC²ÉÑù³õʼ»¯ÅäÖÃ
{
GPIO_InitTypeDef  GPIO_InitStructure;
ADC_InitTypeDef   ADC_InitStructure;
ADC_CommonInitTypeDef  ADC_CommonInitStructure;
DMA_InitTypeDef   DMA_InitStructure;
/* Configure the ADC clock */  
RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
/* Enable the  DMA1¡¢GPIOA ¡¢GPIOB and ADC1 Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_ADC12, ENABLE);

if (SysTick_Config(SystemCoreClock / 1000000))
{
  while (1)
  {}
}
/* Configure PA0/PA1/PA2/PA3/PA6/PA7/PB0/PB1 (ADC Channel1/2/3/4/5/10/15/11/12) in analog mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
         | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);  
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);  

/* Configure DMA1_Channel1  */
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 8;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// DMA_ITConfig(DMA1,DMA_IT_TC,ENABLE);
/* Enable DMA1 Channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);

/* Configure ADC1 */
ADC_StructInit(&ADC_InitStructure);
  
/* Calibration procedure */
ADC_VoltageRegulatorCmd(ADC1, ENABLE);
/* Insert delay equal to 10ms */
Delay(10);
ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
ADC_StartCalibration(ADC1);
  
while(ADC_GetCalibrationStatus(ADC1) != RESET );
calibration_value = ADC_GetCalibrationValue(ADC1);

/* Configure the ADC1 in continuous mode */  
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                  
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;            
ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;                  
ADC_CommonInitStructure.ADC_TwoSamplingDelay = 5;      
ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
  
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_5;     //TIM4_CC4 event        
ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_RisingEdge;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;   
ADC_InitStructure.ADC_NbrOfRegChannel = 8;
ADC_Init(ADC1, &ADC_InitStructure);
  
/* ADC1 regular channel1 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 6, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 7, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 8, ADC_SampleTime_181Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 9, ADC_SampleTime_181Cycles5);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 sample finish interrupt */
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE);
/* wait for ADRDY */
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
  
/* ADC1 DMA Enable */
ADC_DMACmd(ADC1, ENABLE);
ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);
   
}

void TIM4_Configuration(void)  //TIM4定时50us触发AD采样
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

/* TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 50;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;      //72M/(71+1) = 1,000,000 -->1us
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 25;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC4Init(TIM4,&TIM_OCInitStructure);
TIM_Cmd(TIM4,ENABLE);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
}
收藏 评论9 发布时间:2015-6-3 13:45

举报

9个回答
废鱼 回答时间:2015-6-3 14:10:29
楼主用的是DMA1_Channel1通道,采集完成以后是产生的DMA中断,而不是AD。
alisa123 回答时间:2015-6-3 15:07:08
安 发表于 2015-6-3 14:10
楼主用的是DMA1_Channel1通道,采集完成以后是产生的DMA中断,而不是AD。

谢谢楼主回复,我已经你的指导改成DMA1_Channel1中断了,但是还是不能定时50us进入中断读取数据,麻烦请帮忙再指导下,谢谢,修改后的程序如下:
void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;                        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
void ADC1_DMA_Configuration(void)                                //ADC²ÉÑù³õʼ»¯ÅäÖÃ
{
        GPIO_InitTypeDef  GPIO_InitStructure;
        ADC_InitTypeDef          ADC_InitStructure;
        ADC_CommonInitTypeDef  ADC_CommonInitStructure;
        DMA_InitTypeDef          DMA_InitStructure;

        /* Enable the  DMA1¡¢GPIOA ¡¢GPIOB and ADC1 Clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_ADC12, ENABLE);
        /* Configure the ADC clock */  
        RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div2);
       
        if (SysTick_Config(SystemCoreClock / 1000000))
        {
                while (1)
                {}
        }
        /* Configure PA0/PA1/PA2/PA3/PA6/PA7/PB0/PB1 (ADC Channel1/2/3/4/5/10/15/11/12) in analog mode */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3
                                                                 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);  

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
        GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOB, &GPIO_InitStructure);  
       
        /* Configure DMA1_Channel1  */
        DMA_DeInit(DMA1_Channel1);
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_ConvertedValue;
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStructure.DMA_BufferSize = 8;
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
        DMA_Init(DMA1_Channel1, &DMA_InitStructure);
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);

        /* Enable DMA1 Channel1 */
        DMA_Cmd(DMA1_Channel1, ENABLE);
       
        /* Configure ADC1 */       
//        ADC_StructInit(&ADC_InitStructure);
        ADC_DeInit(ADC1);
  
        /* Calibration procedure */
        ADC_VoltageRegulatorCmd(ADC1, ENABLE);
        /* Insert delay equal to 10us */
        Delay(10);
        ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
        ADC_StartCalibration(ADC1);
  
        while(ADC_GetCalibrationStatus(ADC1) != RESET );
        calibration_value = ADC_GetCalibrationValue(ADC1);
       
        /* Configure the ADC1 in continuous mode */  
        ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;                                                                    
        ADC_CommonInitStructure.ADC_Clock = ADC_Clock_AsynClkMode;                  
        ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;            
        ADC_CommonInitStructure.ADC_DMAMode = ADC_DMAMode_Circular;                  
        ADC_CommonInitStructure.ADC_TwoSamplingDelay = 5;      
        ADC_CommonInit(ADC1, &ADC_CommonInitStructure);
  
        ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
        ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;       
        ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_5;                                 //TIM4_CC4 event        
        ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_RisingEdge;
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
        ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;   
        ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;   
        ADC_InitStructure.ADC_NbrOfRegChannel = 8;
        ADC_Init(ADC1, &ADC_InitStructure);
  
        /* ADC1 regular channel1 configuration */
        ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 6, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 7, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 8, ADC_SampleTime_181Cycles5);
        ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 9, ADC_SampleTime_181Cycles5);
       
        /* Enable ADC1 */
        ADC_Cmd(ADC1, ENABLE);
        /* wait for ADRDY */
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY));
  
        /* ADC1 DMA Enable */
        ADC_DMACmd(ADC1, ENABLE);
        ADC_DMAConfig(ADC1, ADC_DMAMode_Circular);         
}
void DMA1_Channel1_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET)
        {
                 sADCFinished();     //读取AD采样数据
                          DMA_ClearFlag(DMA1_FLAG_TC1);
}
废鱼 回答时间:2015-6-3 15:51:04
With an ADCCLK = 12 MHz and a sampling time of 1.5 cycles:
Tconv = 1.5 + 12.5 = 14 cycles = 1.17 μs
楼主用的是 ADC_SampleTime_181Cycles5, 181.5 cycles。按照上面的公式算应该是15us转换 一次。这样所有的转换完大概是120us。不知道和楼主实际测试的间隔是否接近?
alisa123 回答时间:2015-6-4 09:57:56
安 发表于 2015-6-3 15:51
With an ADCCLK = 12 MHz and a sampling time of 1.5 cycles:
Tconv = 1.5 + 12.5 = 14 cycles = 1.17 μs ...

谢谢你的恢复,这个我真是没想到,我修改下实验试试。
stary666 回答时间:2015-6-4 10:00:02
儿科。。。。。。。。。。。。。。
alisa123 回答时间:2015-6-4 11:14:03
安 发表于 2015-6-3 15:51
With an ADCCLK = 12 MHz and a sampling time of 1.5 cycles:
Tconv = 1.5 + 12.5 = 14 cycles = 1.17 μs ...

版主:谢谢你,之前一直是进不了中断中,现在已经找到问题所在了,是TIM4的比较捕获的上升沿触发AD转换没有正确触发,我用软件触发就能进入中断,具体修改TIM4的比较捕获的上升沿触发AD转换正在摸索调试中。
废鱼 回答时间:2015-6-4 14:19:42
楼主有问题继续留贴。
alisa123 回答时间:2015-6-5 11:43:43
请问stm32f10x中的触发ADC的ADC_ExternalTrigConv_T4_CC4和stm32f302中的TIM4_CC4 event有什么区别?怎么用外部触发一直不能触发进入中断?
wo1357997531 回答时间:2019-7-1 17:36:49
你好  楼主  请问后来搞定了没  遇到了同样的问题 求指点 谢谢

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版