Edmond
Edmond

Reputation: 163

Mixed voltage reading from different AD7606 channels

Please help! I am using FSMC to connect a STM32F407 MCU with AD7606 to sample voltage value. MCU would send sampled values to PC using USB HS port after 1024 conversions. But when I inspect the values from PC, I found that readings from channel 0 occasionally contains data from other channels. For example, if connect channel 0 to 5v, connect channel 8 to 3.3v, connect other channels to ground. Then the printed value from channel 0 would contain 5v, 0v, 3.3v. The basic setup is as follows:

  1. A 200KHZ PWM single is generated by TIM10 to act as CONVST signal for AD7606.
    7606 will then issue a BUSY signal which I used as an external interrupt source.
  2. In the Interrupt handler, An DMA request would be issued to read 8 16bit data
    from FSMC address space to memory space. TIM10 PWM would be stopped if 1024
    conversions has been done.
  3. In the DMA XFER_CPLT call back, if 1024 conversions has been done, the converted
    data would be sent out by USB HS port, and TIM10 PWM would be enabled again.

Some code blocks:

    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    {
        if(GPIO_Pin == GPIO_PIN_7)
        {
            // DMA data from FSMC to memory
            HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream0, 0x6C000000, (uint32_t)(adc_data + adc_data_idx) , 8);
    
            adc_data_idx += 8;
    
            if (adc_data_idx >= ADC_DATA_SIZE)
                HAL_TIM_PWM_Stop(&htim10, TIM_CHANNEL_1);
        }

    }

    void dma_done(DMA_HandleTypeDef *_hdma)
    {
        int i;
        int ret;
        
        // adc_data[adc_data_idx] would always contain data from 
        // channel 1, led1 wouldn't light if every thing is fine.
        if (adc_data[adc_data_idx] < 0x7f00 )
                HAL_GPIO_WritePin(led1_GPIO_Port, led1_Pin, GPIO_PIN_SET);
    
        if (adc_data_idx >= ADC_DATA_SIZE)
        {
            if(hUsbDeviceHS.dev_state == USBD_STATE_CONFIGURED)
            {
                // if I don't call CDC_Transmit_HS, everything is fine.
                ret = CDC_Transmit_HS((uint8_t *)(adc_data), ADC_DATA_SIZE * 2 );
                if (ret != USBD_OK)
                {
                    HAL_GPIO_WritePin(led1_GPIO_Port, led2_Pin, GPIO_PIN_SET);
                }
            }
        
            adc_data_idx = 0;
        
            HAL_TIM_PWM_Start(&htim10, TIM_CHANNEL_1);
        
         }
     }

It seems that a single USB transaction would take longer than 5us(one conversion time), so I stopped PWM signal to stop conversion...
If I only send the second half of the data buffer, there is no data mixture. It's very strange.

Upvotes: 0

Views: 486

Answers (1)

jackieBB
jackieBB

Reputation: 125

According to your description, I think the processing is correct, and the problem is at the CDC_Transmit_HS(); I have met the problem on the CDC_Transmit_FS(), which can't transmit more than 64 bytes data for original code, and need to modify some code, otherwise the some error occurs. Did you check the number of received data is correct?

Reference: I can't receive more than 64 bytes on custom USB CDC class based STM32 device

I'm not sure your ADC_DATA_SIZE size; if it's larger than 64 bytes, maybe you can modify to smaller than 64 bytes and try again and check whether or not the data is correct. I am not sure if it is affected by this problem, but I think you can give it a try.

On the other hand, it may also be necessary to GND the ADC IN pins not used by AD7606 to avoid interference between channels.

Or you can try other communication (I2C, SPI, UART...etc) to send the data.

If there is no problem with other communication methods, there is a high chance that it is a problem with CDC_Transmit_HS(). If there are problems with other transmission methods, you may have to check whether there is a conflict between the ADC conversion time or the transmission time.

Upvotes: 0

Related Questions