📄 touchscreen.c
字号:
#include "public.h"
#define ADC1_DR_Address ((u32)0x4001244C)
volatile u16 touch_timer = 0;
volatile u8 touch_state = 0x00;
volatile u16 touch_x = 0;
volatile u16 touch_y = 0;
//volatile u16 touch_adc_time = 0;
//volatile u32 touch_adc_summer = 0;
volatile u16 adc_buffer[20];
u16 tch_para[4];
#define txb tch_para[0]
#define txk tch_para[1]
#define tyb tch_para[2]
#define tyk tch_para[3]
/*用于判断触屏是否被触摸,不会产生中断 */
void en_check_touch(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*Configure x0 as ouput low*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_ResetBits(TOUCH_SCREEN_PORT, TOUCH_SCREEN_X0);
/*Configure y0 as input pu*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_Y0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
/*Configure PC.02 PC.03 as input floating*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X1 | TOUCH_SCREEN_Y1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
}
/*有触屏被触摸时产生中断*/
void en_touch_init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
touch_state = 0x00;
EXTI_ClearITPendingBit(TOUCH_SCREEN_EXTI_LINE);
en_check_touch();
GPIO_EXTILineConfig(TOUCH_SCREEN_PORTSOURCE, TOUCH_SCREEN_PINSOURCE);
/* ENABLE the EXTI1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitStructure.EXTI_Line = TOUCH_SCREEN_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void ADC1_Calibration(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
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 = 1;
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));
}
/*为取得触摸点的X座标做准备*/
void get_touch_x(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//touch_adc_time = 0;
//touch_adc_summer = 0;
/*Configure x0 as ouput low*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_ResetBits(TOUCH_SCREEN_PORT, TOUCH_SCREEN_X0);
/*Configure x1 as ouput hihg*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_SetBits(TOUCH_SCREEN_PORT, TOUCH_SCREEN_X1);
/*Configure y0 as input floating*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_Y0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
/*Configure y1 as anlog input*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_Y1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_EXTILineConfig(TOUCH_SCREEN_PORTSOURCE, 0);
/*init DMA*/
Init_DMA();
/* ADC1 regular channel13 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 1, ADC_SampleTime_55Cycles5);
/* Disable EOC interupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*为取得触摸点的Y座标做准备*/
void get_touch_y(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//touch_adc_time = 0;
//touch_adc_summer = 0;
/*Configure y0 as ouput low*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_Y0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_ResetBits(TOUCH_SCREEN_PORT, TOUCH_SCREEN_Y0);
/*Configure y1 as ouput hihg*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_Y1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_SetBits(TOUCH_SCREEN_PORT, TOUCH_SCREEN_Y1);
/*Configure x0 as input floating*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
/*Configure x1 as anlog input*/
GPIO_InitStructure.GPIO_Pin = TOUCH_SCREEN_X1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(TOUCH_SCREEN_PORT, &GPIO_InitStructure);
GPIO_EXTILineConfig(TOUCH_SCREEN_PORTSOURCE, 0);
/*init DMA*/
Init_DMA();
/* ADC1 regular channel11 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
/* Disable EOC interupt */
ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void dis_touch_init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_ClearITPendingBit(TOUCH_SCREEN_EXTI_LINE);
EXTI_InitStructure.EXTI_Line = TOUCH_SCREEN_EXTI_LINE;
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Init_DMA(void)
{
//ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)adc_buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 15;
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_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC | DMA_IT_TE, ENABLE);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
}
uint8_t get_tch_data(void)
{
uint8_t i;
uint16_t tmp,add = 0xaa,xor = 0x55;
//uint16_t pet = (uint16_t)ee_tch_paras;
uint16_t * pt = (uint16_t *)tch_para;
for(i = 0;i<4;i++)
{
//tmp = eeprom_read_word((const void *)pet);
tmp = *(vu16*)(EPARA_ADDR + i + i);
//pet += 2;
add += tmp;
xor ^= tmp;
*pt++ = tmp;
}
//if(add != eeprom_read_word((const void *)pet))
if(*(vu16*)(EPARA_ADDR + 8) != add)
{
return 0;
}
//pet += 2;
//if(xor != eeprom_read_word((const void *)pet))
if(*(vu16*)(EPARA_ADDR + 10) != xor)
{
return 0;
}
return 0xff;
}
uint16_t get_delta(uint16_t d1,uint16_t d2)
{
if(d1>d2)
{
return (d1-d2);
}
else
{
return (d2-d1);
}
}
/*校正触摸屏*/
void cali_touch(void)
{
uint16_t ctd[4];
uint8_t i;
lcm_set_access_2layers();
lcm_clr();
lcm_set_access_layer1();
lcm_set_1fn();
//取20,20点的ADC值
lcm_set_text_mode()
display_ram_string(10,16,"请准确触碰左上角的靶心",0x20);
get_cali_data(20,20,ctd);
//取300,220点的ADC值
lcm_set_text_mode()
display_ram_string(10,16,"请准确触碰右下角的靶心",0x20);
get_cali_data(300,220,ctd+2);
//计算校正参数
txk = ctd[2] - ctd[0];
txk /= 280;
tyk = ctd[3] - ctd[1];
tyk /= 200;
txb = ctd[0] - 20 * txk;
tyb = ctd[1] - 20 * tyk;
display_ram_string(10,16,"已经计算出触摸屏参数 ",0x20);
display_ram_string(10,32,"可以在下面的方框内测试",0x20);
display_ram_string(3,217,"保存触摸屏参数",0x20);
display_ram_string(23,217,"放弃触摸屏参数",0x20);
lcm_set_graph_mode()
rectangle(5,50,315,210,1,0);
rectangle(16,215,144,235,1,0);
rectangle(176,215,304,235,1,0);
/* circle(20,20,5,1,0);
circle(20,20,10,1,0);
line(5,20,35,20,1);
line(20,5,20,35,1);
lcm_set_graph_mode();
circle(300,220,5,1,0);
circle(300,220,10,1,0);
line(285,220,315,220,1);
line(300,205,300,235,1);*/
//用新计算的参数进行设置
en_touch_init();
while(1)
{
if(get_touch())
{
if(touch_x>5 && touch_x<315 && touch_y>50 && touch_y<210)
{
//beeper_on();
//beeper_timer = 50;
point(touch_x,touch_y,1);
}
else if(touch_x>16 && touch_x<144 && touch_y>215 && touch_y<235)
{
// //转去保存校正参数
// break;
}
else if(touch_x>176 && touch_x<304 && touch_y>215 && touch_y<235)
{
// //放弃保存,重启系统
// soft_reset();
}
}
}
while(1)
{
uint16_t * pt = (uint16_t *)tch_para;
uint16_t add=0xaa,xor=0x55;
FLASH_Unlock();
if(FLASH_COMPLETE != FLASH_ErasePage(EPARA_ADDR))
{
/////////////////////////////////////////////////////////////
while(1)
{
}
}
for(i=0; i<4; i++)
{
add += *pt;
xor ^= *pt;
//eeprom_write_word((uint16_t *)pet,*pt++);
if(FLASH_COMPLETE != FLASH_ProgramHalfWord(EPARA_ADDR + i + i, *(pt++)))
{
while(1)
{
}
};
// pet += 2;
}
// eeprom_write_word((uint16_t *)pet,add);
// pet += 2;
if(FLASH_COMPLETE != FLASH_ProgramHalfWord(EPARA_ADDR + 8, add))
{
while(1)
{
}
};
// eeprom_write_word((uint16_t *)pet,xor);
if(FLASH_COMPLETE != FLASH_ProgramHalfWord(EPARA_ADDR + 10, xor))
{
while(1)
{
}
};
if(get_tch_data())
{
display_ram_string(10,118," !!校准成功,系统将重启动!!",0x20);
//beeper_on();
//beeper_timer = 100;
touch_timer = 200;
while(0x00 != touch_timer);
//asm volatile ("jmp 0"::);
soft_reset();
}
}
}
void get_cali_data(uint16_t x,uint16_t y,uint16_t * pt)
{
uint16_t old_x = 0,old_y = 0;
uint8_t times = 0;
uint32_t tmp_x, tmp_y;
lcm_set_graph_mode();
circle(x,y,5,1,0);
circle(x,y,10,1,0);
line(x-15,y,x+15,y,1);
line(x,y-15,x,y+15,1);
while(1)
{
//while(!scan_touch());
en_touch_init();
while(0x04 != touch_state)
{
}
if(get_delta(touch_x,old_x)>300)
{
//*pt = touch_x;
tmp_x = touch_x;
//*(pt+1) = touch_y;
tmp_y = touch_y;
times = 0;
}
else if(get_delta(touch_y,old_y)>300)
{
//*pt = touch_x;
tmp_x = touch_x;
//*(pt+1) = touch_y;
tmp_y = touch_y;
times = 0;
}
else
{
times++;
//*pt += touch_x;
tmp_x += touch_x;
//*(pt+1) += touch_y;
tmp_y += touch_y;
if(times>=3)
{
*pt = (tmp_x >> 2);
*(pt+1) = (tmp_y >> 2);
break;
}
}
old_x = touch_x;
old_y = touch_y;
}
//beeper_on();
touch_timer = 100;
dis_touch_init();
en_check_touch();
while(touch_timer)
{
//scan_touch();
if(be_penirq())
{
touch_timer = 100;
}
}
//beeper_off();
set_active_window(0,0,5,39);
lcm_clr();
set_active_window(35,200,39,239);
lcm_clr();
set_active_window(0,0,39,239);
}
uint8_t get_touch(void)
{
static uint16_t old_x = 0xffff,old_y= 0xffff;
if(0x04 != touch_state)
{
return 0x00;
}
else if((touch_x < txb) || (touch_y < tyb))
{
en_touch_init();
return 0x00;
}
else
{
touch_x -= txb;
touch_x /= txk;
touch_y -= tyb;
touch_y /= tyk;
if((touch_x > 319) || (touch_y > 239))
{
en_touch_init();
return 0x00;
}
else
{
/*if(get_delta(touch_x,old_x)>3)
{
old_x = touch_x;
old_y = touch_y;
en_touch_init();
return 0x00;
}
else if(get_delta(touch_y,old_y)>3)
{
old_x = touch_x;
old_y = touch_y;
en_touch_init();
return 0x00;
}
else*/
{
old_x = 0xffff;
old_y = 0xffff;
return 0xff;
}
}
}
}
uint8_t analyze_touch(uint16_t x,uint16_t y,const u16 * dpt)
{
uint8_t i = *dpt++;
uint8_t j = *dpt++;
uint8_t k = j;
while(0 != i)
{
if(y >= *dpt++)
{
if(y <= *dpt)
{
dpt++;
break;
}
else
{
dpt++;
}
}
else
{
dpt++;
dpt++;
}
i--;
}
if(0 == i)
{
return 0;
}
i--;
dpt += i;
while(0 != j)
{
if(x >= *dpt)
{
dpt++;
if( x<= *dpt)
{
return (k * i + j);
}
dpt++;
}
else
{
dpt++;
dpt++;
}
j--;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -