2019-02-28 09:57 AM
I have written some codes to work with ADC Of STM32F103RE MCU, the problem is there which when I write this codes the result is 4059 for untouched and around 3585 when touched.
The Codes:
void ADC_DMA_init(void) {
//enable DMA1 clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//create DMA structure
DMA_InitTypeDef DMA_InitStructure;
//reset DMA1 channe1 to default values;
DMA_DeInit(DMA1_Channel1);
//channel will be used for memory to memory transfer
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
//setting normal mode (non circular)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//medium priority
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//source and destination data size word=32bit
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//automatic memory destination increment enable.
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//source address increment disable
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//Location assigned to peripheral register will be source
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//chunk of data to be transfered
DMA_InitStructure.DMA_BufferSize = 2;
//source and destination start addresses
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;;
//adc values is: volatile uint16_t ADC_values[ARRAYSIZE];
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;
//send values to DMA registers
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// Enable DMA1 Channel Transfer Complete interrupt
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1
}
uint16_t Get_ADC_Converted_Value()//int Get_ADC_Converted_Value()
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
return ADC_GetConversionValue(ADC1);
}
}
/**
* Initialization of ADC and the poentiomenter's GPIO
*/
uint16_t badprogADC() {
/// declaring GPIO stuff
GPIO_InitTypeDef GPIO_InitStructure;
// declaring ADC struct
ADC_InitTypeDef ADC_InitStructure;
// deinit ADC
ADC_DeInit(ADC1);
// enabling clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// enabling ADC clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
// B - Init the GPIO with the structure - Testing ADC
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AIN;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//The pins are configured in analog mode
GPIO_Init(GPIOB, &GPIO_InitStructure);
//GPIO_ResetBits(GPIOB,GPIO_Pin_7);
//GPIO_ResetBits(GPIOB,GPIO_Pin_6);
// init ADC struct
ADC_StructInit(&ADC_InitStructure);
// setting the ADC struct
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = 0;//ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_DMA_init();
// init adc
ADC_Init(ADC1, &ADC_InitStructure);
// enable ADC
ADC_Cmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, DISABLE);
/* Enable DMA mode for ADC1 */
ADC_DMACmd(ADC1, ENABLE);
// start ADC1 calibration and check the end
ADC_StartCalibration(ADC1);
// configure ADC_IN6
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_7Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 1, ADC_SampleTime_7Cycles5); ///added
// start ADC -> retrieve the ADC value from the potentiometer
// and add it into ADC1->DR with:
// ADCx->CR2 |= CR2_EXTTRIG_SWSTART_Set;
// this without using ADC1->DR o_O
// CR2 = Configuration Register2 -> it seems to be a config with
// a binary number -> for example 1000010100101010 which sets all
// registers with default values
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// Make sure we have conversion completion
while( ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC ) == RESET )
{
// do nothing (or something useful perhaps)
}
// Wait until ADC is ready
//while (ADC_GetFlagStatus(ADC1, ADC_FLAG_ADONS) == RESET);
// check the end of the ADC1 calibration
// setting ADC1->DR with:
// if ((ADCx->CR2 & CR2_CAL_Set) != (uint32_t)RESET)
while (ADC_GetCalibrationStatus(ADC1) == SET);
// Reset the flag
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
// convert valueADC to valueVolt -> valueADC * (MAX VOLT / 2^12)
// and also :
// ADC_SoftwareStartConvCmdsoftwareS,
// ADC_GetCalibrationStatus
// with
// return (uint16_t) ADCx->DR;
uint16_t valueADC = ADC_GetConversionValue(ADC1);
// convert the "uint_16 valueADC" into a "float valueVolt"
// Volt = 3.3
// ADC = 12 bits, so 2^12 = 4096
float valueVolt = valueADC * (3.3 / 4095);
//return valueVolt;
//return ADC_GetConversionValue(ADC1);
return ADC1ConvertedValue[0];
//return Get_ADC_Converted_Value();
}
And by changing the two last line of codes to this kind:
//return ADC1ConvertedValue[0];
return Get_ADC_Converted_Value();
Touch shown 0 for untouched and around 3940 for touched.
Some part of main function is shown Below:
while (1) {
GUI_Clear();
GUI_SetBkColor(GUI_BLACK);
GUI_SetColor(GUI_CYAN);
sprintf(buffer, "%d\r\n", (int) TouchScreen_readPressure());GUI_Delay(300);
// GUI_Init(); GUI_Delay(300);
GUI_DispStringHCenterAt(buffer, xSize / 3, ySize - 111); GUI_Delay(300);
GUI_DispStringAt("GUI_DispFloat:\n", 11, 11);
GUI_GotoX(100);
GUI_GotoY(100);
//f=(float) TouchScreen_readPressure();
//GUI_DispFloat(f,9);
GUI_Delay(300);
}
So why this happended?
this question in stackowerflow:
https://electronics.stackexchange.com/questions/424898/adc-stm32f013re-default-is-high-4059
Thanks