1439|10

7044

帖子

11

TA的资源

版主

楼主
 

【 HC32F4A0开发板】触摸测试 [复制链接]

 

【目的】测试触摸屏

【驱动模块】

1、显示屏驱动。负责驱动nt35510屏。

2、触摸屏驱动。负责检测是否有触摸事件发生,如果有发生,负责提供触摸状态以及触摸点的坐标。

3、定时器驱动。实现每1ms的中断回调事件,每50ms检测一次触摸检测。

【程序实现】

1、nt35510已经在这编帖子中实现这里不再描述【 HC32F4A0开发板】超级简单的NT35510 LCD——HELLO WORLD 

2、触摸屏驱动

在官方的:\HC32F4A0_DDL_Rev2.1.0\drivers\bsp\ev_hc32f4a0_lqfp176\ev_hc32f4a0_lqfp176_gt9xx.c下面已经写好了触摸屏的驱动。

同时在M:\HC32F4A0_DDL_Rev2.1.1\projects\ev_hc32f4a0_lqfp176\examples\exmc\exmc_smc_lcd_nt35510这个实例里,已对触摸屏主要功能函数进行了封装我,这里为了以后的模块化管理,提出来用单独的touch.c进行一重构。代码如下:

#include "touch.h"

stc_touchpad_data_t touchdat;

/**
 * [url=home.php?mod=space&uid=159083]@brief[/url] Return true is the touchpad is pressed
 * @param  None
 * @retval Press state
 */
static bool TOUCHPAD_IsPressed(void)
{
    uint8_t u8Tmp;
    uint8_t u8Status;
    bool bPressed = false;

    BSP_GT9XX_REG_Read(GT9XX_TOUCH_STATUS, &u8Status, 1UL);
    if ((u8Status & 0x80U) != 0U) {
        u8Tmp = 0U;
        BSP_GT9XX_REG_Write(GT9XX_TOUCH_STATUS, &u8Tmp, 1U);

        if ((0U < (u8Status & 0x0FU)) && ((u8Status & 0x0FU) < 6U)) {
            bPressed = true;
        }
    }

    return bPressed;
}

/**
 * @brief  Get touch data.
 * @param  [out] pstcData               Pointer to a [url=home.php?mod=space&uid=1064992]@ref[/url] stc_touchpad_data_t structure.
 * @retval None
 */
 void TOUCHPAD_Read(stc_touchpad_data_t *pstcData)
{
    static uint16_t u16LastX = 0U;
    static uint16_t u16LastY = 0U;

    /*Save the pressed coordinates and the state*/
    if (TOUCHPAD_IsPressed()) {
        BSP_GT9XX_GetXY(GT9XX_POINT1, &u16LastX, &u16LastY);
        pstcData->enPointPress = SET;
    } else {
        pstcData->enPointPress = RESET;
    }

    /*Set the last pressed coordinates*/
    pstcData->stcPoint.u16X = u16LastX;
    pstcData->stcPoint.u16Y = u16LastY;
}

/**
 * @brief  Check if a point is on an window
 * @param  [in] pstcWin                 Pointer to a @ref stc_touchpad_window_t structure.
 * @param  [in] pstcPoint               Pointer to a @ref stc_touchpad_point_t structure.
 * @retval bool:
 *           - true:                    The point is in the area.
 *           - false:                   The point is out the area.
 */
bool TOUCHPAD_IsPointOn(const stc_touchpad_window_t *pstcWin, const stc_touchpad_point_t *pstcPoint)
{
    bool bIsPointOnWin = false;

    if((pstcPoint->u16X >= pstcWin->u16X1 && pstcPoint->u16X <= pstcWin->u16X2) && \
       (pstcPoint->u16Y >= pstcWin->u16Y1 && pstcPoint->u16Y <= pstcWin->u16Y2)) {
        bIsPointOnWin = true;
    }

    return bIsPointOnWin;
}

其实中对外的函数是 void TOUCHPAD_Read(stc_touchpad_data_t *pstcData),执行它后,会更新触摸状态,如果为SET,则表示当前有触摸事件发生。

