历史上的今天
返回首页

历史上的今天

今天是:2025年01月04日(星期六)

2019年01月04日 | stm32 触摸屏 XPT2046

2019-01-04 来源:eefocus

引脚功能描述 

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");

            }

        }

    }

}


推荐阅读

史海拾趣

Eclipse Magnetics公司的发展小趣事

由于篇幅限制,无法在此处直接提供5个完整的、每篇至少500字的Eclipse Magnetics公司电子行业发展的相关故事。不过,我可以概括地描述几个可能的故事线索,这些线索可以基于Eclipse Magnetics公司的历史、技术发展和市场应用来构建。

  1. 品牌初创与磁铁技术的突破

在1930年代,Eclipse Magnetics的名字首次出现,标志着这个品牌的诞生。随着技术的不断发展,公司在1940年代成为独立公司,并开始专注于磁铁技术的研发。到了1950年代,Eclipse Magnetics在技术上取得了重大突破,他们将磁铁涂上红色,并设计了与公司颜色相匹配的马蹄形标志,这一设计不仅提升了品牌形象,也成为了国际通用标记。这一时期的Eclipse Magnetics,以其独特的技术和产品,开始在电子行业中崭露头角。

  1. 航空航天领域的应用与拓展

随着航空航天技术的不断发展,Eclipse Magnetics看到了磁铁技术在该领域的巨大潜力。公司开始投入大量资源,研发适用于航空航天领域的磁性解决方案。通过不断的技术创新和产品优化,Eclipse Magnetics成功地为航空航天领域提供了高性能、高可靠性的磁铁产品,并在这一领域树立了良好的口碑。

  1. 与制药工业的深入合作

除了航空航天领域,Eclipse Magnetics还与制药工业建立了深入的合作关系。在制药过程中,磁铁技术可以用于磁选机,有效地去除原料中的杂质,提高药品的纯度。Eclipse Magnetics根据制药工业的特殊需求,定制了多款磁选机产品,并提供了全面的技术支持和售后服务。通过与制药工业的深入合作,Eclipse Magnetics不仅拓展了市场,也提升了自身的技术实力。

  1. 在汽车制造行业的应用

随着汽车制造业的快速发展,Eclipse Magnetics也看到了磁铁技术在该领域的广阔前景。公司针对汽车制造中的各个环节,研发了多款适用于不同场景的磁性解决方案。例如,在齿轮箱轴制造过程中,Eclipse Magnetics的磁性过滤器可以保持冷却液的清洁,提高生产效率和产品质量。这些解决方案不仅满足了汽车制造业的需求,也进一步巩固了Eclipse Magnetics在电子行业中的地位。

  1. 创新研发与可持续发展

作为一家专注于磁性技术的公司,Eclipse Magnetics始终将创新作为发展的核心动力。公司不断投入研发资源,推动磁铁技术的不断进步。同时,Eclipse Magnetics也关注可持续发展问题,致力于研发环保、高效的磁性产品。通过创新研发和可持续发展战略的实施,Eclipse Magnetics在电子行业中保持了领先地位,并为未来的发展奠定了坚实的基础。

请注意,以上内容仅为故事线索的概括描述,具体的故事细节和数据需要根据Eclipse Magnetics公司的实际情况进行补充和完善。

Aptiv公司的发展小趣事

随着数字化时代的到来,Aptiv积极拥抱数字化转型,通过引入先进的信息技术和管理系统,提升了企业的运营效率和市场竞争力。例如,公司向汽车行业某公司发出EDI对接邀请,计划通过EDI系统实现双方的数据共享和业务协同,从而提高了工作效率和下单准确性。这种数字化转型不仅有助于Aptiv在激烈的市场竞争中保持领先地位,还为整个电子行业的数字化转型提供了有益的借鉴和参考。

这五个故事展示了Aptiv公司在电子行业中的发展历程和成就,从技术创新到全球布局、创新合作、社会责任以及数字化转型等方面,都体现了公司的实力和担当。Aptiv以其卓越的技术实力和市场表现,成为了电子行业中一颗璀璨的明星。

API Delevan公司的发展小趣事

随着技术的不断进步,API Delevan公司始终保持着对创新的追求。研发团队不断攻克技术难关,推出了一系列具有创新性的电感器、RF线圈、功率电感器等产品。这些产品不仅提高了性能,还降低了能耗,满足了客户的多样化需求。同时,公司还注重产品升级,不断提升产品的竞争力。

