628|2

107

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【兆易GD32H759I-EVAL】 触摸屏驱动实验 [复制链接]

  本帖最后由 尹小舟 于 2024-6-23 22:01 编辑

实验目的  能够读取触摸屏x,yz值

 

电路接口

 

 

XPT2046 芯片

1. 电阻触摸屏与XPT2046

电阻触摸屏通常包含两层导电材料,当触摸屏被按下时,这两层材料会在某个点接触,从而改变其电阻值。XPT2046通过测量这些电阻值的变化来确定触摸点的位置。

2. XPT2046芯片特点

  • 分辨率与转换速率:XPT2046是一款12位的ADC芯片,具有125KHz的转换速率,能够提供高精度的坐标检测。
  • 工作电压:工作电压范围为2.2V~5.25V,支持1.5V~5.25V的数字I/O口。
  • 功能丰富:内建2.5V参考电压源,支持电源电压测量(0V~6V)、内建温度测量功能和触摸压力测量。
  • 通信接口:采用SPI 3线控制通信接口,支持标准SPI接口时序。
  • 功耗与封装:在125KHz转换速率和2.7V电压下的功耗仅为750 µW。封装有QFN-16、TSSOP-16和VFBGA-48等选项。

3. 电阻触摸驱动实现

  • 初始化:在驱动程序中,首先需要对XPT2046进行初始化,设置工作参数,如分辨率、采样率等。
  • 坐标检测:通过执行两次A/D转换来检测触摸屏上被按下的位置。首先,在X+电极施加驱动电压,X-接地,通过Y+或Y-测量电压值来获取X坐标;然后,在Y+电极施加驱动电压,Y-接地,通过X+或X-测量电压值来获取Y坐标。
  • 中断处理:XPT2046支持笔中断输出,该引脚可以配置到单片机的中断脚上。当触摸屏被按下时,会产生中断信号,触发中断处理函数。在中断处理函数中,可以读取触摸屏的坐标数据并进行相应处理。
  • 功耗管理:通过配置XPT2046的工作模式和参考电压等参数,可以降低功耗。例如,在不需要频繁检测触摸事件时,可以关闭参考电压以降低功耗。

 

 

实验代码

 


_m_tp_dev tp_dev =
{
    tp_init,
    tp_scan,
    tp_adjust,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
};



/**
 * @brief   SPI写数据
 *   @note      向触摸屏IC写入1 byte数据
 * @param       data: 要写入的数据
 * @retval      无
 */
static void tp_write_byte(uint8_t data)
{
    uint8_t count = 0;

    for (count = 0; count < 8; count++)
    {
        if (data & 0x80)    /* 发送1 */
        {
            T_MOSI(1);
        }
        else                /* 发送0 */
        {
            T_MOSI(0);
        }

        data <<= 1;
        T_CLK(0);
        delay_us(1);
        T_CLK(1);           /* 上升沿有效 */
    }
}

/**
 * @brief       SPI读数据
 *   @note      从触摸屏IC读取adc值
 * @param       cmd: 指令
 * @retval      读取到的数据,ADC值(12bit)
 */
static uint16_t tp_read_ad(uint8_t cmd)
{
    uint8_t count = 0;
    uint16_t num = 0;
    T_CLK(0);           /* 先拉低时钟 */
    T_MOSI(0);          /* 拉低数据线 */
    T_CS(0);            /* 选中触摸屏IC */
    tp_write_byte(cmd); /* 发送命令字 */
    delay_us(6);        /* ADS7846的转换时间最长为6us */
    T_CLK(0);
    delay_us(1);
    T_CLK(1);           /* 给1个时钟,清除BUSY */
    delay_us(1);
    T_CLK(0);

    for (count = 0; count < 16; count++)    /* 读出16位数据,只有高12位有效 */
    {
        num <<= 1;
        T_CLK(0);       /* 下降沿有效 */
        delay_us(1);
        T_CLK(1);

        if (T_MISO)num++;
    }

    num >>= 4;          /* 只有高12位有效. */
    T_CS(1);            /* 释放片选 */
    return num;
}

