Tengo un MCU STM32F103 y un toque resistivo de 4 cables. este es el circuito que he cableado:
Heescritoestecódigo:
#include"stm32f10x.h"
#include "ili9320.h"
#include "stdio.h"
#define SYSCLK_FREQ_72MHz
uint8_t A = 3,L;
uint16_t read = 0;
char str[15];
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
/* Private functions ---------------------------------------------------------*/
void Pins(void);
void _ADC1(void);
void ReadScaleX(void);
/*******************************************************************************
* Function Name : main
* Description : Main Programme
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
int main(void)
{
/* Initialize the LCD */
ili9320_Initializtion();
/* Clear the LCD */
ili9320_Clear(Yellow);
Pins();
_ADC1();
SysTick_Config(SystemCoreClock/100);
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
/* Infinite loop */
while (1)
{
if(L){
ReadScaleX();
sprintf(str, "%d", read );
ili9320_DisplayStringLine(Line0,(u8 *)"000",White,Blue);
ili9320_DisplayStringLine(Line0,(u8 *)str,White,Blue);
read = 0;
L = 0;
}
}
}
void Pins(void){
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC , ENABLE );
//ADC channels
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOC , &GPIO_InitStructure );
}
void _ADC1(void)
{
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
/* Enable ADC1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_10 , 1, ADC_SampleTime_28Cycles5);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1)){};
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1)){};
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
}
void ReadScaleX(void){
uint8_t i = 0;
/* Changes the pins config
PC0 = +X
PC2 = -X
PC1 = +Y
PC3 = -Y
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_SetBits( GPIOC , GPIO_Pin_1 );
ADC_RegularChannelConfig(ADC1, 10 , 1, ADC_SampleTime_28Cycles5);
for( i=0 ; i<5 ; ++i ){
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus( ADC1 , ADC_FLAG_EOC ) == RESET){};
read += ADC_GetConversionValue(ADC1);
}
read = ((uint32_t)(read*48))/4095;
}
¡Todo está funcionando muy bien, excepto una parte! la entrada ADC! ¡Parece que el ADC se vuelve loco! Acabo de recibir el valor equivocado. O presiono la pantalla o no presiono, me da un valor incorrecto. Depuré el programa y descubrí que la entrada del ADC da un valor incorrecto. Creo que el problema está en la configuración de GPIOs. Me refiero a esta parte:
/ * Cambia la configuración de los pines
PC0 = +X
PC2 = -X
PC1 = +Y
PC3 = -Y
*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //GPIO_Mode_IN_FLOATING
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOC , &GPIO_InitStructure );
GPIO_SetBits( GPIOC , GPIO_Pin_1 );
Para la entrada ADC (PC0), la configuré como GPIO_Mode_AIN
( entrada analógica ) que creo que es correcta, pero dudo de otras partes. en esta función, solo quiero leer el eje X y luego configuré PC1 (+ Y) como push-pull de salida y PC3 (-Y) menú desplegable de entrada y PC2 (-X) como entrada flotante . son correctos?
Se me ocurrió la idea en aquí . ¿Qué piensas?
Edit1: o quizás el problema sea el ADC porque incluso cuando no toco la pantalla, me da un valor extraño. ¿No debería darme 0 en la entrada?
Edit2: Agregué esta línea ili9320_DisplayStringLine(Line0,(u8 *)"000",White,Blue);
en el tiempo principal y ahora está un poco mejor. Solo cambiando entre 1 y 9. Hice dos pruebas simples. Conecté + X a la GND y me mostró solo 0. y gané. Conecté + Y a 3v3 y me mostró entre 169 y 200 en la pantalla LCD depende de dónde presioné la pantalla LCD. [Cambié el código]
Edit3: cambié el código y agregué GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
a cada línea de configuración GPIO y ahora funciona igual que cuando conecté + Y a 3v3 y -Y a GND pero no lo hago saber por qué me muestra que el resultado entre 169 y 200 en la pantalla LCD depende de dónde presioné la pantalla LCD, el voltaje en el pin de entrada es correcto (los cambios dependen de dónde presioné la pantalla LCD)