STM32
直播中

王婷

7年用户 1019经验值
私信 关注
[问答]

DMA ADC多通道采样数据错位的原因?


  •   
  • volatile unsigned int  After_filter[16];    //ÓÃÀ´´æ·ÅÇóƽ¾ùÖµÖ®ºóµÄ½á¹û


  • void ADC1_GPIO_Config(void);
  • void ADC1_Mode_Config(void);
  • void ADC1_DMA_Init(void);

  • void ADC1_Init(void)
  • {
  •         ADC1_DMA_Init();
  •         ADC1_GPIO_Config();
  •         ADC1_Mode_Config();

  • }
  • //Ñ¡ÓÃADCµÄͨµÀ  0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
  • //·Ö±ð¶ÔÓ¦¹Ü½Å   PA0 PA1 PA2 PA3 PA4 PA5 PA6 PA7 PB0 PB1 PC0 PC1 PC2 PC3 PC4 PC5
  • //¶ÔÓ¦¹¦ÄÜ       OCE OCF OCG OCH OVA OVB OVC OVD OVG OVH OCA OCB OCC OCD OVE OVF
  • void ADC1_GPIO_Config(void)
  • {
  •         GPIO_InitTypeDef GPIO_InitStructure;
  •         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
  •                                RCC_APB2Periph_GPIOC |RCC_APB2Periph_AFIO ,ENABLE);//¹¦Äܸ´ÓÃIOʱÖÓ

  •         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  •         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//Ä£ÄâÊäÈë
  •         GPIO_Init(GPIOA, GPIO_InitStructure);//PA0 1 2 3 4 5 6 7

  •         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1;
  •         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//Ä£ÄâÊäÈë
  •         GPIO_Init(GPIOB, GPIO_InitStructure);//PB0 1

  •         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 ;
  •         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//Ä£ÄâÊäÈë
  •         GPIO_Init(GPIOC, GPIO_InitStructure);//PC0 1 2 3 4 5
  • }
  • void ADC1_DMA_Init(void)
  • {
  •   DMA_InitTypeDef DMA_InitStructure;
  •   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//ʹÄÜDMAʱÖÓ
  • ///**************************DMAͨµÀ1ÅäÖÃ****************************/////
  •         DMA_DeInit(DMA1_Channel1);//DMAͨµÀ1³õʼ»¯
  •         DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//ADCµØÖ·
  •         DMA_InitStructure.DMA_MemoryBaseAddr = (u32) After_filter;//ÄÚ´æµØÖ·
  •         DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//ÍâÉèΪÊý¾ÝÔ´
  •         DMA_InitStructure.DMA_BufferSize = 16;//MAX_ADC_CH*GET_ADC_NMB;
  •         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;//Ñ shy;»·´«Êä
  •         DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  •         DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  •         DMA_Init(DMA1_Channel1, DMA_InitStructure);
  •         DMA_Cmd(DMA1_Channel1,ENABLE);
  • }

  • void ADC1_Mode_Config(void)
  • {

  •         ADC_InitTypeDef ADC_InitStructure;
  •   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 ,ENABLE);//ʹÄÜADC1ʱÖÓ
  •         //*******************************ADC1ÅäÖÃ**********************///
  •         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//¶ÀÁ¢ADCģʽ
  •         ADC_InitStructure.ADC_ScanConvMode = ENABLE;//½ûֹɨÃèģʽ£¬É¨ÃèģʽÓÃÓÚ¶àͨµÀ²É¼¯
  •         ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//¿ªÆôÁ¬Ðøģʽ£¬¼´²»Í£µÄ½øÐÐADCת»»
  •         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//²»Ê¹ÓÃÍⲿ´¥·¢×ª»»
  •         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//²É¼¯Êý¾ÝÓÒ¶ÔÆë
  •         ADC_InitStructure.ADC_NbrOfChannel = 8;//Ҫת»»µÄͨµÀÊýÄ¿
  •         ADC_Init(ADC1,  ADC_InitStructure);

  •         RCC_ADCCLKConfig(RCC_PCLK2_Div8);//ÅäÖÃADCʱÖÓ£¬ÎªPCLK2µÄ8·ÖƵ£¬¼´9MHz

  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_10,   1,  ADC_SampleTime_55Cycles5);                      //ADC4   PC0                 µçÁ÷1
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_11,   2,  ADC_SampleTime_55Cycles5);                      //ADC5   PC1     µçÁ÷2
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_12,   3,  ADC_SampleTime_55Cycles5);                      //ADC2   PC2     µçÁ÷3
  •         ADC_RegularChannelConfig(ADC1, ADC_Channel_13,   4,  ADC_SampleTime_55Cycles5);                      //ADC3   PC3     µçÁ÷4
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_0,    5,  ADC_SampleTime_55Cycles5);                      //ADC12  PA0     µçÁ÷5
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_1,    6,  ADC_SampleTime_55Cycles5);                      //ADC13  PA1     µçÁ÷6
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_2,    7,  ADC_SampleTime_55Cycles5);                      //ADC11  PA2     µçÁ÷7
  •   ADC_RegularChannelConfig(ADC1, ADC_Channel_3,    8,  ADC_SampleTime_55Cycles5);                      //ADC10  PA3     µçÁ÷8

  •         ADC_DMACmd(ADC1,ENABLE);
  •         ADC_Cmd(ADC1,ENABLE);

  •         ADC_ResetCalibration(ADC1);//¸´Î»Ð£×¼¼Ä´æÆ÷
  •         while(ADC_GetResetCalibrationStatus(ADC1));//µÈ´ýУ׼¼Ä´æÆ÷¸´Î»Íê³É
  •         ADC_StartCalibration(ADC1);//ADCУ׼
  •         while(ADC_GetCalibrationStatus(ADC1));//µÈ´ýУ׼Íê³É

  •         ADC_SoftwareStartConvCmd(ADC1,ENABLE);//ÓÉÓÚûÓвÉÓÃÍⲿ´¥·¢£¬ËùÒÔʹÓÃÈí¼þ´¥·¢ADCת»»
  • }
  • void pid_task(void *pdata)
  • {
  •         float temp=0;
  •         pdata = pdata;
  •         ADC1_Init();             //ADC³õʼ»¯
  •         OSTimeDlyHMSM(0, 0, 0, 100);//ÑÓʱ0.1Ãë
  •         for(;;)
  •         {

  •           OSTimeDlyHMSM(0, 0, 0, 10);//ÑÓʱ1Ãë

  •                 TIM_SetCompare1(TIM1, After_filter[0]);
  •                 TIM_SetCompare2(TIM1, After_filter[1]);
  •                 TIM_SetCompare3(TIM1, After_filter[2]);
  •                 TIM_SetCompare4(TIM1, After_filter[3]);
  •                 TIM_SetCompare3(TIM2, After_filter[4]);
  •                 TIM_SetCompare4(TIM2, After_filter[5]);
  •                 TIM_SetCompare1(TIM4, After_filter[6]);
  •                 TIM_SetCompare2(TIM4, After_filter[7]);

  •         }
  • }


