完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
开发板购买链接
https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674 开发板简介 开发环境搭建 windows ESP32例程为C语言开发,并非Python/Arduino/AT指令开发,基于ESP-IDF_V4.2框架库,采用纯C语言开发,开发工具为Visual Studio Code Android(安卓)例程全部为原生Android开发,例程全部支持到SDK版本29 Android 10.0(Q) 开发工具为Andirod Studio 4.0 PC源码例程为Visual Studio 2013开发,C++语言,基于MFC 送的MQTT账号,仅用于同学们开发测试,大家不要用到实际产品上,不定期更换密码,会在QQ群公布 以下列出的例程源码均编写完成(不断增加中),开发教程正在编写 基础例程: 0_Hello Bug (ESP_LOGX与printf) 工程模板/打印调试输出 1_LED LED亮灭控制 2_LED_Task 使用任务方式控制LED 3_LEDC_PWM 使用LEDC来控制LED实现呼吸灯效果 4_ADC_LightR 使用ADC读取光敏电阻实现光照传感 5_KEY_Short_Long 按钮长按短按实现 6_TouchPad_Interrupt 电容触摸中断实现 7_WS2812_RMT 使用RMT实现RGB_LED彩虹变色示例 8_DHT11_RMT 使用RMT实现读取DHT11温湿度传感器 9_SPI_SDCard 使用SPI总线实现TF卡文件系统示例 10_IIC_ADXL345 使用IIC总线实现读取ADXL345角度加速度传感器 11_IIC_AT24C02 使用IIC总线实现小容量数据储存测试 12_IR_Rev_RMT 使用RMT实现红外遥控接收解码(NEC编码) 13_IR_Send_RMT 使用RMT实现红外数据发送(NEC编码) 14_WIFI_Scan 附近WIFI信号扫描示例 15_WIFI_AP 创建软AP示例 16_WIFI_AP_TCP_Server 在软AP模式下实现TCP服务端 17_WIFI_AP_TCP_Client 在软AP模式下实现TCP客户端 18_WIFI_AP_UDP 在软AP模式下实现UDP通讯 19_WIFI_STA 创建STA站模连接路由器 20_WIFI_STA_TCP_Server 在站模式STA下实现TCP服务端 21_WIFI_STA_TCP_Client 在站模式STA下实现TCP客户端 22_WIFI_STA_UDP 在站模式STA下实现UDP通讯 23_LCD_Test LCD液晶触摸屏显示测试 24_XPT2046_Touch_Test 电阻触摸XPT2046驱动测试触摸校正 ESP32应用例程 Bluetooth_RGBLight Android手机通过蓝牙控制RGB灯变色 Bluetooth_Sensor Android手机通过蓝牙读取开发板姿态和温度湿度参数 Bluetooth_Test Android手机通过蓝牙与开发板通讯 Encryption_MD5 MD5加密 Encryption_SHA1 SHA1加密 Encryption_SHA256 SHA256加密 EncryptionDecrypt_AES_CBC AES_CBC加密 EncryptionDecrypt_AES_ECB AES_ECB加密 ESP32_SmartConfig 通过Android手机配置WIFI连网 HTTP_GET_Request_Weather HTTP Get请求天气预报 JSON_Package 创建JSON数据包 JSON_Parsing 解析JSON数据包 LCD JPEG_Effect 解码JGEG图片特效显示 MQTT MQTT通讯测试 Android(安卓)工具源码 ESP32_Bluetooth_Chat Android通过蓝牙与开发板通讯测试 ESP32_Bluetooth_RGBLight Android通过蓝牙控制开发板RGB灯 ESP32_Bluetooth_Sensor Android通过蓝牙读取开发板3D姿态和温度湿度数据 ESP32_SmartConfig Android手机配置WIFI配网 MQTT_Test Android与开发板通过MQTT协议通讯 TCP_Client Android作为TCP客户端与开发板通讯 UDP_Client Android通过UDP协议与开发板通讯 PC(Visual Studio 2013 C++ MFC)工具源码 MQTT_调试助手 PC通过MQTT与开发板通讯 TCP 调试助手 PC通过TCP服务器/客户端与开发板通讯 UDP 调试助手 PC通过UDP与开发板通讯 LVGL源码 LVGL_Full_Test LVGL官方例程(使用到了大分部控件) LVGL_Arc_Test 圆弧指示器通过触摸动态改变值 LVGL_Bar_Test 通过动画方式动态演示Bar进度条的使用方法 LVGL_Button_Test 通过5种不同动态效果的按钮学习按钮的创建与使用 LVGL_ButtonMatrix_Test 创建一个计算器布局来演示矩阵按钮控件的使用 LVGL_Calendar_Test 日历控件的创建和使用 LVGL_Canvas_Test 透明画布和画一个圆角过渡色矩形并旋转角度学习画布的使用 LVGL_Chart_Test 通过创建三个不同风格的图表来学习图表控件的使用 LVGL_Checkbox_Test 学习复选框控件的创建和使用 LVGL_ColorPicker_Test 创建一个颜色选择器并动态显示当前颜色的RGB值 LVGL_Container_Test 在内容控件上动态创建三个文本标签学习内容控件的自适应布局 LVGL_Drop_down_List_Test 创建三个不同类型的下拉选择控件 LVGL_Gauge_Test 创建一个动态仪表和静态多指针仪表 LVGL_Image_Test 通过四个滑动条控件控制图片颜色的变化来学习图像控件的使用 LVGL_ImageButton_Test 创建一个图片背景的图像按钮 LVGL_Keyboard_Test 通过一个文本输入框控件还学习键盘控件的调用关闭设置 LVGL_Label_Test 创建内容颜色可变,长文本滚动展示,带阴影3D效果三个标签控件 LVGL_LED_Test 创建三个LED,学习LED控件的调光,颜色,开关的设置 LVGL_Line_Test 通过二维数组创建一段折线来演示线控件的使用 LVGL_LineMeter_Test 创建两个不同的线段弧形指示器动态展示数据 LVGL_List_Test 创建一个带图标的列表控件 LVGL_MessageBox_Test 创建一个带按钮的消息框控件 LVGL_ObjectMask_Test 创建一个变幻色的文本学习蒙版遮罩效果 LVGL_Page_Test 学习页面控件的使用 LVGL_Roller_Test 通过示例学习滑动列表选择器控件 LVGL_Slider_Test 创建一个单向和一个双向滑动条控件 LVGL_Spinbox_Test 学习微调控件的使用 LVGL_Spinner_Test 创建三个不同的环形加载器 LVGL_Switch_Test 创建两个不同的开关控件 LVGL_Table_Test 创建一个简单的表格 LVGL_Tabview_Test 实现三页的页面切换学习Tabview控件 LVGL_Textarea_Test 长按实现打字机效果的Textarea控件 LVGL_Tileview_Test 实现四面环形触摸切换的Tileview控件 LVGL_Window_Test 创建一个窗口,带设置子窗口学习窗口控件的使用 电阻式触摸屏 电阻式触摸屏是一种传感器,并不是屏幕,而是盖在液晶上面透明的电阻式传感器,它将矩形区域中触摸点(X,Y)的物理位置转换为代表X坐标和Y坐标的电压。很多LCD模块都采用了电阻式触摸屏,这种屏幕可以用四线、五线、七线或八线来产生屏幕偏置电压,同时读回触摸点的电压。 电阻层结构原理: 上图是电阻触摸屏的一个侧面剖视图。手指触摸的表面是一个硬涂层,用以保护下面的PET层。PET层是很薄的有弹性的PET薄膜,当表面被触摸时它会向下弯曲,并使得下面的两层ITO涂层能够相互接触并在该点连通电路。两个ITO层之间是约千分之一英寸厚的一些隔离支点使两层分开。最下面是一个透明的硬底层用来支撑上面的结构,通常是玻璃或者塑料。 优点 电阻式触摸屏的优点是它的屏和控制系统都比较便宜,反应灵敏度很好,而且不管是四线电阻触摸屏还是五线电阻触摸屏,它们都是一种对外界完全隔离的工作环境,不怕灰尘和水汽,能适应各种恶劣的环境。它可以用任何物体来触摸,稳定性能较好。 电阻式触摸屏的优点可归类为: 1.电阻式触控屏的精确度高,可到像素点的级别,适用的最大分辨率可达4096x4096。 2. 屏幕不受灰尘、水汽和油污的影响,可以在较低或较高温度的环境下使用。 3. 电阻式触控屏使用的是压力感应,可以用任何物体来触摸,即便是带着手套也可以操作,并可以用来进行手写识别。 4. 电阻式触控屏由于成熟的威廉希尔官方网站 和较低的门槛,成本较为廉价。 缺点 缺点是电阻触摸屏的外层薄膜容易被划伤导致触摸屏不可用,多层结构会导致很大的光损失,对于手持设备通常需要加大背光光源来弥补透光性不好的问题,但这样也会增加电池的消耗。 电阻式触摸屏的缺点可归类为: 1. 电阻式触控屏能够设计成多点触控,但当两点同时受压时,屏幕的压力变得不平衡,导致触控出现误差,因而多点触控的实现程度较难。 2. 电阻式触控屏较易因为划伤等导致屏幕触控部分受损。 XPT2046 XPT2046是一款4导线制触摸屏控制器,内含12位分辨率125KHz的转换速率逐步逼近型A / D转换器。 XPT2046支持从1.5V到5.25V的低电压I / O接口。 XPT2046能通过执行两次A / D转换查出被按的屏幕位置,除此之外,还可以测量加在触摸屏上的压力。 内部自带2.5V参考电压可以作为辅助输入,温度测量和电池监测模式之用, XPT2046电池监测的电压范围可以从0V到6V 。 片内集成有一个温度传感器,在2.7V的典型工作状态下,关闭参考电压,功耗可小于0.75MW 。 XPT2046 应该有 16 个引脚,如图: 其引脚说明如下: 从上面的引脚图,我们知道,XPT2046 跟单片机的主要引脚主要有:BUSY、DIN(单 片机 SPI 输出端)、CS、DCLK(单片机 SPI 时钟端)、PEN(笔触中断)、DOUT(单片机 SPI 输入端) 一、硬件设计及原理 查看原理图,由于高速SPI用到了SD卡和液晶屏,触摸芯片采用普通GPIO模拟SPI来实现坐标采集,除了4线SPI还有一根中断线来判断是否有按压屏幕。 二、代码编写 要驱动触摸芯片少不了触摸校正环节,触摸芯片采集的只是XY坐标上的AD值,要根据屏幕分辨率转换为液晶坐标系,所以应先驱动液晶屏,详细看上文章23_LCD_Test。 为什么要校正? 电阻式触摸屏就是一种传感器,它利用压力感应进行控制,将矩形区域中触摸点(X,Y)的物理位置转换为代表 X坐标和 Y 坐标的电压 电阻式触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏,这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面涂有一层导电层(透明的导电电阻),上面再盖一层经过硬化处理 光滑防擦的塑料层 它的内表面也涂有一层透明导电层层, 在他们之间有许多细小的(小于 1/1000 英寸) 的透明隔离点把两层导电层隔开绝缘 当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,电阻发生变化,其中一面导电层接通 Y 轴方向的 5V 均匀电压场,使得侦测层的电压由零变为非零,控制器侦测到这个接通后,进行 A/D 转换, 并将得到的电压值与 5V 相比即可得触摸点的 Y 轴坐标, 同理也能得出 X 轴的坐标, 然后再根据模拟鼠标的方式运作。 这就是所有电阻威廉希尔官方网站 触摸屏共同的最基本原理由压力感应得到坐标值的并不能达到 100%的精度,它存在着误差。由于误差的存在, 在触摸屏上所绘制的图形和液晶屏上的图形,对应点的集合会有所偏差 在触摸屏上点击某一按钮或选择某项功能时, 内置的软件便无法对触摸屏上的点击做出正确响应,而触摸屏具有离散性,任意两个触摸点密度都不能完全一致, 所以几乎所有带阻性触摸屏的设备在出厂前均要经过一定的校准 校准是一种图形重建的过程,即将图形经过变换,换算出与液晶屏相一致的点集合, 现有的校准算法主要是用来改善上述中的固有误差。 直接用上个LCD液晶测试的工程,添加XPT2046.C和.H lcd.c和gui.c就不说了,上个文章有讲 先看主函数流程 初始化lcd -> 初始化xpt2046 -> 设置为纵向 -> 开始校正 -> 完成后显示画图界面->创建画图任务 void app_main(void) { esp_err_t ret; ESP_LOGI(TAG, "APP Start......"); Init_LCD(WHITE); //初始化 XPT2046 xpt2046_init(); LCD_Set_Orientation(LCD_DISPLAY_ORIENTATION_PORTRAIT);// 纵向 TP_Adjust(); // 实心矩形 LCD_DrawFillRectangle(0,0,30,30,BLUE); LCD_DrawFillRectangle(30,0,60,30,BROWN); LCD_DrawFillRectangle(60,0,90,30,GREEN); LCD_DrawFillRectangle(90,0,120,30,GBLUE); LCD_DrawFillRectangle(120,0,150,30,RED); LCD_DrawFillRectangle(150,0,180,30,MAGENTA); LCD_DrawFillRectangle(180,0,210,30,YELLOW); LCD_DrawRectangle(210,0,240,30,RED); LCD_ShowString(215,9,WHITE,BLACK,16,"Cle",0); LCD_DrawFillRectangle(0,31,240,320,WHITE); xTaskCreate(&Draw, "Draw", 4096, NULL, 5, NULL); while(1){ vTaskDelay(1000 / portTICK_PERIOD_MS); } } 画图任务函数 static void Draw(void *pvParameters) { uint16_t CurrentColor = BLUE; while (1){ if(xpt2046_read()){ if(TouchY<=30 && TouchX<=30){ CurrentColor = BLUE; }else if(TouchY<=30 && TouchX>30 && TouchX<60){ CurrentColor = BROWN; }else if(TouchY<=30 && TouchX>60 && TouchX<90){ CurrentColor = GREEN; }else if(TouchY<=30 && TouchX>90 && TouchX<120){ CurrentColor = GBLUE; }else if(TouchY<=30 && TouchX>120 && TouchX<150){ CurrentColor = RED; }else if(TouchY<=30 && TouchX>150 && TouchX<180){ CurrentColor = MAGENTA; }else if(TouchY<=30 && TouchX>180 && TouchX<210){ CurrentColor = YELLOW; }else if(TouchY<=30 && TouchX>210 && TouchX < 240){ LCD_DrawFillRectangle(0,31,240,320,WHITE); } else{ LCD_DrawPoint1(TouchX,TouchY,CurrentColor);//画点 } } vTaskDelay(10 / portTICK_PERIOD_MS); } vTaskDelete(NULL); } lcd初始化和绘图看上编文章 XPT2046初始化,其中只是初始化了所到的GPIO,下一步用这些IO虚拟SPI来读取坐标参数 //初始化 XPT2046 void xpt2046_init(void) { gpio_config_t irq_config = { .pin_bit_mask = BIT64(XPT2046_IRQ), .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE, }; esp_err_t ret = gpio_config(&irq_config); /**/ gpio_config_t miso_config = { .pin_bit_mask = BIT64(XPT2046_MISO), .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE, }; ret = gpio_config(&miso_config); gpio_pad_select_gpio(XPT2046_MOSI); gpio_set_direction(XPT2046_MOSI, GPIO_MODE_OUTPUT);// 设置GPIO为推挽输出模式 gpio_pad_select_gpio(XPT2046_CLK); gpio_set_direction(XPT2046_CLK, GPIO_MODE_OUTPUT);// 设置GPIO为推挽输出模式 gpio_pad_select_gpio(XPT2046_CS); gpio_set_direction(XPT2046_CS, GPIO_MODE_OUTPUT);// 设置GPIO为推挽输出模式 printf("%s->XPT2046 Initializationn",TAG); assert(ret == ESP_OK); } 虚拟SPI写入一个命令 void xpt2046_gpio_Write_Byte(uint8_t num) { uint8_t count=0; for(count=0;count<8;count++){ if(num&0x80){ gpio_set_level(XPT2046_MOSI, 1); }else{ gpio_set_level(XPT2046_MOSI, 0); } num<<=1; gpio_set_level(XPT2046_CLK, 0); gpio_set_level(XPT2046_CLK, 1); } } 虚拟SPI读取数据 uint16_t xpt2046_gpio_spi_read_reg(uint8_t reg) { uint8_t count=0; uint16_t ADValue=0; gpio_set_level(XPT2046_CLK, 0); // 先拉低时钟 gpio_set_level(XPT2046_MOSI, 0); // 拉低数据线 gpio_set_level(XPT2046_CS, 0); // 选中触摸屏IC xpt2046_gpio_Write_Byte(reg); // 发送命令字 ets_delay_us(6); // ADS7846的转换时间最长为6us gpio_set_level(XPT2046_CLK, 0); ets_delay_us(1); gpio_set_level(XPT2046_CLK, 1); // 给1个时钟,清除BUSY gpio_set_level(XPT2046_CLK, 0); for(count=0;count<16;count++){ // 读出16位数据,只有高12位有效 ADValue<<=1; gpio_set_level(XPT2046_CLK, 0); // 下降沿有效 gpio_set_level(XPT2046_CLK, 1); if(gpio_get_level(XPT2046_MISO))ADValue++; } ADValue>>=4; // 只有高12位有效. gpio_set_level(XPT2046_CS, 1); // 释放片选 return(ADValue); } 有了上现的两个函数实现,就可以读取坐标数据了 读取坐标数据多次求平均 uint16_t TP_Read_XOY(uint8_t xy) { uint8_t LOST_VAL = 1;//丢弃值 uint16_t i,j,temp,buf[Read_Count]; uint32_t sum=0; for(i=0;i } for(i=0;i temp=buf; buf=buf[j]; buf[j]=temp; } } } sum=0; for(i=LOST_VAL;i } temp = sum/(Read_Count-2*LOST_VAL); return temp; } 重点来了,校正函数,采用4点校正,这里的校正结果参数只是保存为变量,实际应该保存在EEPROM中下次读取 void TP_Adjust(void) { uint8_t Last_LCD_Orientation = LCD_Orientation;// 记录校正前屏幕方向,完成后还原 uint16_t pos_temp[4][2];//坐标缓存值 uint8_t cnt=0,GetTouchOK = 0; uint16_t d1,d2; uint32_t tem1,tem2; float fac; uint16_t outtime=0; cnt=0; uint16_t rX,rY; // 校正触摸时要显示为纵向 LCD_Set_Orientation(LCD_DISPLAY_ORIENTATION_PORTRAIT);// 纵向 LCD_Clear(WHITE);//清屏 LCD_ShowString(10,40,WHITE,BLUE,16,"Please use the stylus click",1);//显示提示信息 LCD_ShowString(10,56,WHITE,BLUE,16,"the cross on the screen.",1);//显示提示信息 LCD_ShowString(10,72,WHITE,BLUE,16,"The cross will always move",1);//显示提示信息 LCD_ShowString(10,88,WHITE,BLUE,16,"until the screen adjustment",1);//显示提示信息 LCD_ShowString(10,104,WHITE,BLUE,16,"is completed.",1);//显示提示信息 TP_Drow_Touch_Point(20,20,RED);//画点1 while(1){//如果连续10秒钟没有按下,则自动退出 vTaskDelay(10 / portTICK_PERIOD_MS); if (gpio_get_level(XPT2046_IRQ) == 0) { rX = TP_Read_XOY(CMD_X_READ); rY = TP_Read_XOY(CMD_Y_READ); while(!gpio_get_level(XPT2046_IRQ)){ vTaskDelay(100 / portTICK_PERIOD_MS); } GetTouchOK = 1; } if(GetTouchOK==1){ GetTouchOK = 0; pos_temp[cnt][0]=rX; pos_temp[cnt][1]=rY; cnt++; switch(cnt){ case 1: TP_Drow_Touch_Point(20,20,WHITE); // 清除点1 TP_Drow_Touch_Point(LCD_Width-20,20,RED); // 画点2 vTaskDelay(1000 / portTICK_PERIOD_MS); break; case 2: TP_Drow_Touch_Point(LCD_Width-20,20,WHITE); // 清除点2 TP_Drow_Touch_Point(20,LCD_Height-20,RED); // 画点3 vTaskDelay(1000 / portTICK_PERIOD_MS); break; case 3: TP_Drow_Touch_Point(20,LCD_Height-20,WHITE); // 清除点3 TP_Drow_Touch_Point(LCD_Width-20,LCD_Height-20,RED); // 画点4 break; case 4: //全部四个点已经得到 //对边相等 tem1=abs(pos_temp[0][0]-pos_temp[1][0]);//x1-x2 tem2=abs(pos_temp[0][1]-pos_temp[1][1]);//y1-y2 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,2的距离 tem1=abs(pos_temp[2][0]-pos_temp[3][0]);//x3-x4 tem2=abs(pos_temp[2][1]-pos_temp[3][1]);//y3-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到3,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05||d1==0||d2==0){//不合格{ cnt=0; TP_Drow_Touch_Point(LCD_Width-20,LCD_Height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; } tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,3的距离 tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,4的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05){//不合格{ cnt=0; TP_Drow_Touch_Point(LCD_Width-20,LCD_Height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; }//正确了 //对角线相等 tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3 tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3 tem1*=tem1; tem2*=tem2; d1=sqrt(tem1+tem2);//得到1,4的距离 tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4 tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4 tem1*=tem1; tem2*=tem2; d2=sqrt(tem1+tem2);//得到2,3的距离 fac=(float)d1/d2; if(fac<0.95||fac>1.05)//不合格 { cnt=0; TP_Drow_Touch_Point(LCD_Width-20,LCD_Height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 continue; }//正确了 //计算结果 xfac=(float)(TP_Adjust_Width-40)/(pos_temp[0][0] - pos_temp[2][0]); // 得到xfac 点2-点1的X AD差值 xoff=(TP_Adjust_Width-xfac*(pos_temp[0][0]+pos_temp[2][0]))/2; // 得到xoff yfac=(float)(TP_Adjust_Height-40)/(pos_temp[3][1] - pos_temp[2][1]);// 得到yfac 点4-点3的Y AD差值 yoff=(TP_Adjust_Height-yfac*(pos_temp[3][1]+pos_temp[2][1]))/2; // 得到yoff printf("%s->XPT2046 Read fac(%f,%f)n",TAG, xfac, yfac); printf("%s->XPT2046 Read off(%d,%d)n",TAG, xoff, yoff); printf("%s->XPT2046 Read pos_temp1(X %d,Y %d)n",TAG, pos_temp[0][0], pos_temp[0][1]); printf("%s->XPT2046 Read pos_temp2(X %d,Y %d)n",TAG, pos_temp[1][0], pos_temp[1][1]); printf("%s->XPT2046 Read pos_temp3(X %d,Y %d)n",TAG, pos_temp[2][0], pos_temp[2][1]); printf("%s->XPT2046 Read pos_temp4(X %d,Y %d)n",TAG, pos_temp[3][0], pos_temp[3][1]); if(abs(xfac)>2||abs(yfac)>2){//触屏和预设的相反了. cnt=0; TP_Drow_Touch_Point(LCD_Width-20,LCD_Height-20,WHITE); //清除点4 TP_Drow_Touch_Point(20,20,RED); //画点1 LCD_ShowString(40,26,WHITE,BLUE, 16,"TP Need readjust!",1); vTaskDelay(1000 / portTICK_PERIOD_MS); } LCD_Clear(WHITE);//清屏 LCD_Set_Orientation(Last_LCD_Orientation);// 校正完成后还原开始时屏幕方向 LCD_ShowString(35,110,WHITE,BLUE, 16,"Touch Screen Adjust OK!",1);//校正完成 vTaskDelay(1000 / portTICK_PERIOD_MS); //TP_Save_Adjdata(); //LCD_Clear(WHITE);//清屏 return;//校正完成 } } } } 根据校正的结果读取XY坐标并根据当前屏幕方向转换坐标系 bool xpt2046_read(void) { static int16_t last_x = 0,last_y = 0; bool valid = true; int16_t swap_tmp; uint16_t x = 0,y = 0; uint16_t ux = 0,uy = 0; uint8_t irq = gpio_get_level(XPT2046_IRQ); if (irq == 0) { ux = TP_Read_XOY(CMD_X_READ); //5700 61700 uy = TP_Read_XOY(CMD_Y_READ); //3000 62300 //printf("%s->XPT2046 Read ADC(X:%d,Y:%d)n",TAG, ux, uy); x = xfac * ux + xoff;//将结果转换为屏幕坐标 y = yfac * uy + yoff; /* 校准后采集的触摸坐标系,要结合当前液晶显示坐标系翻转、调换XY,将触摸坐标系转为显示坐标系 X0 X320 Y0 ----------------------------- | | | | 软 | 排 | 线 | | | | | Y240----------------------------- */ //printf("%s->LCD_DISPLAY_ORIENTATION_PORTRAIT %dn",TAG,LCD_Orientation); if(LCD_Orientation == LCD_DISPLAY_ORIENTATION_PORTRAIT){// 纵向 // 调换XY swap_tmp = x; x = y; y = swap_tmp; // 翻转Y y = LCD_Height - y; }else if(LCD_Orientation == LCD_DISPLAY_ORIENTATION_PORTRAIT_INVERTED){// 纵向翻转 // 调换XY swap_tmp = x; x = y; y = swap_tmp; // 翻转X x = LCD_Width - x; }else if(LCD_Orientation == LCD_DISPLAY_ORIENTATION_LANDSCAPE){// 横向 // 翻转X x = LCD_Width - x; // 翻转Y y = LCD_Height - y; }else if(LCD_Orientation == LCD_DISPLAY_ORIENTATION_LANDSCAPE_INVERTED){// 横向翻转 } //printf("%s->XPT2046 Read Touch(X:%d,Y:%d)n",TAG, x, y); TouchX = x; TouchY = y; return true; } return false; } ———————————————— 版权声明:本文为CSDN博主「路过人间本尊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/cnicfhnui/article/details/108655354 下面为液晶屏的4个方向坐标系 三、下载测试 打开ESP-IDF Command Prompt cd命令进入此工程目录 cd F:ESP32_DevBoard_File24_XPT2046_Touch_Test 查看电脑设备管理器中开发板的串口号 执行idf.py -p COM9 flash monitor从串口9下载并运行打开口显示设备调试信息 Ctrl+c退出运行 |
|
|
|
只有小组成员才能发言,加入小组>>
4995个成员聚集在这个小组
加入小组3487 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4389 浏览 1 评论
4446 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-4-19 20:30 , Processed in 0.608052 second(s), Total 74, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191