⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touchscreen.c

📁 ST最新的Cortext-M3内核的ARM触摸屏演示工程
💻 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 + -