硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5608|回复: 0
收起左侧

[emWin] 升级emWin的横竖屏任意切换方式,触摸不好用的解决办法

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2015-4-21 19:45:04 | 显示全部楼层 |阅读模式
有两处特别注意,看红体地方即可:
RA8875显示方向调整:

/*
*********************************************************************************************************
*    函 数 名: RA8875_SetDirection
*    功能说明: 设置显示方向。
*    形    参:  _ucDir : 显示方向代码 0 横屏正常, 1=横屏180度翻转, 2=竖屏, 3=竖屏180度翻转
*    返 回 值: 无
*********************************************************************************************************
*/
void RA8875_SetDirection(uint8_t _ucDir)
{
    uint8_t reg20H = 0;

    /*     REG[40h] Memory Write Control Register 0 (MWCR0)


    Bit 3-2  绘图模式时的内存写入方向
        00b : 左 -> 右,然后上 -> 下。
        01b : 右 -> 左,然后上 -> 下。
        10b : 上 -> 下,然后左 -> 右。
        11b : 下 -> 上,然后左 -> 右。


    Bit 1     内存写入光标自动增加功能设定
        0 : 当内存写入时光标位置自动加一。
        1 : 当内存写入时光标位置不会自动加一。


    Bit 0 内存读取光标自动增加功能设定
        0 : 当内存读取时光标位置自动加一。
        1 : 当内存读取时光标位置不会自动加一。
    */
    s_reg_40H = 0x01;

    if (_ucDir == 0)
    {
        s_reg_40H = 0x01;
        reg20H = (0 << 3) | (0 << 2);
    }
    else if (_ucDir == 1)
    {
        s_reg_40H = 0x01;               ================》这个得改了,裸机的时候使用没问题,但在emWin上有问题,很奇怪。
        reg20H = (1 << 3) | (1 << 2);
    }
    else if (_ucDir == 2)
    {
        s_reg_40H = 0x09;
        reg20H = (0 << 3) | (1 << 2);
    }
    else if (_ucDir == 3)
    {
        s_reg_40H = 0x09;
        reg20H = (1 << 3) | (0 << 2);
    }
    RA8875_WriteReg(0x40, s_reg_40H);   


    /*
        REG[20h] Display Configuration Register (DPCR)
        Bit  说  明  初始值  Access
        Bit7
            图层设定(Layer Control)
            0 : 单图层。
            1 : 双图层。
        Bit3  HDIR 水平扫描方向设定(n = SEG number)
            0 : 由SEG0 到SEG(n-1)。
            1 : 由SEG(n-1) 到SEG0。
        Bit2 VDIR 垂直扫描方向设定(n = COM number)
            0 : 由COM0 到COM(n-1)。
            1 : 由COM(n-1) 到COM0。
    */
    RA8875_WriteReg(0x20, reg20H);   


    if (_ucDir > 1)    /* 竖屏  */
    {
        uint16_t temp;

        if (g_LcdHeight < g_LcdWidth)
        {
            temp = g_LcdHeight;
            g_LcdHeight = g_LcdWidth;
            g_LcdWidth = temp;
        }
    }        
    else    /* 横屏 */
    {
        uint16_t temp;

        if (g_LcdHeight > g_LcdWidth)
        {
            temp = g_LcdHeight;
            g_LcdHeight = g_LcdWidth;
            g_LcdWidth = temp;
        }
    }
}
==============================================================

