2019-02-06 06:05 AM
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
2019-02-06 06:21 AM
Sounds like your ADC input is drifting.
> With 1.5 clk cycles the signal on KPAD pin is 1.75V ...
Presumably a coincidence, caused the selected sampling time. As the far-off value for the temperature shows. While 1.5clk sampling cycle is IMHO totally inappropriate for a keypad input.
I don't know the STSPIN hardware, have you checked all jumpers, and verified proper connection up to the GPIO (AIN) ?
2019-02-06 06:43 AM
With the old hardware (same schematic) everything is working fine. With the old hardware, there is not an influence from the sampling time. values are more or less the same independent of sampling time.
At the moment I think there is an influence of silicon version of CPU. Or my SW code has really a problem. But I have different applications with this family and the AD converter implementation was more or less equal in all my SW implementations.
2019-02-06 07:09 AM
As said, I have no experience with the STSPIN hardware.
Is the MCU in both the old and the new hardware the very same ?
This includes the last letter of the type name, that usually specify the package variant / pin number. Different variants (pinouts) often use different pins for specific IO purposes.
And peripherals (like the ADC) are often very similar across all MCU variants, but sometimes differ in certain specifics.
2019-02-06 07:55 AM
MCU old and new is the same. Only the last letter. I think revision of ST is different only.
2019-02-11 01:21 AM
The problem is solved. Because of wrong assembly, on AD0 was a voltage over 3.3V.
That mean: if any AD channel has a value outside specification this behavior can happen and wrong values can be measured on any other channel. Also the internal temperature sensor can be wrong.
2019-02-11 01:42 AM
If I understand you correctly, basically a violation of the specs, causing a discharge current through the input protection elements at the GPIO.
That wouldn't be surprising, I came to know this effect with many other devices.