/* 电阻触摸驱动芯片 数据采集 滤波用参数 */
#define TP_READ_TIMES   5       /* 读取次数 */
#define TP_LOST_VAL     1       /* 丢弃值 */

/**
 * @brief       读取一个坐标值(x或者y)
 *   @note      连续读取TP_READ_TIMES次数据,对这些数据升序排列,
 *              然后去掉最低和最高TP_LOST_VAL个数, 取平均值
 *              设置时需满足: TP_READ_TIMES > 2*TP_LOST_VAL 的条件
 *
 * @param       cmd : 指令
 *   @arg   0XD0: 读取X轴坐标(@竖屏状态,横屏状态和Y对调.)
 *   @arg       0X90: 读取Y轴坐标(@竖屏状态,横屏状态和X对调.)
 *
 * @retval      读取到的数据(滤波后的), ADC值(12bit)
 */
static uint16_t tp_read_xoy(uint8_t cmd)
{
    uint16_t i, j;
    uint16_t buf[TP_READ_TIMES];
    uint16_t sum = 0;
    uint16_t temp;

    for (i = 0; i < TP_READ_TIMES; i++)   /* 先读取TP_READ_TIMES次数据 */
    {
        buf[i] = tp_read_ad(cmd);
    }

    for (i = 0; i < TP_READ_TIMES - 1; i++)   /* 对数据进行排序 */
    {
        for (j = i + 1; j < TP_READ_TIMES; j++)
        {
            if (buf[i] > buf[j])   /* 升序排列 */
            {
                temp = buf[i];
                buf[i] = buf[j];
                buf[j] = temp;
            }
        }
    }

    sum = 0;

    for (i = TP_LOST_VAL; i < TP_READ_TIMES - TP_LOST_VAL; i++)   /* 去掉两端的丢弃值 */
    {
        sum += buf[i];  /* 累加去掉丢弃值以后的数据. */
    }

    temp = sum / (TP_READ_TIMES - 2 * TP_LOST_VAL); /* 取平均值 */
    return temp;
}

/**
 * @brief       读取x, y坐标
 * @param       x,y: 读取到的坐标值
 * @retval      无
 */
static void tp_read_xy(uint16_t *x, uint16_t *y)
{
    uint16_t xval, yval;

    if (tp_dev.touchtype & 0X01)    /* X,Y方向与屏幕相反 */
    {
        xval = tp_read_xoy(0X90);   /* 读取X轴坐标AD值, 并进行方向变换 */
        yval = tp_read_xoy(0XD0);   /* 读取Y轴坐标AD值 */
    }
    else                    /* X,Y方向与屏幕相同 */
    {
        xval = tp_read_xoy(0XD0);   /* 读取X轴坐标AD值 */
        yval = tp_read_xoy(0X90);   /* 读取Y轴坐标AD值 */
    }

    *x = xval;
    *y = yval;
}

/* 连续两次读取X,Y坐标的数据误差最大允许值 */
#define TP_ERR_RANGE    50      /* 误差范围 */

/**
 * @brief       连续读取2次触摸IC数据, 并滤波
 *   @note      连续2次读取触摸屏IC,且这两次的偏差不能超过ERR_RANGE,满足
 *              条件,则认为读数正确,否则读数错误.该函数能大大提高准确度.
 *
 * @param       x,y: 读取到的坐标值
 * @retval      0, 失败; 1, 成功;
 */
static uint8_t tp_read_xy2(uint16_t *x, uint16_t *y)
{
    uint16_t x1, y1;
    uint16_t x2, y2;

    tp_read_xy(&x1, &y1);   /* 读取第一次数据 */
    tp_read_xy(&x2, &y2);   /* 读取第二次数据 */

    /* 前后两次采样在+-TP_ERR_RANGE内 */
    if (((x2 <= x1 && x1 < x2 + TP_ERR_RANGE) || (x1 <= x2 && x2 < x1 + TP_ERR_RANGE)) &&
            ((y2 <= y1 && y1 < y2 + TP_ERR_RANGE) || (y1 <= y2 && y2 < y1 + TP_ERR_RANGE)))
    {
        *x = (x1 + x2) / 2;
        *y = (y1 + y2) / 2;
        return 1;
    }

    return 0;
}

