cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 ADC LCD WITHOUT CONTROLER

boby6613
Associate II
Posted on April 25, 2012 at 10:18

Hi,

I want to communicate with my touch screen without controler.

I can display pictures, lines, colors, circles, texts...

I've a 4-wire resistive touch screen on my lcd (4,3'' TFT COLOR).

For the moment, I can see the voltage on the multimeter with this code.

void TFT_43M_TACTIL_X (void)

{

            GPIO_InitTypeDef GPIO_InitStruct;

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;  //Touch screen x2

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;

            GPIO_Init(GPIOC,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //Touch screen y2

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;

            GPIO_Init(GPIOC,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;  //Touch screen x1

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;

            GPIO_Init(GPIOB,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //Touch screen y1

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;

            GPIO_Init(GPIOB,&GPIO_InitStruct);

            //(*GPIOC).BSRR=0x00000002;   // bit 1 en sortie port C==> X2

            GPIO_SetBits(GPIOC,GPIO_Pin_1); // bit 1 en sortie port C==> X2

}

void TFT_43M_TACTIL_Y (void)

{

            GPIO_InitTypeDef GPIO_InitStruct;

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;  //Touch screen x2

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;

            GPIO_Init(GPIOC,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //Touch screen y2

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;

            GPIO_Init(GPIOC,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;  //Touch screen x1

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;

            GPIO_Init(GPIOB,&GPIO_InitStruct);

            GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //Touch screen y1

            GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

            GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;

            GPIO_Init(GPIOB,&GPIO_InitStruct);

            //(*GPIOC).BSRR=0x00000001;   // bit 0 en sortie port C==> Y2

            GPIO_SetBits(GPIOC,GPIO_Pin_0); // bit 0 en sortie port C==> Y2

}           

Now I want to configure the ADC and try to use the touchscreen, but I've no idea how to do this?

If you can help me.

Thank you

Boby

#touch-screen
8 REPLIES 8
alok472
Associate II
Posted on April 25, 2012 at 17:39

1. Suggest to start with ADC examples in Std peripheral lib

2. ADC Window Watchdog can be good idea to generate Interrupt when a touch is detected

boby6613
Associate II
Posted on April 25, 2012 at 21:42

1.I've found this :

void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; /* PCLK2 is the APB2 clock */ /* ADCCLK = PCLK2/6 = 72/6 = 12MHz*/ RCC_ADCCLKConfig(RCC_PCLK2_Div6); /* Enable ADC1 clock so that we can talk to it */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* Put everything back to power-on defaults */ ADC_DeInit(ADC1); /* ADC1 Configuration ------------------------------------------------------*/ /* ADC1 and ADC2 operate independently */ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /* Disable the scan conversion so we do one at a time */ ADC_InitStructure.ADC_ScanConvMode = DISABLE; /* Don't do contimuous conversions - do them on demand */ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; /* Start conversin by software, not an external trigger */ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /* Conversions are 12 bit - put them in the lower 12 bits of the result */ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /* Say how many channels would be used by the sequencer */ ADC_InitStructure.ADC_NbrOfChannel = 1; /* Now do the setup */ ADC_Init(ADC1, &ADC_InitStructure); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); }
2.''ADC Window Watchdog can be good idea to generate Interrupt when a touch is detected''
Can you explain how to do this?
Thank you 

raptorhal2
Lead
Posted on April 25, 2012 at 22:46

You are asking us to design your program for you. That is your task.

Read the ADC section of the Reference Manual to learn how the ADC works. You have initialized ADC1 to one unspecified channel. The Peripheral Library examples shows how to specify the channels to convert. Your touch screen apparently needs Channels 8, 9, 10 and 11 converted. Read the data sheet for the touch screen to determine what the signals mean, then figure out what your program needs to do with those signals.

Cheers, Hal

boby6613
Associate II
Posted on April 26, 2012 at 09:10

NoI don't want that you design the program for me.

As I said, I had already design some task on my screen. (color, line...).

But I have some dificulties with the touchscreen, and I have no information about the touchscreen.

Thank you.

________________

Attachments :

WF43BTIBEDA.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HtX6&d=%2Fa%2F0X0000000aRN%2FDARILqr_YKQzsoFS6JDNDK_K7CkM6GbUf0Zovyj5Ml0&asPdf=false
alok472
Associate II
Posted on April 26, 2012 at 12:28

You can refer to the datasheet of STMPE811 touch screen controller. It is faster to use a dedicated controller than to develop a software based solution. Anyway some explaination from this datasheet can be useful for you for sw implementation as well.

boby6613
Associate II
Posted on April 27, 2012 at 10:15

Yes, i know that is better to use a controller.

But the hardware is done.

I have configured my ADC  :

 /* DMA1 channel1 configuration ----------------------------------------------*/

  DMA_DeInit(DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC1_DR_Address;

  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_DualConvertedValueTab;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 16;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  /* Enable DMA1 Channel1 */

  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 2;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channels configuration */

  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);   

  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

  /* ADC2 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 2;

  ADC_Init(ADC2, &ADC_InitStructure);

  /* ADC2 regular channels configuration */

  ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);

  ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 2, ADC_SampleTime_239Cycles5);

  /* Enable ADC2 external trigger conversion */

  ADC_ExternalTrigConvCmd(ADC2, ENABLE);

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  /* Enable Vrefint channel17 */

  ADC_TempSensorVrefintCmd(ENABLE);

  /* Enable ADC1 reset calibaration register */  

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  while(ADC_GetCalibrationStatus(ADC1));

  /* Enable ADC2 */

  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC2 reset calibaration register */  

  ADC_ResetCalibration(ADC2);

  /* Check the end of ADC2 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibaration */

  ADC_StartCalibration(ADC2);

  /* Check the end of ADC2 calibration */

  while(ADC_GetCalibrationStatus(ADC2));

  /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  /* Test on DMA1 channel1 transfer complete flag */

  while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));

  /* Clear DMA1 channel1 transfer complete flag */

  DMA_ClearFlag(DMA1_FLAG_TC1);

