【目的】测试触摸屏
【驱动模块】
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);
}
}
实验现象: