imx6ull , 4.3寸800*480屏幕,触摸芯片型号 gt9147,显示触摸点的坐标数据

前半部分是显示效果,后半部分是代码。

gt9147_init() 初始化,打印的数据 ->

屏幕显示的数据 ->

历程源码中的 bsp_gt9147.c 文件 有几处需要修改,4.3寸屏幕 才能显示数据。

bsp_gt9147.h 文件不用修改。

复制代码
/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_gt9147.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 触摸屏驱动文件,触摸芯片为GT9147。
其他	   : 无
论坛 	   : www.openedv.com
日志	   : 初版V1.0 2020/1/15 左忠凯创建
***************************************************************/
#include "bsp_gt9147.h"
#include "bsp_i2c.h"
#include "bsp_int.h"
#include "bsp_delay.h"
#include "stdio.h"
#include "bsp_lcd.h"
#include "bsp_lcdapi.h"

/*
 * GT9147配置参数表
 * 第一个字节为版本号(0X61),必须保证新的版本号大于等于GT9147内部
 * flash原有版本号,才会更新配置.
 */
u8 GT9147_CFG_TBL[]=
{ 
	0x41,0xe0,0x01,0x10,0x01,0x05,0x0d,0x00,0x01,0x08,
	0x28,0x05,0x50,0x32,0x03,0x05,0x00,0x00,0xff,0xff,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x28,0x0a,
	0x17,0x15,0x31,0x0d,0x00,0x00,0x02,0x9b,0x03,0x25,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,
	0x00,0x0f,0x94,0x94,0xc5,0x02,0x07,0x00,0x00,0x04,
	0x8d,0x13,0x00,0x5c,0x1e,0x00,0x3c,0x30,0x00,0x29,
	0x4c,0x00,0x1e,0x78,0x00,0x1e,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0x00,0x00,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,
	0x18,0x1a,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0xff,0xff,0x00,0x02,0x04,0x05,0x06,0x08,0x0a,0x0c,
	0x0e,0x1d,0x1e,0x1f,0x20,0x22,0x24,0x28,0x29,0xff,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
	0xff,0xff,0xff,0xff,
};

struct gt9147_dev_struc gt9147_dev;
int gt_init_fail = 0;

/*
 * @description	: 初始化触摸屏,其实就是初始化GT9147
 * @param		: 无
 * @return 		: 无
 */
