1.8寸彩色触摸屏
模块来源
采购链接:
https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-23991449512.20.62ae703buie1Ei&id=568584833602
资料下载链接:
https://pan.baidu.com/s/1n_vp38V7ij88PUGpbJPd7Q
资料提取码:8888
规格参数
工作电压:3.3V
工作电流:30MA
模块尺寸:35(H) x 56(V) MM
像素大小:128(H) x 160(V)RGB
驱动芯片:ST7735S
通信协议:SPI
管脚数量:12 Pin(2.54mm间距排针)
带电阻触摸芯片:XPT2046
移植过程
我们的目标是将例程移植至立创开发板GD32E230C8T6上。按照以下步骤,即可完成移植。
- 将源码导入工程;
- 根据编译报错处进行粗改;
- 修改引脚配置;
- 修改时序配置;
- 移植验证。
查看资料
打开厂家资料例程。具体路径见 图1.8.3.1 例程路径
移植至工程
将厂家资料路径下的【LCD】和【TOUCH】文件夹,复制到自己的工程中。自己的工程至少需要有毫秒级延时函数。(工程可以参考入门手册空白工程(工程模板)下载)
文件下载
文件1.8.3.2 空白工程下载
打开空白工程,我们先导入c文件到工程
- LCD文件夹
- TOUCH文件夹
接下来,我们添加h文件的路径到工程中
- LCD文件夹中的h文件
- TOUCH文件夹中的h文件
这样我们两个文件夹路径就添加到工程中了
我们将 main.c、lcd.c、lcd_init.c、touch.c、lcd.h、lcd_init.h和touch.h 的头文件换成下面的形式:
// main.c
#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#include "pic.h"
#include "lcd_init.h"
#include "lcd.h"
#include "touch.h"
2
3
4
5
6
7
8
// lcd.c
#include "lcd.h"
#include "lcd_init.h"
#include "lcdfont.h"
2
3
4
// lcd_init.c
#include "lcd_init.h"
2
// touch.c
#include "touch.h"
#include "lcd_init.h"
#include "lcd.h"
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
2
3
4
5
6
7
// lcd.h
#include "gd32e23x.h"
#include "systick.h"
2
3
// lcd_init.h
#include "gd32e23x.h"
#include "systick.h"
2
3
// touch.h
#include "gd32e23x.h"
#include "systick.h"
2
3
分别在 lcd_init.h、lcd.h 和 touch.h 文件中定义三个宏,u32、u16与u8。
#ifndef u8
#define u8 uint8_t
#endif
#ifndef u16
#define u16 uint16_t
#endif
#ifndef u32
#define u32 uint32_t
#endif
2
3
4
5
6
7
8
9
10
11
再编译发现只剩下LCD引脚初始化的内容报错,接下来我们要进行引脚选择。
引脚选择
该屏幕需要设置12个接口,具体接口说明见 表1.8.3.1 各引脚说明。
下面分为软件SPI移植与硬件SPI移植进行讲解。
软件SPI移植
当前厂家源码使用的是软件SPI接口,SPI时序部分厂家已经完成,我们只需要将引脚和延时配置好即可。所以对应接入的屏幕引脚请按照你的需要。这里选择的引脚见表1.8.3.2 软件SPI接线
选择好引脚后,进入工程开始编写屏幕引脚初始化代码。
为了方便后续移植,我在lcd_init.h处宏定义了每一个引脚,后续根据需要进行修改即可。
//-----------------LCD端口移植----------------
//GND - GND
//VCC - 3.3V
//CLK - PC13
//MOS - PC14
//RES - PC15(可以接入复位)
//DC - PA0
//BLK - PA1
//MIS - PA2
//CS1 - PA3
//CS2 - PA4
//PEN - PA5
//NC - 不用接
#define RCU_LCD_CLK RCU_GPIOC//SCK
#define PORT_LCD_CLK GPIOC
#define GPIO_LCD_CLK GPIO_PIN_13
#define RCU_LCD_MOS RCU_GPIOC//MOSI
#define PORT_LCD_MOS GPIOC
#define GPIO_LCD_MOS GPIO_PIN_14
#define RCU_LCD_MIS RCU_GPIOA//MIS0
#define PORT_LCD_MIS GPIOA
#define GPIO_LCD_MIS GPIO_PIN_2
#define RCU_LCD_CS1 RCU_GPIOA//NSS
#define PORT_LCD_CS1 GPIOA
#define GPIO_LCD_CS1 GPIO_PIN_3
#define RCU_LCD_CS2 RCU_GPIOA//CS2
#define PORT_LCD_CS2 GPIOA
#define GPIO_LCD_CS2 GPIO_PIN_4
#define RCU_LCD_PEN RCU_GPIOA //PEN
#define PORT_LCD_PEN GPIOA
#define GPIO_LCD_PEN GPIO_PIN_5
#define RCU_LCD_DC RCU_GPIOA //DC
#define PORT_LCD_DC GPIOA
#define GPIO_LCD_DC GPIO_PIN_0
#define RCU_LCD_RES RCU_GPIOC//RES
#define PORT_LCD_RES GPIOC
#define GPIO_LCD_RES GPIO_PIN_15
#define RCU_LCD_BLK RCU_GPIOA//BLK
#define PORT_LCD_BLK GPIOA
#define GPIO_LCD_BLK GPIO_PIN_1
/******** 硬件SPI修改此次 ********/
//#define RCU_SPI_HARDWARE RCU_SPI1
//#define PORT_SPI SPI1
//#define LINE_AF_SPI GPIO_AF_5
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
将lcd_init.c源代码中的void LCD_GPIO_Init(void)修改为如下代码。
void LCD_GPIO_Init(void)
{
/* 使能时钟 */
rcu_periph_clock_enable(RCU_LCD_CLK);
rcu_periph_clock_enable(RCU_LCD_MOS);
rcu_periph_clock_enable(RCU_LCD_MIS);
rcu_periph_clock_enable(RCU_LCD_CS1);
rcu_periph_clock_enable(RCU_LCD_CS2);
rcu_periph_clock_enable(RCU_LCD_PEN);
rcu_periph_clock_enable(RCU_LCD_DC);
rcu_periph_clock_enable(RCU_LCD_RES);
rcu_periph_clock_enable(RCU_LCD_BLK);
/* 配置CLK */
gpio_mode_set(PORT_LCD_CLK,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_CLK);
gpio_output_options_set(PORT_LCD_CLK,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_CLK);
gpio_bit_write(PORT_LCD_CLK, GPIO_LCD_CLK, SET);
/* 配置MOS */
gpio_mode_set(PORT_LCD_MOS,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_MOS);
gpio_output_options_set(PORT_LCD_MOS,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_MOS);
gpio_bit_write(PORT_LCD_MOS, GPIO_LCD_MOS, SET);
/* 配置MIS */
gpio_mode_set(PORT_LCD_MIS,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,GPIO_LCD_MIS);
gpio_bit_write(PORT_LCD_MIS, GPIO_LCD_MIS, SET);
/* 配置DC */
gpio_mode_set(PORT_LCD_DC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DC);
gpio_output_options_set(PORT_LCD_DC,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_DC);
gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET);
/* 配置CS1 */
gpio_mode_set(PORT_LCD_CS1,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_CS1);
gpio_output_options_set(PORT_LCD_CS1,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_CS1);
gpio_bit_write(PORT_LCD_CS1, GPIO_LCD_CS1, SET);
/* 配置CS2 */
gpio_mode_set(PORT_LCD_CS2,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_CS2);
gpio_output_options_set(PORT_LCD_CS2,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_CS2);
gpio_bit_write(PORT_LCD_CS2, GPIO_LCD_CS2, SET);
/* 配置RES */
gpio_mode_set(PORT_LCD_RES,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_RES);
gpio_output_options_set(PORT_LCD_RES,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_LCD_RES);
gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET);
/* 配置BLK */
gpio_mode_set(PORT_LCD_BLK, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_LCD_BLK);
gpio_output_options_set(PORT_LCD_BLK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_BLK);
gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, SET);
/* 配置PEN */
gpio_mode_set(PORT_LCD_PEN,GPIO_MODE_INPUT,GPIO_PUPD_PULLUP,GPIO_LCD_PEN);
gpio_bit_write(PORT_LCD_PEN, GPIO_LCD_PEN, SET);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
将lcd_init.h中的 LCD端口定义 宏,修改为图1.8.3.25样式。
//-----------------LCD端口定义----------------
#define LCD_SCLK_Clr() gpio_bit_write(PORT_LCD_CLK, GPIO_LCD_CLK, RESET)//SCL=SCLK
#define LCD_SCLK_Set() gpio_bit_write(PORT_LCD_CLK, GPIO_LCD_CLK, SET)
#define LCD_MOSI_Clr() gpio_bit_write(PORT_LCD_MOS, GPIO_LCD_MOS, RESET)//SDA=MOSI
#define LCD_MOSI_Set() gpio_bit_write(PORT_LCD_MOS, GPIO_LCD_MOS, SET)
#define LCD_RES_Clr() gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, RESET)//RES
#define LCD_RES_Set() gpio_bit_write(PORT_LCD_RES, GPIO_LCD_RES, SET)
#define LCD_DC_Clr() gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, RESET)//DC
#define LCD_DC_Set() gpio_bit_write(PORT_LCD_DC, GPIO_LCD_DC, SET)
#define LCD_CS_Clr() gpio_bit_write(PORT_LCD_CS1, GPIO_LCD_CS1, RESET)//CS
#define LCD_CS_Set() gpio_bit_write(PORT_LCD_CS1, GPIO_LCD_CS1, SET)
#define LCD_BLK_Clr() gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, RESET)//BLK
#define LCD_BLK_Set() gpio_bit_write(PORT_LCD_BLK, GPIO_LCD_BLK, SET)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
修改为如图1.8.3.27 修改后触摸功能引脚所示
//电阻屏芯片连接引脚
#define TCLK(x) gpio_bit_write(GPIOC, GPIO_PIN_13, x?1:0) //PC13 SCLK--
#define TDIN(x) gpio_bit_write(GPIOC, GPIO_PIN_14, x?1:0) //PC14 MOSI--
#define DOUT gpio_input_bit_get(GPIOA, GPIO_PIN_2) //PA2 MISO--
#define TCS(x) gpio_bit_write(GPIOA, GPIO_PIN_4, x?1:0) //PA4 CS2--
#define PEN gpio_input_bit_get(GPIOA, GPIO_PIN_5) //PA5 INT(PEN)--
2
3
4
5
6
然后我们转到touch.c文件将文件中的代码,替换成下方的代码:
#include "touch.h"
#include "lcd_init.h"
#include "lcd.h"
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
_m_tp_dev tp_dev=
{
TP_Init,
TP_Scan,
TP_Adjust,
0,
0,
0,
0,
0,
0,
0,
};
#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
u8 CMD_RDX=0XD0;
u8 CMD_RDY=0X90;
#else
u8 CMD_RDX=0X90;
u8 CMD_RDY=0XD0;
#endif
//SPI写数据
//向触摸屏IC写入1byte数据
//num:要写入的数据
void TP_Write_Byte(u8 num)
{
u8 count=0;
for(count=0;count<8;count++)
{
if(num&0x80)TDIN(1);
else TDIN(0);
num<<=1;
TCLK(0);
delay_us(1);
TCLK(1); //上升沿有效
}
}
//SPI读数据
//从触摸屏IC读取adc值
//CMD:指令
//返回值:读到的数据
u16 TP_Read_AD(u8 CMD)
{
u8 count=0;
u16 Num=0;
TCLK(0); //先拉低时钟
TDIN(0); //拉低数据线
TCS(0); //选中触摸屏IC
TP_Write_Byte(CMD);//发送命令字
delay_us(6);
TCLK(0);
delay_us(1);
TCLK(1); //给1个时钟,清除BUSY
delay_us(1);
TCLK(0);
for(count=0;count<16;count++)//读出16位数据,只有高12位有效
{
Num<<=1;
TCLK(0); //下降沿有效
delay_us(1);
TCLK(1);
if(DOUT)Num++;
}
Num>>=4; //只有高12位有效.
TCS(1); //释放片选
return(Num);
}
//读取一个坐标值(x或者y)
//连续读取READ_TIMES次数据,对这些数据升序排列,
//然后去掉最低和最高LOST_VAL个数,取平均值
//xy:指令(CMD_RDX/CMD_RDY)
//返回值:读到的数据
#define READ_TIMES 5 //读取次数
#define LOST_VAL 1 //丢弃值
u16 TP_Read_XOY(u8 xy)
{
u16 i, j;
u16 buf[];
u16 sum=0;
u16 temp;
for(i=0;i<READ_TIMES;i++)buf[]=TP_Read_AD(xy);
for(i=0;i<READ_TIMES-1; i++)//排序
{
for(j=i+1;j<READ_TIMES;j++)
{
if(buf[]>buf[])//升序排列
{
temp=buf[];
buf[]=buf[];
buf[]=temp;
}
}
}
sum=0;
for(i=LOST_VAL;i<READ_TIMES-LOST_VAL;i++)sum+=buf[];
temp=sum/(READ_TIMES-2*LOST_VAL);
return temp;
}
//读取x,y坐标
//最小值不能少于100.
//x,y:读取到的坐标值
//返回值:0,失败;1,成功。
u8 TP_Read_XY(u16 *x,u16 *y)
{
u16 xtemp,ytemp;
xtemp=TP_Read_XOY(CMD_RDX);
ytemp=TP_Read_XOY(CMD_RDY);
*x=xtemp;
*y=ytemp;
return 1;//读数成功
}
//连续2次读取触摸屏IC,且这两次的偏差不能超过
//ERR_RANGE,满足条件,则认为读数正确,否则读数错误.
//该函数能大大提高准确度
//x,y:读取到的坐标值
//返回值:0,失败;1,成功。
#define ERR_RANGE 50 //误差范围
u8 TP_Read_XY2(u16 *x,u16 *y)
{
u16 x1,y1;
u16 x2,y2;
u8 flag;
flag=TP_Read_XY(&x1,&y1);
if(flag==0)return(0);
flag=TP_Read_XY(&x2,&y2);
if(flag==0)return(0);
if(((x2<=x1&&x1<x2+ERR_RANGE)||(x1<=x2&&x2<x1+ERR_RANGE))//前后两次采样在+-50内
&&((y2<=y1&&y1<y2+ERR_RANGE)||(y1<=y2&&y2<y1+ERR_RANGE)))
{
*x=(x1+x2)/2;
*y=(y1+y2)/2;
return 1;
}else return 0;
}
//////////////////////////////////////////////////////////////////////////////////
//与LCD部分有关的函数
//画一个触摸点
//用来校准用的
//x,y:坐标
//color:颜色
void TP_Drow_Touch_Point(u16 x,u16 y,u16 color)
{
LCD_DrawLine(x-12,y,x+13,y,color);//横线
LCD_DrawLine(x,y-12,x,y+13,color);//竖线
LCD_DrawPoint(x+1,y+1,color);
LCD_DrawPoint(x-1,y+1,color);
LCD_DrawPoint(x+1,y-1,color);
LCD_DrawPoint(x-1,y-1,color);
Draw_Circle(x,y,6,color);//画中心圈
}
//画一个大点(2*2的点)
//x,y:坐标
//color:颜色
void TP_Draw_Big_Point(u16 x,u16 y,u16 color)
{
LCD_DrawPoint(x,y,color);//中心点
LCD_DrawPoint(x+1,y,color);
LCD_DrawPoint(x,y+1,color);
LCD_DrawPoint(x+1,y+1,color);
}
/******************************************************************************
函数说明:画线
入口数据:x1,y1 起始坐标
x2,y2 终止坐标
color 线的颜色
返回值: 无
******************************************************************************/
void LCD_DrawRoughLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 color)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;//画线起点坐标
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if (delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if (delta_y==0)incy=0;//水平线
else {incy=-1;delta_y=-delta_y;}
if(delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<distance+1;t++)
{
TP_Draw_Big_Point(uRow,uCol,color);//画点
xerr+=delta_x;
yerr+=delta_y;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
}
//////////////////////////////////////////////////////////////////////////////////
//触摸按键扫描
//tp:0,屏幕坐标;1,物理坐标(校准等特殊场合用)
//返回值:当前触屏状态.
//0,触屏无触摸;1,触屏有触摸
u8 TP_Scan(u8 tp)
{
if(PEN==0)//有按键按下
{
if(tp)TP_Read_XY2(&tp_dev.x[],&tp_dev.y[]);//读取物理坐标
else if(TP_Read_XY2(&tp_dev.x[],&tp_dev.y[]))//读取屏幕坐标
{
tp_dev.x[]=tp_dev.xfac*tp_dev.x[]+tp_dev.xoff;//将结果转换为屏幕坐标
tp_dev.y[]=tp_dev.yfac*tp_dev.y[]+tp_dev.yoff;
}
if((tp_dev.sta&TP_PRES_DOWN)==0)//之前没有被按下
{
tp_dev.sta=TP_PRES_DOWN|TP_CATH_PRES;//按键按下
tp_dev.x[]=tp_dev.x[];//记录第一次按下时的坐标
tp_dev.y[]=tp_dev.y[];
}
}else
{
if(tp_dev.sta&TP_PRES_DOWN)//之前是被按下的
{
tp_dev.sta&=~(1<<7);//标记按键松开
}else//之前就没有被按下
{
tp_dev.x[]=0;
tp_dev.y[]=0;
tp_dev.x[]=0xffff;
tp_dev.y[]=0xffff;
}
}
return tp_dev.sta&TP_PRES_DOWN;//返回当前的触屏状态
}
//触摸屏校准代码
//得到四个校准参数
void TP_Adjust(void)
{
u16 pos_temp[][];//坐标缓存值
u8 cnt=0;
u16 d1,d2;
u32 tem1,tem2;
double fac;
cnt=0;
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);//清屏
LCD_ShowString(5,40,"Please adjust!",RED,WHITE,16,0);//显示提示信息
TP_Drow_Touch_Point(20,20,RED);//画点1
tp_dev.sta=0;//消除触发信号
tp_dev.xfac=0;//xfac用来标记是否校准过,所以校准之前必须清掉!以免错误
while(1)//如果连续10秒钟没有按下,则自动退出
{
tp_dev.scan(1);//扫描物理坐标
if((tp_dev.sta&0xc0)==TP_CATH_PRES)//按键按下了一次(此时按键松开了.)
{
tp_dev.sta&=~(1<<6);//标记按键已经被处理过了.
pos_temp[][]=tp_dev.x[];
pos_temp[][]=tp_dev.y[];
cnt++;
switch(cnt)
{
case 1:
TP_Drow_Touch_Point(20,20,WHITE); //清除点1
TP_Drow_Touch_Point(LCD_W-20,20,RED); //画点2
break;
case 2:
TP_Drow_Touch_Point(LCD_W-20,20,WHITE); //清除点2
TP_Drow_Touch_Point(20,LCD_H-20,RED); //画点3
break;
case 3:
TP_Drow_Touch_Point(20,LCD_H-20,WHITE); //清除点3
TP_Drow_Touch_Point(LCD_W-20,LCD_H-20,RED); //画点4
break;
case 4: //全部四个点已经得到
//对边相等
tem1=abs(pos_temp[][]-pos_temp[][]);//x1-x2
tem2=abs(pos_temp[][]-pos_temp[][]);//y1-y2
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,2的距离
tem1=abs(pos_temp[][]-pos_temp[][]);//x3-x4
tem2=abs(pos_temp[][]-pos_temp[][]);//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_W-20,LCD_H-20,WHITE); //清除点4
TP_Drow_Touch_Point(20,20,RED); //画点1
LCD_ShowString(5,40,"Adjust Filed! ",RED,WHITE,16,0);//校正失败提示
LCD_ShowString(5,60,"Please Adjust!",RED,WHITE,16,0);//校正失败提示
delay_ms(1000);
continue;
}
tem1=abs(pos_temp[][]-pos_temp[][]);//x1-x3
tem2=abs(pos_temp[][]-pos_temp[][]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,3的距离
tem1=abs(pos_temp[][]-pos_temp[][]);//x2-x4
tem2=abs(pos_temp[][]-pos_temp[][]);//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_W-20,LCD_H-20,WHITE); //清除点4
TP_Drow_Touch_Point(20,20,RED); //画点1
LCD_ShowString(5,40,"Adjust Filed! ",RED,WHITE,16,0);//校正失败提示
LCD_ShowString(5,60,"Please Adjust!",RED,WHITE,16,0);//校正失败提示
delay_ms(1000);
continue;
}//正确了
//对角线相等
tem1=abs(pos_temp[][]-pos_temp[][]);//x1-x3
tem2=abs(pos_temp[][]-pos_temp[][]);//y1-y3
tem1*=tem1;
tem2*=tem2;
d1=sqrt(tem1+tem2);//得到1,4的距离
tem1=abs(pos_temp[][]-pos_temp[][]);//x2-x4
tem2=abs(pos_temp[][]-pos_temp[][]);//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_W-20,LCD_H-20,WHITE); //清除点4
TP_Drow_Touch_Point(20,20,RED); //画点1
LCD_ShowString(5,40,"Adjust Filed! ",RED,WHITE,16,0);//校正失败提示
LCD_ShowString(5,60,"Please Adjust!",RED,WHITE,16,0);//校正失败提示
delay_ms(1000);
continue;
}//正确了
//计算结果
tp_dev.xfac=(float)(LCD_W-40)/(pos_temp[][]-pos_temp[][]);//得到xfac
tp_dev.xoff=(LCD_W-tp_dev.xfac*(pos_temp[][]+pos_temp[][]))/2;//得到xoff
tp_dev.yfac=(float)(LCD_H-40)/(pos_temp[][]-pos_temp[][]);//得到yfac
tp_dev.yoff=(LCD_H-tp_dev.yfac*(pos_temp[][]+pos_temp[][]))/2;//得到yoff
TP_Drow_Touch_Point(LCD_W-20,LCD_H-20,WHITE); //清除点4
LCD_ShowString(5,40," Adjust OK! ",RED,WHITE,16,0);//校正完成
LCD_ShowString(5,60," ",RED,WHITE,16,0);//清除文字
delay_ms(1000);
LCD_ShowString(5,40," ",RED,WHITE,16,0);//清除文字
return;//校正完成
}
}
}
}
//触摸屏初始化
u8 TP_Init(void)
{
u8 fac[];
if(Adujust)
{
if(USE_HORIZONTAL==0)
{//***因触摸屏批次不同等原因,默认的校准参数值可能会引起触摸识别不准,建议校准后再使用,不建议使用固定的默认校准参数
tp_dev.xfac=-0.035584;
tp_dev.xoff=136;
tp_dev.yfac=-0.043796;
tp_dev.yoff=169;
}else if(USE_HORIZONTAL==1)
{//***因触摸屏批次不同等原因,默认的校准参数值可能会引起触摸识别不准,建议校准后再使用,不建议使用固定的默认校准参数
tp_dev.xfac=0.034810;
tp_dev.xoff=-5;
tp_dev.yfac=0.043057;
tp_dev.yoff=-7;
}else if(USE_HORIZONTAL==2)
{//***因触摸屏批次不同等原因,默认的校准参数值可能会引起触摸识别不准,建议校准后再使用,不建议使用固定的默认校准参数
tp_dev.xfac=-0.045232;
tp_dev.xoff=171;
tp_dev.yfac=0.039321;
tp_dev.yoff=-13;
}else
{//***因触摸屏批次不同等原因,默认的校准参数值可能会引起触摸识别不准,建议校准后再使用,不建议使用固定的默认校准参数
tp_dev.xfac=0.045627;
tp_dev.xoff=-11;
tp_dev.yfac=-0.037006;
tp_dev.yoff=137;
}
return 0;
}else
{
TP_Adjust();//屏幕校准
//校准参数显示在LCD上,如果默认参数不准,请手动校正后自行修改
sprintf((char*)fac,"xfac:%10.6f",tp_dev.xfac);
LCD_ShowString(10,LCD_H-118,fac,RED,WHITE,16,0);
sprintf((char*)fac,"xoff:%d",tp_dev.xoff);
LCD_ShowString(10,LCD_H-102,fac,RED,WHITE,16,0);
sprintf((char*)fac,"yfac:%10.6f",tp_dev.yfac);
LCD_ShowString(10,LCD_H-86,fac,RED,WHITE,16,0);
sprintf((char*)fac,"yoff:%d",tp_dev.yoff);
LCD_ShowString(10,LCD_H-70,fac,RED,WHITE,16,0);
return 1;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
到这里软件SPI就移植完成了,请移步到1.8.4节进行移植验证。
移植验证
在main.c中输入代码如下
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#include "pic.h"
#include "lcd_init.h"
#include "lcd.h"
#include "touch.h"
int main(void)
{
float t=0;
u16 lastpos[];//最后一次的数据
systick_config(); //滴答定时器初始化 1ms
LCD_Init();//LCD初始化
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
lastpos[]=0XFFFF;
LCD_ShowString(24,30,"LCD_W:",RED,WHITE,16,0);
LCD_ShowIntNum(72,30,LCD_W,3,RED,WHITE,16);
LCD_ShowString(24,50,"LCD_H:",RED,WHITE,16,0);
LCD_ShowIntNum(72,50,LCD_H,3,RED,WHITE,16);
LCD_ShowFloatNum1(20,80,t,4,RED,WHITE,16);
t+=0.11;
LCD_ShowPicture(65,80,40,40,gImage_1);
delay_1ms(1000);
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
TP_Init();
LCD_ShowString(10,LCD_H-40,"X:",RED,WHITE,16,0);
LCD_ShowIntNum(26,LCD_H-40,0,3,RED,WHITE,16);
LCD_ShowString(10,LCD_H-20,"Y:",RED,WHITE,16,0);
LCD_ShowIntNum(26,LCD_H-20,0,3,RED,WHITE,16);
while(1)
{
tp_dev.scan(0);//扫描
if(tp_dev.sta&TP_PRES_DOWN)//有按键被按下
{
delay_1ms(1);//必要的延时,否则老认为有按键按下.
if((tp_dev.x[]<(LCD_W-1)&&tp_dev.x[]>=1)&&(tp_dev.y[]<(LCD_H-1)&&tp_dev.y[]>=1))
{
if(lastpos[]==0XFFFF)
{
lastpos[]=tp_dev.x[];
lastpos[]=tp_dev.y[];
}
//给触摸过的地方画线
LCD_DrawRoughLine(lastpos[],lastpos[],tp_dev.x[],tp_dev.y[],BLUE);
lastpos[]=tp_dev.x[];
lastpos[]=tp_dev.y[];
//显示当前触摸位置的X轴坐标
LCD_ShowString(10,LCD_H-40,"X:",RED,WHITE,16,0);
LCD_ShowIntNum(26,LCD_H-40,tp_dev.x[],3,RED,WHITE,16);
//显示当前触摸位置的Y轴坐标
LCD_ShowString(10,LCD_H-20,"Y:",RED,WHITE,16,0);
LCD_ShowIntNum(26,LCD_H-20,tp_dev.y[],3,RED,WHITE,16);
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
上电效果