/******************************************************************************************/
/* 与LCD部分有关的函数, 用来校准用的 */

/**
 * @brief       画一个校准用的触摸点(十字架)
 * @param       x,y   : 坐标
 * @param       color : 颜色
 * @retval      无
 */
static void tp_draw_touch_point(uint16_t x, uint16_t y, uint16_t color)
{
    lcd_draw_line(x - 12, y, x + 13, y, color); /* 横线 */
    lcd_draw_line(x, y - 12, x, y + 13, color); /* 竖线 */
    lcd_draw_point(x + 1, y + 1, color);
    lcd_draw_point(x - 1, y + 1, color);
    lcd_draw_point(x + 1, y - 1, color);
    lcd_draw_point(x - 1, y - 1, color);
    lcd_draw_circle(x, y, 6, color);            /* 画中心圈 */
}

/**
 * @brief       画一个大点(2*2的点)
 * @param       x,y   : 坐标
 * @param       color : 颜色
 * @retval      无
 */
void tp_draw_big_point(uint16_t x, uint16_t y, uint16_t color)
{
    lcd_draw_point(x, y, color);       /* 中心点 */
    lcd_draw_point(x + 1, y, color);
    lcd_draw_point(x, y + 1, color);
    lcd_draw_point(x + 1, y + 1, color);
}

/******************************************************************************************/

/**
 * @brief       触摸按键扫描
 * @param       mode: 坐标模式
 *   @arg       0, 屏幕坐标;
 *   @arg       1, 物理坐标(校准等特殊场合用)
 *
 * @retval      0, 触屏无触摸; 1, 触屏有触摸;
 */
uint8_t tp_scan(uint8_t mode)
{
    if (T_PEN == 0)     /* 有按键按下 */
    {
        if (mode)       /* 读取物理坐标, 无需转换 */
        {
            tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]);
        }
        else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]))     /* 读取屏幕坐标, 需要转换 */
        {
            /* 将X轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的X坐标值) */
            tp_dev.x[0] = (signed short)(tp_dev.x[0] - tp_dev.xc) / tp_dev.xfac + lcddev.width / 2;

            /* 将Y轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的Y坐标值) */
            tp_dev.y[0] = (signed short)(tp_dev.y[0] - tp_dev.yc) / tp_dev.yfac + lcddev.height / 2;
        }

        if ((tp_dev.sta & TP_PRES_DOWN) == 0)   /* 之前没有被按下 */
        {
            tp_dev.sta = TP_PRES_DOWN | TP_CATH_PRES;   /* 按键按下 */
            tp_dev.x[CT_MAX_TOUCH - 1] = tp_dev.x[0];   /* 记录第一次按下时的坐标 */
            tp_dev.y[CT_MAX_TOUCH - 1] = tp_dev.y[0];
        }
    }
    else
    {
        if (tp_dev.sta & TP_PRES_DOWN)      /* 之前是被按下的 */
        {
            tp_dev.sta &= ~TP_PRES_DOWN;    /* 标记按键松开 */
        }
        else     /* 之前就没有被按下 */
        {
            tp_dev.x[CT_MAX_TOUCH - 1] = 0;
            tp_dev.y[CT_MAX_TOUCH - 1] = 0;
            tp_dev.x[0] = 0xffff;
            tp_dev.y[0] = 0xffff;
        }
    }

    return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */
}

/* TP_SAVE_ADDR_BASE定义触摸屏校准参数保存在EEPROM里面的位置(起始地址)
 * 占用空间 : 13字节.
 */
#define TP_SAVE_ADDR_BASE   40

/**
 * @brief       保存校准参数
 *   @note      参数保存在EEPROM芯片里面(24C02),起始地址为TP_SAVE_ADDR_BASE.
 *              占用大小为13字节
 * @param       无
 * @retval      无
 */