void gt9147_init(void)
{
    volatile unsigned char temp[7];	// 修改这里
  
	gpio_pin_config_t ctintpin_config;
	gpio_pin_config_t ctretpin_config;
	gt9147_dev.initfalg = GT9147_INIT_NOTFINISHED;
	int i;
	for( i = 0; i < 5; i++ )
	{	/* 避免编译器自动赋值 */
		gt9147_dev.x[i] = 0;
		gt9147_dev.y[i] = 0;
	}
	gt9147_dev.point_num = 0;
	/* 1、初始化IIC2 IO
     * I2C2_SCL -> UART5_TXD
     * I2C2_SDA -> UART5_RXD
     */
	IOMUXC_SetPinMux(IOMUXC_UART5_TX_DATA_I2C2_SCL,1);
	IOMUXC_SetPinMux(IOMUXC_UART5_RX_DATA_I2C2_SDA,1);

	/* 配置I2C2 IO属性	
	 *bit 16:0 HYS关闭
	 *bit [15:14]: 1 默认47K上拉
	 *bit [13]: 1 pull功能
	 *bit [12]: 1 pull/keeper使能 
	 *bit [11]: 0 关闭开路输出
	 *bit [7:6]: 10 速度100Mhz
	 *bit [5:3]: 110 驱动能力为R0/6
	 *bit [0]: 1 高转换率
	 */
	IOMUXC_SetPinConfig(IOMUXC_UART5_TX_DATA_I2C2_SCL, 0x70B0);
	IOMUXC_SetPinConfig(IOMUXC_UART5_RX_DATA_I2C2_SDA, 0X70B0);
	
	/* 2、初始化触摸屏中断IO和复位IO */
	IOMUXC_SetPinMux(IOMUXC_GPIO1_IO09_GPIO1_IO09,0);		/* 复用为GPIO1_IO9 */
	IOMUXC_SetPinMux(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0);/* 复用为GPIO5_IO9 */
	
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0x10B0);
	IOMUXC_SetPinConfig(IOMUXC_SNVS_SNVS_TAMPER9_GPIO5_IO09,0X10B0);

	/* 中断IO初始化 */
	ctintpin_config.direction = kGPIO_DigitalOutput;
	ctintpin_config.outputLogic = 1;
	ctintpin_config.interruptMode = kGPIO_NoIntmode;
	gpio_init(GPIO1, 9, &ctintpin_config);

	/* 复位IO初始化 */
    ctretpin_config.direction = kGPIO_DigitalOutput;	
    ctretpin_config.interruptMode = kGPIO_NoIntmode;	
    ctretpin_config.outputLogic = 1;					   
    gpio_init(GPIO5, 9, &ctretpin_config); 

	/* 3、初始化I2C */
	i2c_init(I2C2);	

	/* 4、初始化GT9147,要严格按照GT9147时序要求 */
	gpio_pinwrite(GPIO5, 9, 0);	/* 复位GT9147 */
	delayms(10);
	gpio_pinwrite(GPIO5, 9, 1); /* 停止复位GT9147 */ 
	delayms(10);
	gpio_pinwrite(GPIO1, 9, 0);	/* 拉低INT引脚 */
	delayms(100);

    gt9147_read_len(GT9147_ADDR, GT_PID_REG, 6, (unsigned char *)temp);/* 读取产品ID */
	temp[6] = temp[4];
    temp[4] = 0;
	printf("CTP ID:%s\r\n", temp);	    /* 打印ID */
	printf("Default Ver:%#x\r\n",((temp[5]<<8) | temp[6]));   /* 打印固件版本 */

	/* 重新设置中断IO,配置为中断功能 */
	IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO09_GPIO1_IO09,0x0080);
	ctintpin_config.direction = kGPIO_DigitalInput;
	ctintpin_config.outputLogic=0;
	if(temp[0] != 0x31)
	{
		temp[0]=gt9147_read_byte(GT9147_ADDR, 0x804D) & 0x3;     /* 获取中断模式 */
		printf("9xx\r\n");
	}	
	else temp[0]=gt9147_read_byte(GT9147_ADDR, 0x8056) & 0x3;
	switch(temp[0]) {
		case 0x0:
			printf("InterruptMode:IntRisingEdge\r\n");
			ctintpin_config.interruptMode = kGPIO_IntRisingEdge;
			break;
		case 0x1:
			printf("InterruptMode:IntFallingEdge\r\n");
			ctintpin_config.interruptMode = kGPIO_IntFallingEdge;
			break;
		case 0x2:
			printf("InterruptMode:IntLowLevel\r\n");
			ctintpin_config.interruptMode = kGPIO_IntLowLevel;
			break;
		case 0x3:
			printf("InterruptMode:IntHighLevel\r\n");
			ctintpin_config.interruptMode = kGPIO_IntHighLevel;
			break;
		default : printf("InterruptMode: Error\r\n");
			ctintpin_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
			break;
	}
	gpio_init(GPIO1, 9, &ctintpin_config);

	if(gt9147_write_byte(GT9147_ADDR, GT_CTRL_REG, 0x02))
	{
		gt_init_fail = 1;  //gt系列初始化失败
		goto done;
	}
	delayms(10);
	
	// 修改这里,使能中断之前,标记GT9147初始化完成
	gt9147_dev.initfalg = GT9147_INIT_FINISHED;	/* 标记GT9147初始化完成 */
	gt9147_dev.intflag = 0;

	gt9147_write_byte(GT9147_ADDR, GT_CTRL_REG, 0);	
	GIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);			/* 使能GIC中对应的中断 */
	system_register_irqhandler(GPIO1_Combined_0_15_IRQn, (system_irq_handler_t)gt9147_irqhandler, NULL);	/* 注册中断服务函数 */
	gpio_enableint(GPIO1, 9);								/* 使能GPIO1_IO09的中断功能 */		
    delayms(100);
	
