针的功能说明
控制字的控制位指令
控制字节的各说明
单端模式输入配置
差分模式输入结构
时间序列
前8个时钟用于从DIN引脚输入控制字节,后12个时钟周期用于完成真正的模数转换,剩下的3个多时钟周期用于完成转换器忽略的最后一个字节(例如
举个例子
#define TOUCH_READ_TIMES 40 //读取次数
#define TOUCH_ERR_RANGE 20 //误差范围
#define TOUCH_X_CMD0xD0 //读取x轴
#define TOUCH_Y_CMD0x90 //读取y轴
#define TOUCH_Continue_Read0xFF
#define TOUCH_X_MAX 4000 //X最高值
#define TOUCH_X_MIN 100 //X最小值
#define TOUCH_Y_MAX 4000 //Y最高值
#define TOUCH_Y_MIN 100 //X最小值
#defineLCD_calx_min(10 ) /校准点最小值x
# define LCD _ calx _ max (tft LCD _ data.width-LCD _ calx _ min ) /校准点最大值x
#defineLCD_caly_min(10 ) /校准点最小值y
# define LCD _ caly _ max (tft LCD _ 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
类型结构
{
u8标志;
短偏移;
短偏移;
浮动x因子;
浮动因子;
} calibrate_t;
calibrate_t calibrate={0};
u16托尔克斯;
u16托克丝;
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 _ full duplex,
SPI_Mode_Master,//0x0104
SPI_DataSize_8b,
SPI_CPOL_High,
SPI_CPHA_2Edge,
SPI_NSS_Soft,
SPI_BaudRatePrescaler_256,
SPI_FirstBit_MSB,
7
(;
RCC _ AP B2 periphclockcmd (RCC _ AP B2 per iph _ SPI1| RCC _ AP B2 per iph _ gpioa|RCC _ AP B2 per iph _ gpiod,ENABLE );
Gpio_init(gpioa,gpioa );
gpio_init(gp
IOD, &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 %dn", calibrate.xoffset);
printf("yoffset %dn", calibrate.yoffset);
printf("xFactor %fn", calibrate.xFactor);
printf("yFactor %fn", 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");
}
}
}
}