void tp_save_adjust_data(void)
{
    uint8_t *p = (uint8_t *)&tp_dev.xfac;   /* 指向首地址 */

    /* p指向tp_dev.xfac的地址, p+4则是tp_dev.yfac的地址
     * p+8则是tp_dev.xoff的地址,p+10,则是tp_dev.yoff的地址
     * 总共占用12个字节(4个参数)
     * p+12用于存放标记电阻触摸屏是否校准的数据(0X0A)
     * 往p[12]写入0X0A. 标记已经校准过.
     */
    at24cxx_write(TP_SAVE_ADDR_BASE, p, 12);                /* 保存12个字节数据(xfac,yfac,xc,yc) */
    at24cxx_write_one_byte(TP_SAVE_ADDR_BASE + 12, 0X0A);   /* 保存校准值 */
}

/**
 * @brief       获取保存在EEPROM里面的校准值
 * @param       无
 * @retval      0,获取失败,要重新校准
 *              1,成功获取数据
 */
uint8_t tp_get_adjust_data(void)
{
    uint8_t *p = (uint8_t *)&tp_dev.xfac;
    uint8_t temp = 0;

    /* 由于我们是直接指向tp_dev.xfac地址进行保存的, 读取的时候,将读取出来的数据
     * 写入指向tp_dev.xfac的首地址, 就可以还原写入进去的值, 而不需要理会具体的数
     * 据类型. 此方法适用于各种数据(包括结构体)的保存/读取(包括结构体).
     */
    at24cxx_read(TP_SAVE_ADDR_BASE, p, 12);                 /* 读取12字节数据 */
    temp = at24cxx_read_one_byte(TP_SAVE_ADDR_BASE + 12);   /* 读取校准状态标记 */

    if (temp == 0X0A)
    {
        return 1;
    }

    return 0;
}

/* 提示字符串 */
char *const TP_REMIND_MSG_TBL = "Please use the stylus click the cross on the screen.The cross will always move until the screen adjustment is completed.";

/**
 * @brief       提示校准结果(各个参数)
 * @param       xy[5][2]: 5个物理坐标值
 * @param       px,py   : x,y方向的比例因子(约接近1越好)
 * @retval      无
 */
static void tp_adjust_info_show(uint16_t xy[5][2], double px, double py)
{
    uint8_t i;
    char sbuf[20];

    for (i = 0; i < 5; i++)   /* 显示5个物理坐标值 */
    {
        sprintf(sbuf, "x%d:%d", i + 1, xy[i][0]);
        lcd_show_string(40, 160 + (i * 20), lcddev.width, lcddev.height, 16, sbuf, RED);
        sprintf(sbuf, "y%d:%d", i + 1, xy[i][1]);
        lcd_show_string(40 + 80, 160 + (i * 20), lcddev.width, lcddev.height, 16, sbuf, RED);
    }

    /* 显示X/Y方向的比例因子 */
    lcd_fill(40, 160 + (i * 20), lcddev.width - 1, 16, WHITE);  /* 清除之前的px,py显示 */
    sprintf(sbuf, "px:%0.2f", px);
    sbuf[7] = 0; /* 添加结束符 */
    lcd_show_string(40, 160 + (i * 20), lcddev.width, lcddev.height, 16, sbuf, RED);
    sprintf(sbuf, "py:%0.2f", py);
    sbuf[7] = 0; /* 添加结束符 */
    lcd_show_string(40 + 80, 160 + (i * 20), lcddev.width, lcddev.height, 16, sbuf, RED);
}

/**
 * @brief       触摸屏校准代码
 *   @note      使用五点校准法(具体原理请百度)
 *              本函数得到x轴/y轴比例因子xfac/yfac及物理中心坐标值(xc,yc)等4个参数
 *              我们规定: 物理坐标即AD采集到的坐标值,范围是0~4095.
 *                        逻辑坐标即LCD屏幕的坐标, 范围为LCD屏幕的分辨率.
 *
 * @param       无
 * @retval      无
 */