done:
	delayms(10);
}

/*
 * @description			: GPIO1_IO9最终的中断处理函数
 * @param				: 无
 * @return 				: 无
 */
void gt9147_irqhandler(void)
{ 
	if(gt9147_dev.initfalg == GT9147_INIT_FINISHED) // 触摸屏初始化完成
	{
		gt9147_dev.intflag = 1;

		// 修改这里
		unsigned char touch_status = gt9147_read_byte(GT9147_ADDR, GT_GSTID_REG);
		if(touch_status & 0x80)	// 第7位为1 表示有 有效触摸数据,此时再读取触摸点的坐标
		{
			gt9147_read_tpcoord();	// 读取当前 所有触摸点的坐标

			/* 4.3寸屏幕,触摸芯片型号 gt9147,屏幕显示坐标数据 测试 */
			#if 1
			tftlcd_dev.forecolor = LCD_BLUE;
			lcd_shownum(50 + 72, 110, gt9147_dev.point_num , 1, 16);
			lcd_shownum(50 + 72, 130, gt9147_dev.x[0], 5, 16);
			lcd_shownum(50 + 72, 150, gt9147_dev.y[0], 5, 16);
			lcd_shownum(50 + 72, 170, gt9147_dev.x[1], 5, 16);
			lcd_shownum(50 + 72, 190, gt9147_dev.y[1], 5, 16);
			lcd_shownum(50 + 72, 210, gt9147_dev.x[2], 5, 16);
			lcd_shownum(50 + 72, 230, gt9147_dev.y[2], 5, 16);
			lcd_shownum(50 + 72, 250, gt9147_dev.x[3], 5, 16);
			lcd_shownum(50 + 72, 270, gt9147_dev.y[3], 5, 16);
			lcd_shownum(50 + 72, 290, gt9147_dev.x[4], 5, 16);
			lcd_shownum(50 + 72, 310, gt9147_dev.y[4], 5, 16);

			lcd_draw_big_point(gt9147_dev.x[0],gt9147_dev.y[0],LCD_BLACK);
			lcd_draw_big_point(gt9147_dev.x[1],gt9147_dev.y[1],LCD_BLUE);
			lcd_draw_big_point(gt9147_dev.x[2],gt9147_dev.y[2],LCD_RED);
			lcd_draw_big_point(gt9147_dev.x[3],gt9147_dev.y[3],LCD_GREEN);
			lcd_draw_big_point(gt9147_dev.x[4],gt9147_dev.y[4],LCD_YELLOW);
			#endif
		}
		else{

		}
	}
	gpio_clearintflags(GPIO1, 9); /* 清除中断标志位 */
}

/*
 * @description	: 向GT9147写入数据
 * @param - addr: 设备地址
 * @param - reg : 要写入的寄存器
 * @param - data: 要写入的数据
 * @return 		: 操作结果
 */
unsigned char gt9147_write_byte(unsigned char addr,unsigned int reg, unsigned char data)
{
    unsigned char status=0;
    unsigned char writedata=data;
    struct i2c_transfer masterXfer;
	
    /* 配置I2C xfer结构体 */
   	masterXfer.slaveAddress = addr; 			/* 设备地址 				*/
    masterXfer.direction = kI2C_Write;			/* 写入数据 				*/
    masterXfer.subaddress = reg;				/* 要写入的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = &writedata;				/* 要写入的数据 				*/
    masterXfer.dataSize = 1;  					/* 写入数据长度1个字节			*/

    if(i2c_master_transfer(I2C2, &masterXfer))
        status=1;
        
    return status;
}