But my question is now that my ADC is configured. How can I make to read my ADCvalue (ADC12_IN11-ADC12_IN9 == X2-X1 == a value that I need to convert)?

Thank you

 

frankmeyer9
Associate II
Posted on April 27, 2012 at 12:57

I suggest to configure an interrupt after each DMA transfer completion.

Just process the values in the buffer you provided for the DMA transfer.

    /* NVIC DMA interrupt setup */

    NVIC_InitStructure.NVIC_IRQChannel                   = DMA1_Channel1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

and later :

    /* Enable DMA1 Channel Transfer Complete interrupt*/

    DMA_ITConfig (DMA1_Channel1, DMA_IT_TC, ENABLE);

From: sarzon.boby

Posted: Friday, April 27, 2012 10:15 AM

Subject: STM32F1 ADC LCD WITHOUT CONTROLER

Yes, i know that is better to use a controller.

But the hardware is done.

I have configured my ADC  :

 /* DMA1 channel1 configuration ----------------------------------------------*/

  DMA_DeInit(DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)ADC1_DR_Address;

  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_DualConvertedValueTab;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 16;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  /* Enable DMA1 Channel1 */

  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 2;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channels configuration */

  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);   

  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_239Cycles5);

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

  /* ADC2 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 2;

  ADC_Init(ADC2, &ADC_InitStructure);

  /* ADC2 regular channels configuration */

  ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 1, ADC_SampleTime_239Cycles5);

  ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 2, ADC_SampleTime_239Cycles5);

  /* Enable ADC2 external trigger conversion */

  ADC_ExternalTrigConvCmd(ADC2, ENABLE);

  /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  /* Enable Vrefint channel17 */

  ADC_TempSensorVrefintCmd(ENABLE);

  /* Enable ADC1 reset calibaration register */  

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  while(ADC_GetCalibrationStatus(ADC1));

  /* Enable ADC2 */

  ADC_Cmd(ADC2, ENABLE);

  /* Enable ADC2 reset calibaration register */  

  ADC_ResetCalibration(ADC2);

  /* Check the end of ADC2 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibaration */

  ADC_StartCalibration(ADC2);

  /* Check the end of ADC2 calibration */

  while(ADC_GetCalibrationStatus(ADC2));

  /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  /* Test on DMA1 channel1 transfer complete flag */

  while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));

  /* Clear DMA1 channel1 transfer complete flag */

  DMA_ClearFlag(DMA1_FLAG_TC1);

But my question is now that my ADC is configured. How can I make to read my ADCvalue (ADC12_IN11-ADC12_IN9 == X2-X1 == a value that I need to convert)?

Thank you

 

raptorhal2
Lead
Posted on April 27, 2012 at 15:50

It will be simpler if you use ADC1 to convert 4 channels into the DMA buffer, and not use ADC2. The 4 channel conversion time will still be much shorter than human touch time.

How does the screen notify the processor that a touch is happening ? That notification should be used by your program to start the conversion. If the only notification is a change in the 4 analog channels, then you need to frequently convert and analyze to determine when something has happened. Alokm's suggestion of using Analog Watchdog is a good suggestion. The channel selection is 1 or all, injected or normal, so verify that will not conflict with whatever else you have in mind for the ADC.

Cheers, Hal