void tp_adjust(void)
{
    uint16_t pxy[5][2];     /* 物理坐标缓存值 */
    uint8_t  cnt = 0;
    short s1, s2, s3, s4;   /* 4个点的坐标差值 */
    double px, py;          /* X,Y轴物理坐标比例,用于判定是否校准成功 */
    uint16_t outtime = 0;
    cnt = 0;

    lcd_clear(WHITE);       /* 清屏 */
    lcd_show_string(40, 40, 160, 100, 16, TP_REMIND_MSG_TBL, RED); /* 显示提示信息 */
    tp_draw_touch_point(20, 20, RED);   /* 画点1 */
    tp_dev.sta = 0;         /* 消除触发信号 */

    while (1)               /* 如果连续10秒钟没有按下,则自动退出 */
    {
        tp_dev.scan(1);     /* 扫描物理坐标 */

        if ((tp_dev.sta & 0xc000) == TP_CATH_PRES)   /* 按键按下了一次(此时按键松开了.) */
        {
            outtime = 0;
            tp_dev.sta &= ~TP_CATH_PRES;    /* 标记按键已经被处理过了. */

            pxy[cnt][0] = tp_dev.x[0];      /* 保存X物理坐标 */
            pxy[cnt][1] = tp_dev.y[0];      /* 保存Y物理坐标 */
            cnt++;

            switch (cnt)
            {
                case 1:
                    tp_draw_touch_point(20, 20, WHITE);                 /* 清除点1 */
                    tp_draw_touch_point(lcddev.width - 20, 20, RED);    /* 画点2 */
                    break;

                case 2:
                    tp_draw_touch_point(lcddev.width - 20, 20, WHITE);  /* 清除点2 */
                    tp_draw_touch_point(20, lcddev.height - 20, RED);   /* 画点3 */
                    break;

                case 3:
                    tp_draw_touch_point(20, lcddev.height - 20, WHITE); /* 清除点3 */
                    tp_draw_touch_point(lcddev.width - 20, lcddev.height - 20, RED);    /* 画点4 */
                    break;

                case 4:
                    lcd_clear(WHITE);   /* 画第五个点了, 直接清屏 */
                    tp_draw_touch_point(lcddev.width / 2, lcddev.height / 2, RED);  /* 画点5 */
                    break;

                case 5:     /* 全部5个点已经得到 */
                    s1 = pxy[1][0] - pxy[0][0]; /* 第2个点和第1个点的X轴物理坐标差值(AD值) */
                    s3 = pxy[3][0] - pxy[2][0]; /* 第4个点和第3个点的X轴物理坐标差值(AD值) */
                    s2 = pxy[3][1] - pxy[1][1]; /* 第4个点和第2个点的Y轴物理坐标差值(AD值) */
                    s4 = pxy[2][1] - pxy[0][1]; /* 第3个点和第1个点的Y轴物理坐标差值(AD值) */

                    px = (double)s1 / s3;       /* X轴比例因子 */
                    py = (double)s2 / s4;       /* Y轴比例因子 */

                    if (px < 0)px = -px;        /* 负数改正数 */
                    if (py < 0)py = -py;        /* 负数改正数 */

                    if (px < 0.95 || px > 1.05 || py < 0.95 || py > 1.05 ||     /* 比例不合格 */
                            abs(s1) > 4095 || abs(s2) > 4095 || abs(s3) > 4095 || abs(s4) > 4095 || /* 差值不合格, 大于坐标范围 */
                            abs(s1) == 0 || abs(s2) == 0 || abs(s3) == 0 || abs(s4) == 0            /* 差值不合格, 等于0 */
                       )
                    {
                        cnt = 0;
                        tp_draw_touch_point(lcddev.width / 2, lcddev.height / 2, WHITE); /* 清除点5 */
                        tp_draw_touch_point(20, 20, RED);   /* 重新画点1 */
                        tp_adjust_info_show(pxy, px, py);   /* 显示当前信息,方便找问题 */
                        continue;
                    }

                    tp_dev.xfac = (float)(s1 + s3) / (2 * (lcddev.width - 40));
                    tp_dev.yfac = (float)(s2 + s4) / (2 * (lcddev.height - 40));

                    tp_dev.xc = pxy[4][0];      /* X轴,物理中心坐标 */
                    tp_dev.yc = pxy[4][1];      /* Y轴,物理中心坐标 */

                    lcd_clear(WHITE);   /* 清屏 */
                    lcd_show_string(35, 110, lcddev.width, lcddev.height, 16, "Touch Screen Adjust OK!", BLUE); /* 校正完成 */
                    delay_ms(1000);
                    tp_save_adjust_data();

                    lcd_clear(WHITE);/* 清屏 */
                    return;/* 校正完成 */
            }
        }

        delay_ms(10);
        outtime++;

        if (outtime > 1000)
        {
            tp_get_adjust_data();
            break;
        }
    }

}



