/*
 * @description	: 从GT9147读取一个字节的数据
 * @param - addr: 设备地址
 * @param - reg : 要读取的寄存器
 * @return 		: 读取到的数据。
 */
unsigned char gt9147_read_byte(unsigned char addr,unsigned int reg)
{
	unsigned char val=0;
	
	struct i2c_transfer masterXfer;	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = &val;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = 1;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);

	return val;
}

/*
 * @description	: 从GT9147读取多个字节的数据
 * @param - addr: 设备地址
 * @param - reg : 要读取的开始寄存器地址
 * @param - len : 要读取的数据长度.
 * @param - buf : 读取到的数据缓冲区
 * @return 		: 无
 */
void gt9147_read_len(unsigned char addr,unsigned int reg,unsigned int len,unsigned char *buf)
{	
	struct i2c_transfer masterXfer;	
	
	masterXfer.slaveAddress = addr;				/* 设备地址 				*/
    masterXfer.direction = kI2C_Read;			/* 读取数据 				*/
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 			*/
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节 			*/
    masterXfer.data = buf;						/* 接收数据缓冲区 				*/
    masterXfer.dataSize = len;					/* 读取数据长度1个字节			*/
	i2c_master_transfer(I2C2, &masterXfer);
} 

/*
 * @description	: 向GT9147多个寄存器写入数据
 * @param - addr: 设备地址
 * @param - reg : 要写入的开始寄存器地址
 * @param - len : 要写入的数据长度.
 * @param - buf : 写入到的数据缓冲区
 * @return 		: 无
 */
void gt9147_write_len(unsigned char addr,unsigned int reg,unsigned int len, unsigned char *buf)
{	
	struct i2c_transfer masterXfer;	
	
	masterXfer.slaveAddress = addr;				/* 设备地址         */
    masterXfer.direction = kI2C_Write;			/* 读取数据 	    */
    masterXfer.subaddress = reg;				/* 要读取的寄存器地址 */
    masterXfer.subaddressSize = 2;				/* 地址长度一个字节     */
    masterXfer.data = buf;						/* 接收数据缓冲区 	    */
    masterXfer.dataSize = len;					/* 读取数据长度1个字节  */
	i2c_master_transfer(I2C2, &masterXfer);
} 

/*
 * @description	: 发送GT9147配置参数
 * @param - mode: 0,参数不保存到flash
 *                1,参数保存到flash
 * @return 		: 无
 */
void gt9147_send_cfg(unsigned char mode)
{
	unsigned char buf[2];
	unsigned int i = 0;

	buf[0] = 0;
	buf[1] = mode;	/* 是否写入到GT9147 FLASH?  即是否掉电保存 */
	for(i = 0; i < (sizeof(GT9147_CFG_TBL)); i++) /* 计算校验和 */
        buf[0] += GT9147_CFG_TBL[i];            
    buf[0] = (~buf[0]) + 1;

    /* 发送寄存器配置 */
    gt9147_write_len(GT9147_ADDR, GT_CFGS_REG, sizeof(GT9147_CFG_TBL), GT9147_CFG_TBL);
    gt9147_write_len(GT9147_ADDR, GT_CHECK_REG, 2, buf);/* 写入校验和,配置更新标记 */
} 

const u16 GT9147_TPX_TBL[5]={GT_TP1_REG,GT_TP2_REG,GT_TP3_REG,GT_TP4_REG,GT_TP5_REG};
/*
 * @description	: 读取当前所有触摸点的坐标
 * @param 		: 无
 * @return 		: 无
 */
