STSPIN32F0 AD Converter problem: There is a difference between different silicon variant.
- February 6, 2019
- 4 replies
- 1684 views
I use STSPIN32F0 since over 2 years. In the last assembly I have a problem with wrong AD values. So SW is in the older and in the newer hardware equal. The problem is so strange.
Attached is the schematic of Keypad Input which is connected to PB1 (AD9). I have no external components on connector J5. So at the output KPAD it must be 1.65V.
With the old HW (STPIN32F0 FN01V) I have these 1.65V allways. With the new Hardware (STSPIN32F0 FN01F) I have 1.65V only if processor is in reset state or AD converter is not started. If I start the AD Converter, the voltage on KPAD pin is increasing up to 2.25V. Also I see the wrong value with the emulator.
I also convert the internal temperature sensor with the old HW I have around 1744 (12-Bit AD value) with the new hardware I always measure 4095 AD value. So the problem seems to be not only on external AD inputs. It is also on internal temperature sensor.
Important to know is: Same software is running on older hardware.
I I change the AD sampling time, the result of AD values is changing. My description above is with 55.5 cycles. But with the new hardware I do not have an error free signal. As longer the sampling time as bigger the error on KPAD signal. With the longest sampling time I have 3.3V on KPAD signal when AD converter is working. With 1.5 clk cycles the signal on KPAD pin is 1.75V, but temperature sensor signal is still completely wrong.
Below you find my code part for the AD converter.
Hope somebody can help to find the problem.
Thank you for help.
Franz
Initialization of AD channels:
// ************ ADC PA0-4 PB1 ******************************************
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
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_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
Initialisation of AD converter:
void ADC_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_DeInit(ADC1); // ADCs DeInit
DMA_DeInit(DMA1_Channel1); //DMA1 Channel1 Config
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ui16ADResult;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 7;
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_Cmd(DMA1_Channel1, ENABLE); //DMA1 Channel1 enable
ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular); //ADC DMA request in circular mode
ADC_DMACmd(ADC1, ENABLE); //Enable ADC_DMA
ADC_StructInit(&ADC_InitStructure); //Initialize ADC structure
ADC_VrefintCmd(ENABLE);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // Conversions Triggered
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_ChannelConfig(ADC1, ADC_Channel_0 | ADC_Channel_1 | ADC_Channel_2 | ADC_Channel_3 | ADC_Channel_4 | ADC_Channel_9 | ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles); //Convert the ADC1 Channel
// ADC_ChannelConfig(ADC1, ADC_Channel_0 | ADC_Channel_1 | ADC_Channel_2 | ADC_Channel_3 | ADC_Channel_4 | ADC_Channel_9 | ADC_Channel_TempSensor , ADC_SampleTime_1_5Cycles); //Convert the ADC1 Channel
ADC_TempSensorCmd(ENABLE);
ADC_VrefintCmd(ENABLE);
ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular); //Enable DMA request after last transfer (Single-ADC mode)
ADC_GetCalibrationFactor(ADC1); //ADC Calibration
ADC_Cmd(ADC1, ENABLE); //Enable ADCperipheral[PerIdx]
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); //Wait the ADCEN flag
ADC_StartOfConversion(ADC1); //ADC1 regular Software Start Conv
}
I call the AD converter in a 0.1ms IRQ. There are no AD interrupts.
AD_avr(); //get the values and calculate average values
ADC_StartOfConversion(ADC1); //manually restart of AD converter
