stm32 触摸屏 XPT2046
来源:互联网 发布:巴尔扎的军靴知乎 编辑:程序博客网 时间:2024/05/08 23:54
引脚功能描述
控制字的控制位命令
控制字节各位描述
单端模式输入配置
差分模式输入配置
时序
前8个时钟用来通过DIN引脚输入控制字节,接着的12个时钟周期将完成真正的模数转换,剩下的3个多时钟周期将用来完成被转换器忽略的最后字节(DOUT置低)
举例
#define TOUCH_READ_TIMES 40 //读取次数#define TOUCH_ERR_RANGE 20 //误差范围#define TOUCH_X_CMD 0xD0 //读取X轴#define TOUCH_Y_CMD 0x90 //读取Y轴#define TOUCH_Continue_Read 0xFF#define TOUCH_X_MAX 4000 //X最大值#define TOUCH_X_MIN 100 //X最小值#define TOUCH_Y_MAX 4000 //Y最大值#define TOUCH_Y_MIN 100 //X最小值#define LCD_CALx_MIN (10) //校准点最小值X#define LCD_CALx_MAX (tftlcd_data.width - LCD_CALx_MIN) //校准点最大值X#define LCD_CALy_MIN (10) //校准点最小值Y#define LCD_CALy_MAX (tftlcd_data.height - LCD_CALy_MIN) //校准点最大值Y#define LCD_CAL_X (LCD_CALx_MAX - LCD_CALx_MIN) //方框的宽度#define LCD_CAL_Y (LCD_CALy_MAX - LCD_CALy_MIN) //方框的高度#define TOUCH_CAL_OK 'Y' //校准OK标志#define TOUCH_CAL_ADDR 200 //校准参数在at24c02的保存地址typedef struct{ u8 flag; short xoffset; short yoffset; float xFactor; float yFactor;} calibrate_t;calibrate_t calibrate = {0};u16 touchX;u16 touchY;void TOUCH_init(){ GPIO_InitTypeDef gpioa = { GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7, GPIO_Speed_50MHz, GPIO_Mode_AF_PP }; GPIO_InitTypeDef gpiod6 = { GPIO_Pin_6, GPIO_Speed_50MHz, GPIO_Mode_Out_PP }; GPIO_InitTypeDef gpiod7 = { GPIO_Pin_7, GPIO_Speed_50MHz, GPIO_Mode_IPU }; SPI_InitTypeDef spi = { SPI_Direction_2Lines_FullDuplex, SPI_Mode_Master, //0x0104 SPI_DataSize_8b, SPI_CPOL_High, SPI_CPHA_2Edge, SPI_NSS_Soft, SPI_BaudRatePrescaler_256, SPI_FirstBit_MSB, 7 }; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE); GPIO_Init(GPIOA, &gpioa); GPIO_Init(GPIOD, &gpiod6); GPIO_Init(GPIOD, &gpiod7); SPI_Init(SPI1, &spi); //初始化SPI SPI_Cmd(SPI1, ENABLE); //使能SPI}u16 TOUCH_read(u16 cmd){ u8 i = 0, j = 0; u16 tmp; u16 value[TOUCH_READ_TIMES] = {0}; u32 total_value = 0; SPI1_SetSpeed(SPI_BaudRatePrescaler_32); //设置SPI速度 for(i = 0; i < TOUCH_READ_TIMES; i++) //读取次数 { TOUCH_CS = 0; SPI1_read_write(cmd); value[i] = SPI1_read_write(TOUCH_Continue_Read) << 8; //详见时序 value[i] |= SPI1_read_write(TOUCH_Continue_Read); value[i] >>= 3; TOUCH_CS = 1; } for (i = 0; i < TOUCH_READ_TIMES; i++) //排序 { for (j = i + 1; j < TOUCH_READ_TIMES; j++) { if (value[i] < value[j]) { tmp = value[i]; value[i] = value[j]; value[j] = tmp; } } } for (i = 1; i < TOUCH_READ_TIMES - 1; i++) //去掉一个最大值,一个最小值 { total_value += value[i]; } total_value /= (TOUCH_READ_TIMES - 2); //求平均值 return total_value;}u8 TOUCH_readXY(u16 *x, u16 *y){ u16 valueX1, valueY1, valueX2, valueY2; valueX1 = TOUCH_read(TOUCH_X_CMD); //读取触摸值 valueY1 = TOUCH_read(TOUCH_Y_CMD); valueX2 = TOUCH_read(TOUCH_X_CMD); valueY2 = TOUCH_read(TOUCH_Y_CMD); *x = valueX1 > valueX2 ? (valueX1 - valueX2) : (valueX2 - valueX1); *y = valueY1 > valueY2 ? (valueY1 - valueY2) : (valueY2 - valueY1); if((*x > TOUCH_ERR_RANGE) || (*y > TOUCH_ERR_RANGE)) //判断容错范围 { return 0xFF; } *x = (valueX1 + valueX2) / 2; *y = (valueY1 + valueY2) / 2; if((*x < TOUCH_X_MIN || *x > TOUCH_X_MAX) || //判断边界范围 (*y < TOUCH_Y_MIN || *y > TOUCH_Y_MAX)) { return 0xFF; } return 0;}void TOUCH_start_calibrate(u16 x, u16 y, u16 *valueX,u16 *valueY) //开始校准{ u8 i = 0; LCD_Clear(BACK_COLOR); //清屏 LCD_DrowSign(x, y, BACK_COLOR); //画十字 while(1) { if(TOUCH_readXY(valueX, valueY) != 0xFF) { i++; if(i > 10) { LCD_DrowSign(x, y, BACK_COLOR); break; } } }}void TOUCH_calibrate(){ u16 px[2], py[2], valueX[4], valueY[4]; float xFactor = 0, yFactor = 0; TOUCH_start_calibrate(LCD_CALx_MIN, LCD_CALy_MIN, &valueX[0], &valueY[0]); //第一次校准 delay_ms(500); TOUCH_start_calibrate(LCD_CALx_MIN, LCD_CALy_MAX, &valueX[1], &valueY[1]); delay_ms(500); TOUCH_start_calibrate(LCD_CALx_MAX, LCD_CALy_MIN, &valueX[2], &valueY[2]); delay_ms(500); TOUCH_start_calibrate(LCD_CALx_MAX, LCD_CALy_MAX, &valueX[3], &valueY[3]); delay_ms(500); //整合成对角的两点 px[0] = (valueX[0] + valueX[1]) / 2; py[0] = (valueY[0] + valueY[2]) / 2; px[1] = (valueX[3] + valueX[2]) / 2; py[1] = (valueY[3] + valueY[1]) / 2; //求出比例因子 xFactor = (float)LCD_CAL_X / (px[1] - px[0]); yFactor = (float)LCD_CAL_Y / (py[1] - py[0]); //求出偏移量 calibrate.xoffset = (short)LCD_CALx_MAX - ((float)px[1] * xFactor); calibrate.yoffset = (short)LCD_CALy_MAX - ((float)py[1] * yFactor); calibrate.xFactor = xFactor ; calibrate.yFactor = yFactor ; printf("xoffset %d\n", calibrate.xoffset); printf("yoffset %d\n", calibrate.yoffset); printf("xFactor %f\n", calibrate.xFactor); printf("yFactor %f\n", calibrate.yFactor); //保存校准数据到at24c02 calibrate.flag = TOUCH_CAL_OK; at24c02Write_buf((u8*)&calibrate, TOUCH_CAL_ADDR, sizeof(calibrate)); }u8 TOUCH_scan() //查看是否触摸{ u16 valueX; u16 valueY; if(TOUCH_readXY(&valueX, &valueY) == 0xFF) { return 0xFF; } //根据物理坐标,计算彩屏坐标 touchX = valueX * calibrate.xFactor + calibrate.xoffset; touchY = valueY * calibrate.yFactor + calibrate.yoffset; if((touchX > tftlcd_data.width) || (touchY > tftlcd_data.height)) { return 0xFF; } return 0;}int main(void){ I2C_init(); TOUCH_init(); at24c02Read_buf((u8*)&calibrate, TOUCH_CAL_ADDR, sizeof(calibrate)); if(calibrate.flag != TOUCH_CAL_OK) //判断是否已经校准 { TOUCH_calibrate(); } LCD_ShowString(tftlcd_data.width-40,0,tftlcd_data.width,tftlcd_data.height,16,"clear"); while(1) { if(TOUCH_scan() == 0) { LCD_Fill(touchX-1, touchY-1, touchX+2, touchY+2, FRONT_COLOR); //画粗线 if((touchX > tftlcd_data.width-40) && (touchY < 20)) { LCD_Fill(0, 0, tftlcd_data.width,tftlcd_data.height, BACK_COLOR); //清屏 LCD_ShowString(tftlcd_data.width-40,0,tftlcd_data.width,tftlcd_data.height,16,"clear"); } } }}
阅读全文
1 0
- stm32 触摸屏 XPT2046
- STM32-触摸屏实验
- [转载]STM32+UCGUI+触摸屏
- AD转换 XPT2046
- XPT2046芯片datasheet
- STM32 触摸屏触摸功能学习总结
- 在STM32上移植ucGUI之触摸屏
- STM32 TFT学习笔记——触摸屏
- STM32系列第26篇--电容触摸屏
- 基于STM32的触摸屏学习笔记
- STM32-TFT-LCD触摸屏以及FSMC基础
- STM32开发板电容触摸屏驱动,单点有效
- 基于STM32的电池管理系统触摸屏设计方案
- 手绘轨迹(STM32触摸屏)控制小车运动
- stm32 四线IO口驱动触摸屏
- 关于STM32应用触摸屏校准原理的总结
- 嵌入式系统学习——STM32之电容型触摸屏
- 嵌入式系统学习——STM32之电阻型触摸屏
- 20170612
- Atitit 收入理论大总结 4位一体 4象限理论 财政收入理论 6位一体
- 树的dfs序入门,BZOJ1103 ,hdu6162,EOJ3335
- Java虚拟机四:类加载机制
- F—水仙花数
- stm32 触摸屏 XPT2046
- org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'productCode
- 浅谈虚拟化技术
- java乱码 java使用的编码是utf-8还是utf-16还是unicode
- POJ 2186 Popular Cows(tarjan求强连通)
- 学习总结
- 创建设计字典表
- 关于公众号
- PCSc