void gt9147_read_tpcoord(void)
{
	u8 buf[4];
	u8 i = 0;
	u8 regvalue = 0;

	regvalue = gt9147_read_byte(GT9147_ADDR, GT_GSTID_REG);
	gt9147_write_byte(GT9147_ADDR, GT_GSTID_REG, 0x00);
	gt9147_dev.point_num = regvalue & 0XF; /* 计算读取了多少个点 */
	/* 读取当前所有的触摸坐标值 */
	for(i = 0; i < gt9147_dev.point_num; i++)
	{
		gt9147_read_len(GT9147_ADDR, GT9147_TPX_TBL[i], 4, buf);	/* 读取坐标值 */
		gt9147_dev.x[i] = ((u16)buf[1] << 8) + buf[0];
		gt9147_dev.y[i] = (((u16)buf[3] << 8) + buf[2]);				
	} 
}

主函数 代码 ->

复制代码
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_uart.h"
#include "bsp_lcd.h"
#include "bsp_lcdapi.h"
#include "bsp_rtc.h"
#include "bsp_ft5xx6.h"
#include "bsp_gt9147.h"
#include "stdio.h"

/*
 * @description	: 使能I.MX6U的硬件NEON和FPU
 * @param 		: 无
 * @return 		: 无
 */
 void imx6ul_hardfpu_enable(void)
{
	uint32_t cpacr;
	uint32_t fpexc;

	/* 使能NEON和FPU */
	cpacr = __get_CPACR();
	cpacr = (cpacr & ~(CPACR_ASEDIS_Msk | CPACR_D32DIS_Msk))
		   |  (3UL << CPACR_cp10_Pos) | (3UL << CPACR_cp11_Pos);
	__set_CPACR(cpacr);
	fpexc = __get_FPEXC();
	fpexc |= 0x40000000UL;	
	__set_FPEXC(fpexc);
}

/*
 * @description	: main函数
 * @param 		: 无
 * @return 		: 无
 */
int main(void)
{
 	unsigned char i = 0;
	unsigned char state = OFF;

	imx6ul_hardfpu_enable();	/* 使能I.MX6U的硬件浮点 			*/
	int_init(); 				/* 初始化中断(一定要最先调用!) */
	imx6u_clkinit();			/* 初始化系统时钟 					*/
	delay_init();				/* 初始化延时 					*/
	clk_enable();				/* 使能所有的时钟 					*/
	led_init();					/* 初始化led 					*/
	beep_init();				/* 初始化beep	 				*/
	uart_init();				/* 初始化串口,波特率115200 */
	lcd_init();					/* 初始化LCD 					*/		
	
	/* 初始化触摸屏					*/ 
	gt9147_init();
	if(gt_init_fail==1) //判断gt系列初始化是否失败
	{
		ft5426_init();
	}

	tftlcd_dev.forecolor = LCD_RED;
	lcd_show_string(50, 10, 400, 24, 24, (char*)"IMX6U-ALPHA TOUCH SCREEN TEST");  
	lcd_show_string(50, 40, 200, 16, 16, (char*)"TOUCH SCREEN TEST");  
	lcd_show_string(50, 60, 200, 16, 16, (char*)"ATOM@ALIENTEK");  
	lcd_show_string(50, 80, 200, 16, 16, (char*)"2019/3/27");  
	
	lcd_show_string(50, 110, 400, 16, 16,	(char*)"TP Num	:");  
	lcd_show_string(50, 130, 200, 16, 16,	(char*)"Point0 X:");  
	lcd_show_string(50, 150, 200, 16, 16,	(char*)"Point0 Y:");  
	lcd_show_string(50, 170, 200, 16, 16,	(char*)"Point1 X:");  
	lcd_show_string(50, 190, 200, 16, 16,	(char*)"Point1 Y:");  
	lcd_show_string(50, 210, 200, 16, 16,	(char*)"Point2 X:");  
	lcd_show_string(50, 230, 200, 16, 16,	(char*)"Point2 Y:");  
	lcd_show_string(50, 250, 200, 16, 16,	(char*)"Point3 X:");  
	lcd_show_string(50, 270, 200, 16, 16,	(char*)"Point3 Y:");  
	lcd_show_string(50, 290, 200, 16, 16,	(char*)"Point4 X:");  
	lcd_show_string(50, 310, 200, 16, 16,	(char*)"Point4 Y:");  
	
	while(1)					
	{
		/* 触摸中断函数: gt9147_irqhandler() , 选择是否显示坐标数据 */

		delayms(10);
		i++;
	
		if(i == 50)
		{	
			i = 0;
			state = !state;
			led_switch(LED0,state); 
		}
	}
	return 0;
}

bsp_lcd.h 文件 ,画点函数 代码参考 ->

复制代码
#ifndef _BSP_LCD_H
#define _BSP_LCD_H
#include "imx6ul.h"

/* 颜色 */
#define LCD_BLUE		  0x000000FF
#define LCD_GREEN		  0x0000FF00
#define LCD_RED 		  0x00FF0000
#define LCD_CYAN		  0x0000FFFF
#define LCD_MAGENTA 	  0x00FF00FF
#define LCD_YELLOW		  0x00FFFF00
#define LCD_LIGHTBLUE	  0x008080FF
#define LCD_LIGHTGREEN	  0x0080FF80
#define LCD_LIGHTRED	  0x00FF8080
#define LCD_LIGHTCYAN	  0x0080FFFF
#define LCD_LIGHTMAGENTA  0x00FF80FF
#define LCD_LIGHTYELLOW   0x00FFFF80
#define LCD_DARKBLUE	  0x00000080
#define LCD_DARKGREEN	  0x00008000
#define LCD_DARKRED 	  0x00800000
#define LCD_DARKCYAN	  0x00008080
#define LCD_DARKMAGENTA   0x00800080
#define LCD_DARKYELLOW	  0x00808000
#define LCD_WHITE		  0x00FFFFFF
#define LCD_LIGHTGRAY	  0x00D3D3D3
#define LCD_GRAY		  0x00808080
#define LCD_DARKGRAY	  0x00404040
#define LCD_BLACK		  0x00000000
#define LCD_BROWN		  0x00A52A2A
#define LCD_ORANGE		  0x00FFA500
#define LCD_TRANSPARENT   0x00000000

/* 屏幕ID */
#define ATK4342		0X4342	/* 4.3寸480*272 	*/
#define ATK4384		0X4384	/* 4.3寸800*480 	*/
#define ATK7084		0X7084	/* 7寸800*480 		*/
#define ATK7016		0X7016	/* 7寸1024*600 		*/
#define ATK1018		0X1018	/* 10.1寸1280*800 	*/
#define ATKVGA		0xff00 /* VGA */

/* LCD显存地址 */
#define LCD_FRAMEBUF_ADDR	(0x89000000)

/* LCD控制参数结构体 */
struct tftlcd_typedef{
	unsigned short height;		/* LCD屏幕高度 */
	unsigned short width;		/* LCD屏幕宽度 */
	unsigned char pixsize;		/* LCD每个像素所占字节大小 */
	unsigned short vspw;
	unsigned short vbpd;
	unsigned short vfpd;
	unsigned short hspw;
	unsigned short hbpd;
	unsigned short hfpd;
	unsigned int framebuffer; 	/* LCD显存首地址   	  */
	unsigned int forecolor;		/* 前景色 */
	unsigned int backcolor;		/* 背景色 */
	unsigned int id;  			/*	屏幕ID */
};

extern struct tftlcd_typedef tftlcd_dev;


/* 函数声明 */
void lcd_init(void);
unsigned short lcd_read_panelid(void);
void lcdgpio_init(void);
void lcdclk_init(unsigned char loopDiv, unsigned char prediv, unsigned char div);
void lcd_reset(void);
void lcd_noreset(void);
void lcd_enable(void);
//void video_pllinit(unsigned char loopdivi, unsigned char postdivi);

void lcd_clear(unsigned int color);
void lcd_fill(unsigned    short x0, unsigned short y0, unsigned short x1, unsigned short y1, unsigned int color);