/**
 * @brief       触摸屏初始化
 * @param       无
 * @retval      0,没有进行校准
 *              1,进行过校准
 */
uint8_t tp_init(void)
{
        tp_dev.touchtype = 1;                   /* 默认设置(电阻屏 & 竖屏) */
    

  
        rcu_periph_clock_enable(T_PEN_GPIO_CLK);      /* 使能T_PEN脚时钟 */
        rcu_periph_clock_enable(T_CS_GPIO_CLK);       /* 使能T_CS脚时钟 */
        rcu_periph_clock_enable(T_MISO_GPIO_CLK);     /* 使能T_MISO脚时钟 */
        rcu_periph_clock_enable(T_MOSI_GPIO_CLK);     /* 使能T_MOSI脚时钟 */
        rcu_periph_clock_enable(T_CLK_GPIO_CLK);      /* 使能T_CLK脚时钟 */
      
        gpio_mode_set(T_PEN_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, T_PEN_GPIO_PIN);  /* T_PEN引脚模式设置,上拉输入 */
        gpio_mode_set(T_MISO_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, T_MISO_GPIO_PIN);  /* T_MISO引脚模式设置,上拉输入 */
      
        /* 设置T_CLK 引脚推挽输出模式 */
        gpio_mode_set(T_CLK_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, T_CLK_GPIO_PIN);
        gpio_output_options_set(T_CLK_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, T_CLK_GPIO_PIN);
        /* 设置T_CS引脚 推挽输出模式 */
        gpio_mode_set(T_CS_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, T_CS_GPIO_PIN);
        gpio_output_options_set(T_CS_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, T_CS_GPIO_PIN);
        /* 设置T_MOSI引脚 推挽输出模式 */
        gpio_mode_set(T_MOSI_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, T_MOSI_GPIO_PIN);
        gpio_output_options_set(T_MOSI_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, T_MOSI_GPIO_PIN);

        tp_read_xy(&tp_dev.x[0], &tp_dev.y[0]); /* 第一次读取初始化 */
        at24cxx_init();         /* 初始化24CXX */

        if (tp_get_adjust_data())
        {
            return 0;           /* 已经校准 */
        }
        else                    /* 未校准? */
        {
            lcd_clear(WHITE);   /* 清屏 */
            tp_adjust();        /* 屏幕校准 */
            tp_save_adjust_data();
        }

        tp_get_adjust_data();
    

    return 1;
}

 

 

#include "gd32h7xx.h"
#include "systick.h"
#include <stdio.h>
#include "gd32h759i_eval.h"
#include "gd32h759i_lcd_eval.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/TIMER/timer.h"
#include "./BSP/24CXX/24cxx.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/TOUCH/touch.h"

const uint8_t g_text_buf[] = {"gd32 IIC TEST"}; /* 要写入到 24c02 的字符串数组 */
#define TEXT_SIZE sizeof(g_text_buf) /* TEXT 字符串长度 */

/**
 * @brief       清空屏幕并在右上角显示"RST"
 * @param       无
 * @retval      无
 */
void load_draw_dialog(void)
{
    lcd_clear(WHITE);                                                /* 清屏 */
    lcd_show_string(lcddev.width - 24, 0, 200, 16, 16, "RST", BLUE); /* 显示清屏区域 */
}


