现在有一个问题,ADC采样有时会不准,十几分钟出现1,2次采集数据不准确。以下是我的ADC初始化,帮忙看下有什么问题?
硬件:stm32f030x4 (16k flash,4k ram,5 timer,1 usart)
原理:通过XtBspAdcTimerStart(),启动TIM16,625us中断一次,然后再中断中,启动ADC转换,并打开DMA中断,直到采集完SAMPLE_NUM,停止定时器,表示采用完成,然后再进行ADC数据处理。
补充说明:
1、系统还用到TM14,每1ms产生一次中断;和串口1中断。另外TIM3和TIM17,分别作为PWM时钟和模拟USART时钟。TIM1闲置。
2、NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 所有中断优先级,都设为同级别优先级了。
3、正常数据应该是一个正弦波,而出错数据如下。
我做的一些实验:
1、恒定给一个3.3V的直流信号。数据采集出来都是OK得
2、用信号源,给一个稳定的1.65V的正弦波信号,采集数据还是一样会有时出错。
3、判定是否硬件电平不稳定,用示波器捕捉了很久,没有看到有脉冲信号。
-->之前初步判定是TIM16优先级不够,被打断,导致采样间隔误差造成,采样数据出错。
4、于是我TIM16改为TIM1后,还是偶尔会出现采集出错的问题,根据一些列表,和我用到得中断,我的TIM1在我系统中,除了DMA,已经是优先级最高了。
以下是我的ADC采样相关设置代码,请帮忙看下有什么问题吗?谢谢
//--------------------------------------------------------
void STM_EVAL_ADCConfig(void)
{
ADC_InitTypeDef ADC_InitStructure;
//ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable ADC1, and GPIO clocks ****************************************/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
//RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc1Buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//DMA_Priority_High
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_Cmd(DMA1_Channel1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Initialize ADC structure */
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续扫描模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
ADC_Init(ADC1, &ADC_InitStructure);
//ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T3_CC2);
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*enable transfer complete interrupt------------------*/
//DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
/* ADC3 regular channel7 configuration *************************************/
ADC_ChannelConfig(ADC1, ADC_Channel_7 , ADC_SampleTime_13_5Cycles);
ADC_ChannelConfig(ADC1, ADC_Channel_9 , ADC_SampleTime_13_5Cycles);
//ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
//ADC_StartOfConversion(ADC1);
}
xt_s32 XtBspAdcTimerStart()
{
xt_s32 ret = 0;
STM_EVAL_Tim16Config();
return ret;
}
xt_s32 XtBspAdcTimerStop()
{
xt_s32 ret = 0;
TIM_ITConfig(TIM16, TIM_IT_Update, DISABLE);
TIM_Cmd(TIM16, DISABLE);
return ret;
}
void TIM16_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* TIM3 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
/* Enable the TIM16 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void STM_EVAL_Tim16Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//unsigned int val;
unsigned int psc;
unsigned int arr;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);
TIM16_Config();
//val = RCC_Clocks.PCLK2_Frequency / (50 * 32);
//psc = (val + 49999) / 50000 - 1;
//arr = (val / (psc + 1)) - 1;
arr= RCC_Clocks.PCLK_Frequency/1600-1;
psc=0;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;//;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure);
/* Prescaler configuration */
TIM_PrescalerConfig(TIM16, psc, TIM_PSCReloadMode_Update);
TIM_SetAutoreload(TIM16, arr);
/* TIM Interrupts enable */
TIM_ITConfig(TIM16, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM16, ENABLE);
}
//-------------stm32f0xx_it.c--------------------
void TIM16_IRQHandler(void)
{
//__disable_irq();
if(TIM_GetITStatus(TIM16, TIM_IT_Update) == SET) {
dmaFlag = 1;
ADC_StartOfConversion(ADC1);
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);
TIM_ClearITPendingBit(TIM16, TIM_IT_Update);
}
//__enable_irq();
}
void DMA1_Channel1_IRQHandler (void)
{
unsigned char i;
//__disable_irq();
if(DMA_GetITStatus(DMA1_IT_TC1) == SET) {
DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, DISABLE);
if (dmaFlag == 1)
{
for(i=0;i<CHANNLE;i++)
{
ad_cvs.buf[i][ad_cvs.sample]=adc1Buf[i];//(adc1Buf[i]>>4) & 0xfff;
}
ad_cvs.sample++;
if(ad_cvs.sample>=SAMPLE_NUM)
{
XtBspAdcTimerStop();
}
dmaFlag = 0;
}
DMA_ClearITPendingBit(DMA1_IT_TC1);
}
//__enable_irq();
}
--------------------------------------------------------------------------------
|
|