/*
 * @description		: 画点函数 
 * @param - x		: x轴坐标
 * @param - y		: y轴坐标
 * @param - color	: 颜色值
 * @return 			: 无
 */
static inline void lcd_drawpoint(unsigned short x,unsigned short y,unsigned int color)
{ 
  	*(unsigned int*)((unsigned int)tftlcd_dev.framebuffer + 
		             tftlcd_dev.pixsize * (tftlcd_dev.width * y+x))=color;
}

/*
 * @description		: 读取指定点的颜色值
 * @param - x		: x轴坐标
 * @param - y		: y轴坐标
 * @return 			: 读取到的指定点的颜色值
 */
static inline unsigned int lcd_readpoint(unsigned short x,unsigned short y)
{ 
	return *(unsigned int*)((unsigned int)tftlcd_dev.framebuffer + 
		   tftlcd_dev.pixsize * (tftlcd_dev.width * y + x));
}

static inline void lcd_draw_big_point(unsigned short x,unsigned short y,unsigned int color)
{ 
  	// 画一个5x5的点阵
	lcd_drawpoint(x, y, color);
	lcd_drawpoint(x+1, y, color);
	lcd_drawpoint(x-1, y, color);
	lcd_drawpoint(x, y+1, color);
	lcd_drawpoint(x, y-1, color);
	lcd_drawpoint(x+1, y+1, color);
	lcd_drawpoint(x-1, y+1, color);
	lcd_drawpoint(x+1, y-1, color);
	lcd_drawpoint(x-1, y-1, color);
}

/* 
内联函数要放在头文件中的原因:编译器需要看到完整定义,每个编译单元需要自己的副本。
   inline 关键字:建议编译器将函数内联展开,而不是进行函数调用。减少函数调用开销(压栈、跳转、返回等)。
   函数内联展开和普通函数调用在性能上有显著差异。
何时使用 static inline: 
    1、函数很小(1-5行代码,画点函数 只是一行内存访问)
    2、频繁调用(减少调用开销,每个像素点都可能调用)
    3、性能关键(避免函数调用延迟,图形操作需要快速)
    4、通用工具函数(多个文件都需要)

画一个800×480的屏幕:
    函数调用:800×480 = 384,000次函数调用
    内联:384,000次直接内存写入
    假设每次函数调用需要10个时钟周期:
    函数调用总开销:384,000 × 10 = 3,840,000 周期
    在100MHz的MCU上:约38.4ms的纯调用开销
    内联可以节省这38.4ms!
*/

#endif
相关推荐
阿常呓语1 小时前
ls 命令详解
linux·运维·服务器·ls
小龙报2 小时前
【51单片机】串口通讯从入门到精通:原理拆解 + 参数详解 + 51 单片机实战指南
c语言·驱动开发·stm32·单片机·嵌入式硬件·物联网·51单片机
倔强的石头1062 小时前
【Linux指南】基础IO系列(一)Linux 文件本质揭秘 —— 从 “磁盘文件” 到 “一切皆文件”
linux·运维·服务器
robitmind2 小时前
操作input子系统,用模拟按键输入解锁ubuntu锁屏
linux·运维·ubuntu
落羽的落羽2 小时前
【Linux系统】文件IO:理解文件描述符、重定向、缓冲区
linux·服务器·开发语言·数据结构·c++·人工智能·机器学习
xie_pin_an2 小时前
Linux 基础入门:从历史到核心指令全解析
linux·运维·服务器
ajole2 小时前
Linux学习笔记——基本指令
linux·服务器·笔记·学习·centos·bash
嵌入小生0072 小时前
数据结构与算法 | 完全二叉树的实现、哈希表的实现
linux·c语言·数据结构·算法·vim·嵌入式
仰望星空的凡人2 小时前
探秘MCU最小系统中的晶振部分是如何工作的?
单片机·嵌入式硬件