/*!
    \brief      toggle the led every 500ms
    \param[in]  none
    \param[out] none
    \retval     none
*/
void led_spark(void)
{
    static __IO uint32_t timingdelaylocal = 0U;

    if(timingdelaylocal) {

        if(timingdelaylocal < 500U) {
            gd_eval_led_on(LED1);
        } else {
            gd_eval_led_off(LED1);
        }

        timingdelaylocal--;
    } else {
        timingdelaylocal = 1000U;
    }
}

/*!
    \brief      enable the CPU cache
    \param[in]  none
    \param[out] none
    \retval     none
*/
void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}



/**
 * @brief       电阻触摸屏测试函数
 * @param       无
 * @retval      无
 */
void rtp_test(void)
{
    uint8_t key;
    uint8_t i = 0;
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
    while (1)
    {
       
        tp_dev.scan(0);

			if (tp_dev.sta & TP_PRES_DOWN)  /* 触摸屏被按下 */
			{
					if (tp_dev.x[0] < lcddev.width && tp_dev.y[0] < lcddev.height)
					{
							if (tp_dev.x[0] > (lcddev.width - 24) && tp_dev.y[0] < 16)
							{
									load_draw_dialog(); /* 清除 */
							}
							else 
							{
								  printf("\r\nx %d  y %d", tp_dev.x[0], tp_dev.y[0]);
									tp_draw_big_point(tp_dev.x[0], tp_dev.y[0], RED);   /* 画点 */
							}
					}
			}
			else 
			{
					delay_ms(10);       /* 没有按键按下的时候 */
			}
      if(RESET == gd_eval_key_scan(KEY_WAKEUP))
			{
			      lcd_clear(WHITE);   /* 清屏 */
            tp_adjust();        /* 屏幕校准 */
            tp_save_adjust_data();
            load_draw_dialog();
			}
    }
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
	  uint8_t x = 0;
	  uint8_t datatemp[TEXT_SIZE];
    /* enable the CPU cache */
    cache_enable();
    /* configure systick */
    //systick_config();
	  delay_init(600);
    /* initilize the LEDs, USART and key */
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    gd_eval_com_init(EVAL_COM);
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
	  gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);
	  at24cxx_init();
	  timerx_int_init(10 - 1, 30000 - 1);     
    printf("\r\nCK_SYS is %d", rcu_clock_freq_get(CK_SYS));
	  lcd_init();
	  tp_dev.init();                      /* 触摸屏初始化 */
    
//	  while(1)
//		{
//		   tp_dev.scan(1);
//			 printf("\r\nx %d  y %d", tp_dev.x[0], tp_dev.y[0]);
//		
//		}
	  while (at24cxx_check()) 
		{
		   gd_eval_led_on(LED1);
		   delay_ms(500);lcd_init();
		   gd_eval_led_off(LED1);
		   delay_ms(500);
		}
		
		
     lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "TOUCH TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);

    if (tp_dev.touchtype != 0XFF)
    {
        lcd_show_string(30, 110, 200, 16, 16, "Press KEY0 to Adjust", RED); /* 电阻屏才显示 */
    }

    delay_ms(1500);
    load_draw_dialog();

    
    rtp_test(); /* 电阻屏测试 */
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM, USART_FLAG_TBE));

    return ch;
}

 

#include "gd32h7xx.h"
#include "systick.h"
#include <stdio.h>
#include "gd32h759i_eval.h"
#include "gd32h759i_lcd_eval.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/TIMER/timer.h"
#include "./BSP/24CXX/24cxx.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/TOUCH/touch.h"

const uint8_t g_text_buf[] = {"gd32 IIC TEST"}; /* 要写入到 24c02 的字符串数组 */
#define TEXT_SIZE sizeof(g_text_buf) /* TEXT 字符串长度 */

/**
 * @brief       清空屏幕并在右上角显示"RST"
 * @param       无
 * @retval      无
 */