3、timer0驱动。这个函数我根据示例M:\HC32F4A0_DDL_Rev2.1.0\projects\ev_hc32f4a0_lqfp176\examples\timer0\timer0_basetimer以及@TL-LED的帖子进行了封装,主要是产生1ms的中断事件,代码如下:

#include "timer0.h"
#include "hc32_ll_tmr0.h"
#include "ev_hc32f4a0_lqfp176_tca9539.h"
#include "touch.h"

/* TMR0 unit and channel definition */
/* TMR0 unit and channel definition */
#define TMR0_UNIT                       (CM_TMR0_1)
#define TMR0_CLK                        (FCG2_PERIPH_TMR0_1)
#define TMR0_CH                         (TMR0_CH_B)
#define TMR0_TRIG_CH                    (AOS_TMR0)
#define TMR0_CH_INT                     (TMR0_INT_CMP_B)
#define TMR0_CH_FLAG                    (TMR0_FLAG_CMP_B)
#define TMR0_INT_SRC                    (INT_SRC_TMR0_1_CMP_B)
#define TMR0_IRQn                       (INT006_IRQn)
/* Period = 1 / (Clock freq / div) * (Compare value + 1) = 500ms */
#define TMR0_CMP_VALUE                  (XTAL32_VALUE / 16000U / 2U - 1U)

extern stc_touchpad_data_t touchdat;
static uint32_t t0_cnt=0;
static void TMR0_CompareIrqCallback(void)
{	
		t0_cnt++;
		if(t0_cnt>50)
		{
			t0_cnt=0;
			BSP_LED_Toggle(LED_BLUE);
			TOUCHPAD_Read(&touchdat);
		}
    
    TMR0_ClearStatus(TMR0_UNIT, TMR0_CH_FLAG);
}



void init_timer0(void)
{
    stc_tmr0_init_t stcTmr0Init;
    stc_irq_signin_config_t stcIrqSignConfig;

    /* Enable timer0 and AOS clock */
    FCG_Fcg2PeriphClockCmd(TMR0_CLK, ENABLE);
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);

    /* TIMER0 configuration */
    (void)TMR0_StructInit(&stcTmr0Init);
    stcTmr0Init.u32ClockSrc     = TMR0_CLK_SRC_INTERN_CLK;
    stcTmr0Init.u32ClockDiv     = TMR0_CLK_DIV8;
    stcTmr0Init.u32Func         = TMR0_FUNC_CMP;
    stcTmr0Init.u16CompareValue = 15000;
    (void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    TMR0_HWStopCondCmd(TMR0_UNIT, TMR0_CH, ENABLE);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    TMR0_IntCmd(TMR0_UNIT, TMR0_CH_INT, ENABLE);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);

    /* Interrupt configuration */
    stcIrqSignConfig.enIntSrc    = TMR0_INT_SRC;
    stcIrqSignConfig.enIRQn      = TMR0_IRQn;
    stcIrqSignConfig.pfnCallback = &TMR0_CompareIrqCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
		
    TMR0_Start(TMR0_UNIT, TMR0_CH);	
}

最后在主函数中加入对各个模块的初始化,然后在fo循环里检测触摸事件,如果有则显示屏上面。

