stm32 触摸屏 XPT2046

来源:互联网 发布:巴尔扎的军靴知乎 编辑:程序博客网 时间:2024/05/08 23:54

引脚功能描述
1

控制字的控制位命令
1

控制字节各位描述
1

单端模式输入配置
1

差分模式输入配置
1

时序
前8个时钟用来通过DIN引脚输入控制字节,接着的12个时钟周期将完成真正的模数转换,剩下的3个多时钟周期将用来完成被转换器忽略的最后字节(DOUT置低)

1

举例
1
2
3

#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");            }        }    }}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 胸变的又软又小怎么办 u盘16g变成4g了怎么办 1岁宝宝吃了就吐怎么办 脚崴了肿了很痛怎么办 九格拼图5在9那怎么办 4s锁屏密码忘了怎么办 6p触屏偶尔乱跳怎么办 新办劳务公司的劳务资质怎么办 汽车没电了打不着火怎么办 吃凉的甜的牙疼怎么办 学车对点对不上怎么办 发现老公有外遇最明智的怎么办 想开个童装店但是没经验怎么办 母乳不够吃宝宝又不喝奶粉怎么办 掉头发很厉害怎么办有什么偏方 红米2a刷死机了怎么办 公司退市我们买的股票怎么办 黑魂3把npc杀了怎么办 摔倒了膝盖摔肿了又痛怎么办 厕所堵了怎么办疏通马桶有妙招 月经不来怎么办如何让它快点来 苹果手机进水了开不了机怎么办 苹果5s进水了怎么办修要多少钱 吃了过期3年的药怎么办 离婚后孩子的抚养费不给怎么办 小车钥匙丢了怎么办配要多少钱 一键启动的车钥匙丢了怎么办 股票退市了手里的股票怎么办 3d硬金以后要换怎么办 偏指甲红肿长在了肉里怎么办 牙齿黄怎么办教你牙齿美白小窍门 2岁孩门牙磕断了怎么办 脸上用了含激素的产品应该怎么办 身上起红疙瘩水泡很痒怎么办 怀疑老公有外遇他不承认怎么办 苹果手机锁屏密码忘了怎么办 黑色t恤洗了掉毛怎么办 老婆要和我离婚我该怎么办 发现老婆有外遇最明智的怎么办 高度近视怎么办我快一千度近 天刀耐久度为0了怎么办