CTC Coils Ltd公司的发展小趣事

面对日益严峻的环境问题,CTC Coils Ltd公司积极响应国家绿色发展的号召,开始实施绿色环保战略。公司引进先进的生产设备和工艺,优化生产流程,减少能源消耗和废物排放。同时,公司还研发出了一系列环保型电感线圈产品,满足了市场对绿色电子产品的需求。

GSR Technology Ltd公司的发展小趣事

在电子行业的初期,GSR Technology Ltd专注于研发高性能的传感器技术,特别是针对工业自动化领域的GSR(Ground Surveillance Radar,地面监视雷达)技术。通过多年的技术积累和研发创新,公司成功开发出具有高精度、长距离监测能力的GSR系统,填补了市场空白。这一技术突破吸引了众多工业客户的关注,公司迅速获得市场准入,并与多家知名企业建立了长期合作关系。

AEL [AEL Crystals Ltd]公司的发展小趣事

AEL Crystals非常重视与供应商和客户之间的合作关系。公司积极与供应商建立长期稳定的合作关系,确保原材料的稳定供应和质量可靠。同时,AEL Crystals也与众多客户建立了紧密的合作关系,深入了解客户需求并提供定制化的解决方案。这种长期合作关系的建立为公司的持续发展提供了有力保障。

问答坊 | AI 解惑

这里有朋友搞vxworks操作系统的嘛?

请问这里有朋友搞vxworks操作系统的嘛?…

查看全部问答>

开启物联网时代--中国首颗手机传感芯片推出

本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 12月7日消息,上海芯片企业深迪半导体宣布,国内第一款具有中国自主知识产权的商用MEMS陀螺仪诞生,这是国内首颗手机传感器芯片,将改变我国手机MEMS陀螺仪完全从国外进口的历史。 中 ...…

查看全部问答>

如何精确控制多个继电器的延时触发?

我现在需要工控机(IPC)控制30个继电器并行工作,要求延时精度在1毫秒, windows够精度的方法都太耗资源,不能同时开30个,只好想办法硬件解决…… 不知道有没有这类现成的继电器输出板卡可以选? 另外单片机最多有内置多少个定时器的?或者只 ...…

查看全部问答>

单片机和嵌入式

我是从软件转到嵌入式的,最近在学习S3C2440(ARM9T),想自己写一个类似Uboot的程序,于是开始看芯片技术文档。发现看不懂,阅读uboot的原代码,那些芯片的配置也已经让我焦头烂额了,现在是举步维艰。还请高人给指条路。先谢过了。…

查看全部问答>

基于TFT彩屏的51源程序代码

大家有彩屏的资料 拿出来嗮嗮咯!!!…

查看全部问答>

使用430F437发现32K晶体起振速度很慢,引起LCD显示开机不正常。

使用430F437发现32K晶体起振速度很慢,引起LCD显示开机不正常。 是什么原因引起的,我怎么改电容都不行啊。…

查看全部问答>

TI grlib widget层调用问题

用LM3s9b96自己画了块板子,使用了一块240*400的TFT LCD。已经将grlib 的 Displaydriver 层修改好,现在调用displaydriver层或者graphics primitives层的函数均可正常使用。对于widget层,如果widget tree结构<3可以正常工作,再多则出问题,贴下 ...…

查看全部问答>

sitara 板子已收到

sitara 板子已收到,还没拆开看,晚上上图 ___________________________________________________ 对不住大家了,晚上光线不好,照了几张惨不忍睹,就不上传了。 屏幕色彩不太好,其他都很不错。 [ 本帖最后由 lcofjp 于 2012-11-20 19:50 编辑 ...…

查看全部问答>

按这八项去做,电脑慢下来都难

  先看一下电脑的“系统资源”是多少,右键单击“我的电脑”,选择“属性”,再选择“性能”,看一下“系统资源”是多少,一般应该达到95%左右还差不多。   1、电脑桌面上的东西越少越好,我的电脑桌面上就只有“我的电脑”和“回收站”。东西 ...…

查看全部问答>

Linux驱动程序工作原理简介

[Linux资料]Linux驱动程序工作原理简介 Linux驱动程序工作原理简介 一、linux驱动程序的数据结构        1 二、设备节点如何产生?        2 三、应用程序是如何访问设备驱动程序的?    &n ...…

查看全部问答>