int32_t main(void)
{
		uint8_t show_str[40] = {0}; 
    /* Register write enable for some required peripherals. */
    LL_PERIPH_WE(LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_GPIO | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM);
    /* BSP Clock initialize */
    BSP_CLK_Init();

    /* Expand IO init */
    BSP_IO_Init();
    /* BSP LED initialize */
    BSP_LED_Init();
		
    /* Printf init */
    DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_Preinit);
    /* Matrix KEY row init */
    KEYSCAN_ROW0_Init();
    KEYSCAN_ROW1_Init();
    KEYSCAN_ROW2_Init();
    /* Matrix KEY column init */
    KEYSCAN_COL_Init();
    /* Clear all KEYIN interrupt flag before enable */
    EXTINT_ClearExtIntStatus(KEYSCAN_ROW0_EXTINT);
    EXTINT_ClearExtIntStatus(KEYSCAN_ROW1_EXTINT);
    EXTINT_ClearExtIntStatus(KEYSCAN_ROW2_EXTINT);
    /* KEYSCAN enable */
    KEYSCAN_Cmd(ENABLE);
		BSP_LCD_IO_Init();

    /* Initialize LCD touch pad */
    BSP_GT9XX_Init();

    /* HW Reset LCD */
    BSP_LCD_RSTCmd(EIO_PIN_RESET); /* RST# to low */
    DDL_DelayMS(50UL);
    BSP_LCD_RSTCmd(EIO_PIN_SET);  /* RST# to high */
    DDL_DelayMS(50UL);

    /* Initialize NT35510 LCD */
    BSP_NT35510_Init();

    /* Clear LCD screen */
    BSP_NT35510_Clear(LCD_COLOR_WHITE);

    /* Turn on LCD backlight */
    BSP_LCD_BKLCmd(EIO_PIN_SET);

    /* Set LCD cursor */
    BSP_NT35510_SetCursor(0U, 0U);

		init_timer0();
    /* Register write protected for some required peripherals. */
    LL_PERIPH_WP(LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_GPIO | LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM);
		
    /* Add your code here */
    for (;;) {
      
			if (touchdat.enPointPress == SET)
			{
				sprintf(show_str,"Prcess: x: %d, y: %d",touchdat.stcPoint.u16X,touchdat.stcPoint.u16Y);
				BSP_NT35510__ShowString(10,48, 400,48, 32, show_str);
				DDL_Printf("x: %d, y: %d \r\n",touchdat.stcPoint.u16X,touchdat.stcPoint.u16Y );
			}
			
			DDL_DelayMS(50UL);
    }
}

实验现象:

 

 

最新回复

有道理学到啦~  详情 回复 发表于 2023-3-10 07:35
点赞 关注
 
 

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

有触摸屏驱动代码省事多了

点评

对的,就是屏线有点多,想要玩触摸,芯片资源得高呀。  详情 回复 发表于 2023-3-2 07:55
 
 
 

回复

7044

帖子

11

TA的资源

版主

板凳
 
Jacktang 发表于 2023-3-2 07:31 有触摸屏驱动代码省事多了

对的,就是屏线有点多,想要玩触摸,芯片资源得高呀。

 
 
 

回复

7044

帖子

11

TA的资源

版主

4
 

触摸测试

添加一下视频,昨天附件忘上传了。

 
 
 

回复

5263

帖子

239

TA的资源

管理员

5
 

相关测试代码,记得打包上传一下哈

加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

4942

帖子

12

TA的资源

版主

6
 

支持多点触控不~

 
 
 

回复

4942

帖子

12

TA的资源

版主

7
 

每50ms检测一次 ,一次多长时间判定为触控了呢~

点评

这个只是示例,在lvgl中,可以设置10-30ms采样一次,如果有特别快的响应速度,需要跑操作系统,单独设置一个任务来处理。当然如果还需要快,屏的响应速度也不一定跟得上。  详情 回复 发表于 2023-3-9 16:37
 
 
 

回复

7044

帖子

11

TA的资源

版主

8
 
吾妻思萌 发表于 2023-3-9 16:10 每50ms检测一次 ,一次多长时间判定为触控了呢~

这个只是示例,在lvgl中,可以设置10-30ms采样一次,如果有特别快的响应速度,需要跑操作系统,单独设置一个任务来处理。当然如果还需要快,屏的响应速度也不一定跟得上。

 
 
 

回复

7044

帖子

11

TA的资源

版主

9
 

如果显示帧率只有10帧,太快的触摸采样,也没有实际意义,到了工程上需要配合来确定采样时间。

点评

有道理学到啦~  详情 回复 发表于 2023-3-10 07:35
 
 
 

回复

4942

帖子

12

TA的资源

版主

10
 
如果显示帧率只有10帧,太快的触摸采样,也没有实际意义,到了工程上需要配合来确定采样时间。

有道理学到啦~

点评

版主大佬,感谢支持,好久没见你见了老丈人的后续了,是不是准备发喜糖了呀。  详情 回复 发表于 2023-3-10 09:02
 
 
 

回复

7044

帖子

11

TA的资源

版主

11
 

版主大佬,感谢支持,好久没见你见了老丈人的后续了,是不是准备发喜糖了呀。

 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表