/*
*********************************************************************************************************
*    函 数 名: TOUCH_TransX
*    功能说明: 将触摸ADC值转换为像素坐标
*    形    参:  无
*    返 回 值: X 坐标值,允许负值
*********************************************************************************************************
*/
static int16_t TOUCH_TransX(uint16_t _usAdcX, uint16_t _usAdcY)
{
#if CALIB_POINT_COUNT == 2    /* 2点校准 */
    uint16_t x;
    int32_t y;

    if (g_tTP.XYChange == 0)
    {
        x = _usAdcX;
        if (x == 0)
        {
            y = 0;
        }
        else
        {
            //y = CalTwoPoint(g_tTP.usAdcX1, TP_X1, g_tTP.usAdcX2, TP_X2, x);
            y = CalTwoPoint(g_tTP.usAdcX1, g_tTP.usLcdX1, g_tTP.usAdcX2, g_tTP.usLcdX2, x);
        }
    }
    else
    {
        x = _usAdcY;
        if (x == 0)
        {
            y = 0;
        }
        else
        {
            //y = CalTwoPoint(g_tTP.usAdcY1, TP_X1, g_tTP.usAdcY2, TP_X2, x);
            y = CalTwoPoint(g_tTP.usAdcY1, g_tTP.usLcdX1, g_tTP.usAdcY2, g_tTP.usLcdX2, x);
        }
    }
    return y;
#else        /* 4点校准 */
    uint16_t x, x1, x2;
    int32_t y;

    if (g_tTP.XYChange == 0)    /* X Y 坐标不交换 */
    {
        x = _usAdcX;

        /* 根据 Y ADC 实时计算直线方程的参考点x1, x2
            if  _usAdcY = usAdcY1 then  取点 = (AdcX1, TP_X1, AdcX4, TP_X4, _usAdcY)
            if  _usAdcY = usAdcY2 then  取点 = (AdcX3, TP_X3, AdcX2, TP_X2, _usAdcY)

            其中 TP_X1 = TP_X3;  TP_X4 = TP_X1 , 这是程序设定的校准位置的像素坐标, 是固定的。
            我们仅需要动态计算对第1个和第3个参数。同样采用2点直线方程计算。
        */
        x1 = CalTwoPoint(g_tTP.usAdcY1, g_tTP.usAdcX1, g_tTP.usAdcY2,  g_tTP.usAdcX3, _usAdcY);
        x2 = CalTwoPoint(g_tTP.usAdcY1, g_tTP.usAdcX4, g_tTP.usAdcY2,  g_tTP.usAdcX2, _usAdcY);
    }
    else                        /* X Y 坐标交换 */
    {
        x = _usAdcY;

        /* 根据 X ADC 实时计算直线方程的参考点x1, x2
            if  _usAdcX = usAdcX1 then  取点 = (AdcY1, TP_X1, AdcY4, TP_X4, _usAdcX)
            if  _usAdcX = usAdcX2 then  取点 = (AdcY3, TP_X3, AdcY2, TP_X2, _usAdcX)

            其中 TP_X1 = TP_X3;  TP_X4 = TP_X1 , 这是程序设定的校准位置的像素坐标, 是固定的。
            我们仅需要动态计算对第1个和第3个参数。同样采用2点直线方程计算。
        */
        x1 = CalTwoPoint(g_tTP.usAdcX1, g_tTP.usAdcY1, g_tTP.usAdcX2,  g_tTP.usAdcY3, _usAdcX);
        x2 = CalTwoPoint(g_tTP.usAdcX1, g_tTP.usAdcY4, g_tTP.usAdcX2,  g_tTP.usAdcY2, _usAdcX);
    }

    if (x == 0)
    {
        y = 0;
    }
    else
    {
        /* 根据2点直线方程,计算坐标 */
//        y = CalTwoPoint(x1, TP_X1, x2, TP_X2, x);      ================================》这个不行,其中参数TP_X1和TP_X2是常数,这个地方最邪门!!!!!                     
        y = CalTwoPoint(x1, g_tTP.usLcdX1, x2, g_tTP.usLcdX2, x);
    }
    return y;
#endif
}

函数原型:
#define CALIB_OFFSET    20
#define TP_X1    CALIB_OFFSET
#define TP_Y1    CALIB_OFFSET


/**********************************************************************************************************
*    函 数 名: CalTwoPoint*    功能说明: 根据2点直线方程,计算Y值
*    形    参:  2个点的坐标和x输入量*    返 回 值: x对应的y值
**********************************************************************************************************/
static int32_t CalTwoPoint(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x){
    return y1 + ((int32_t)(y2 - y1) * (x - x1)) / (x2 - x1);}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 06:07 , Processed in 0.036642 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表