回帖(1)

王越建

2024-5-8 17:38:34
DMA (Direct Memory Access) ADC (Analog-to-Digital Converter) 多通道采样数据错位的原因可能有以下几点:

1. **时钟同步问题**:如果ADC采样和DMA传输之间的时钟不同步,可能会导致数据错位。

2. **DMA配置错误**:如果DMA的配置不正确,例如源地址、目标地址、传输大小等设置错误,可能会导致数据错位。

3. **中断处理不当**:如果DMA传输过程中的中断处理不当,可能会导致数据传输中断,从而引起数据错位。

4. **硬件故障**:如果ADC或DMA硬件存在故障,也可能导致数据错位。

5. **软件bug**:程序中可能存在bug,导致数据处理不当,从而引起数据错位。

6. **数据缓冲区溢出**:如果数据缓冲区大小设置不当,可能会导致数据溢出,从而引起数据错位。

7. **多任务环境下的并发问题**:在多任务环境下,如果任务调度不当,可能会导致数据错位。

8. **电源噪声干扰**:电源噪声可能会影响ADC的采样精度,从而导致数据错位。

9. **电磁兼容性问题**:电磁兼容性问题可能会导致数据传输过程中的干扰,从而引起数据错位。

10. **采样速率不匹配**:如果ADC的采样速率与DMA的传输速率不匹配,可能会导致数据错位。

在您提供的代码片段中,我注意到您调用了`ADC1_DMA_Init()`、`ADC1_GPIO_Config()`和`ADC1_Mode_Config()`函数。这些函数的实现细节对于确定数据错位的原因至关重要。例如,DMA初始化函数中的配置参数、GPIO配置以及ADC模式配置都可能影响数据的传输和采样。

为了解决这个问题,您需要检查以下几个方面:

1. **检查DMA配置**:确保DMA的源地址、目标地址、传输大小等配置正确。

2. **检查中断处理**:确保DMA传输过程中的中断处理正确,没有导致数据传输中断。

3. **检查硬件**:检查ADC和DMA硬件是否存在故障。

4. **检查程序逻辑**:检查程序中是否存在bug,导致数据处理不当。

5. **检查数据缓冲区大小**:确保数据缓冲区大小设置适当,避免数据溢出。

6. **检查多任务环境下的任务调度**:在多任务环境下,确保任务调度正确,避免并发问题。

7. **检查电源和电磁兼容性**:确保电源稳定,电磁兼容性良好。

8. **检查采样速率匹配**:确保ADC的采样速率与DMA的传输速率匹配。

通过以上步骤,您应该能够找到导致数据错位的原因,并采取相应的措施解决问题。
举报

更多回帖

相关问答

dma ADC 多通道
发帖
登录/注册
×
20
完善资料,
赚取积分