void load_draw_dialog(void)
{
    lcd_clear(WHITE);                                                /* 清屏 */
    lcd_show_string(lcddev.width - 24, 0, 200, 16, 16, "RST", BLUE); /* 显示清屏区域 */
}


/*!
    \brief      toggle the led every 500ms
    \param[in]  none
    \param[out] none
    \retval     none
*/
void led_spark(void)
{
    static __IO uint32_t timingdelaylocal = 0U;

    if(timingdelaylocal) {

        if(timingdelaylocal < 500U) {
            gd_eval_led_on(LED1);
        } else {
            gd_eval_led_off(LED1);
        }

        timingdelaylocal--;
    } else {
        timingdelaylocal = 1000U;
    }
}

/*!
    \brief      enable the CPU cache
    \param[in]  none
    \param[out] none
    \retval     none
*/
void cache_enable(void)
{
    /* enable i-cache */
    SCB_EnableICache();

    /* enable d-cache */
    SCB_EnableDCache();
}



/**
 * @brief       电阻触摸屏测试函数
 * @param       无
 * @retval      无
 */
void rtp_test(void)
{
    uint8_t key;
    uint8_t i = 0;
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
    while (1)
    {
       
        tp_dev.scan(0);

			if (tp_dev.sta & TP_PRES_DOWN)  /* 触摸屏被按下 */
			{
					if (tp_dev.x[0] < lcddev.width && tp_dev.y[0] < lcddev.height)
					{
							if (tp_dev.x[0] > (lcddev.width - 24) && tp_dev.y[0] < 16)
							{
									load_draw_dialog(); /* 清除 */
							}
							else 
							{
								  printf("\r\nx %d  y %d", tp_dev.x[0], tp_dev.y[0]);
									tp_draw_big_point(tp_dev.x[0], tp_dev.y[0], RED);   /* 画点 */
							}
					}
			}
			else 
			{
					delay_ms(10);       /* 没有按键按下的时候 */
			}
      if(RESET == gd_eval_key_scan(KEY_WAKEUP))
			{
			      lcd_clear(WHITE);   /* 清屏 */
            tp_adjust();        /* 屏幕校准 */
            tp_save_adjust_data();
            load_draw_dialog();
			}
    }
}

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
	  uint8_t x = 0;
	  uint8_t datatemp[TEXT_SIZE];
    /* enable the CPU cache */
    cache_enable();
    /* configure systick */
    //systick_config();
	  delay_init(600);
    /* initilize the LEDs, USART and key */
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    gd_eval_com_init(EVAL_COM);
    gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
	  gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);
	  at24cxx_init();
	  timerx_int_init(10 - 1, 30000 - 1);     
    printf("\r\nCK_SYS is %d", rcu_clock_freq_get(CK_SYS));
	  lcd_init();
	  tp_dev.init();                      /* 触摸屏初始化 */
    
//	  while(1)
//		{
//		   tp_dev.scan(1);
//			 printf("\r\nx %d  y %d", tp_dev.x[0], tp_dev.y[0]);
//		
//		}
	  while (at24cxx_check()) 
		{
		   gd_eval_led_on(LED1);
		   delay_ms(500);lcd_init();
		   gd_eval_led_off(LED1);
		   delay_ms(500);
		}
		
		
     lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "TOUCH TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);

    if (tp_dev.touchtype != 0XFF)
    {
        lcd_show_string(30, 110, 200, 16, 16, "Press KEY0 to Adjust", RED); /* 电阻屏才显示 */
    }

    delay_ms(1500);
    load_draw_dialog();

    
    rtp_test(); /* 电阻屏测试 */
}

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM, (uint8_t)ch);
    while(RESET == usart_flag_get(EVAL_COM, USART_FLAG_TBE));

    return ch;
}

 

实验现象

 

 

 

   GD32H7_EVAL_ATK_TOUCH.zip (14.05 MB, 下载次数: 1)

最新回复

good nice  详情 回复 发表于 2024-6-27 20:00
点赞 关注
 
 

回复
举报

7628

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

谢谢分享,期待后续!

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
good nice
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表