STM32 ADC DMA读取AD采样码有时会读到错误的值,但是DMA_Memory里面的值是对的,就一个赋值语句而已,是不是赋值的时候DMA正在对内存写操作?没有使用中断。
#define CONVERTTIMES 14 /*采样次数*/
#define CHANNELQUANITY 4 /*采样通道数*/
#define ADCSampleTime ADC_SampleTime_41Cycles5 /*采样速率*/
static u16 ADCConvertedValue[CONVERTTIMES][CHANNELQUANITY];
//DMA初始化
void DMA1_Init(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCConvertedValue[0];
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = CONVERTTIMES * CHANNELQUANITY;
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);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
//ADC初始化
void ADC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* 配置ADC时钟 72MHz/6=12MHz */
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
/* 配置16个模拟量输入通道 */
GPIO_InitStructure.GPIO_Pin = Pin_ADC_1;
GPIO_Init(GPIO_ADC_1, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Pin_ADC_2;
GPIO_Init(GPIO_ADC_2, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Pin_ADC_3;
GPIO_Init(GPIO_ADC_3, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Pin_ADC_4;
GPIO_Init(GPIO_ADC_4, &GPIO_InitStructure);
/* 配置ADC1工作在DMA模式下 */
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = CHANNELQUANITY;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel configuration */
ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_1, 1, ADCSampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_2, 2, ADCSampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_3, 3, ADCSampleTime);
ADC_RegularChannelConfig(ADC1, ADC_Ch_ADC_4, 4, ADCSampleTime);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
ADC_StartCalibration(ADC1);
//while(ADC_GetCalibrationStatus(ADC1) == SET);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
//Read AD
u16 ReadAD(u8 ch)
{
u8 i;
u32 sum = 0;
for(i=0; i<CONVERTTIMES; i++)
{
tmp = ADCConvertedValue[i][ch];
if(abs(tmp - 1760)>7)
{
aderrodata[0] = tmp;
for (tmp =1;tmp<2000;tmp++)
{
aderrodata[tmp] = ADCConvertedValue[i][ch];
}
tmp = aderrodata[0];
}
sum += tmp;
}
tmp = sum/ CONVERTTIMES;
return (tmp);
}
//问题现象:4个通道的AD采样码都是1760,跳动很小,当跳动大于7的时候加断点,监控发现ADCConvertedValue内的值仍为1760,但是赋值后读出来就变为1768或1772等其他的值,此时再连续读2000次此通道的ADCConvertedValue,发现读到500次左右的时候又能读到正确的值1762
请问版主,大概是什么问题? |