单片机模块移植大全————电容触摸屏移植(一)

注意!这个主要是给笔者用的,移植经验仅供参考,要根据不同驱动IC进行不同的移植!

一、 笔者所使用的电容触摸屏基本属性:

在这里插入图片描述
链接: 电容式触摸屏资料

二、 笔者所使用的单片机和编译环境:

单片机:STM32F407ZET6
环境:KEIL5

三、 详细移植过程:

3.1 移植demo

首先根据上面的WIKI下载对应的示例DEMO,解压后打开如下:
在这里插入图片描述
依次打开1-DEMO,Demo_STM32、Demo_MSP2833_MSP2834_STM32F407ZGT6_Hardware_SPI:
STM32F407ZGT6STM32F407ZET6只是FLASH大小不一样,所以如果引脚允许的话,是可以直接烧录的。打开demo,先编译一遍,如果没有问题,就复制一份作为正式项目。

3.2 修改环境

将复制的一份项目打开,修改硬件:
在这里插入图片描述
修改完之后重新编译,应该是0报错,0警告的。

3.3 修改LCD_Init函数

如果只需要驱动LCD屏幕的话,只需要以下的这些引脚。(注意,我这里和DEMO给的不一样,已经进行了修改,接下来我会详细讲怎么用尽可能少的步骤去移植)
在这里插入图片描述

3.3.1 修改SPI初始化

其中SDI、SDO、SCK需要对应的SPI线,可以通过查找芯片的数据手册去看哪些引脚支持SPI功能。你可以通过在数据芯片手册里搜索SPI来找对应的引脚,注意虽然大多数封装的引脚定义都是一样的,但是最好还是确定是同一种封装。
如下:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另外的LED、LCD_RS 、LCD_RST、LCD_CS都是简单的GPIO口用法,可以随意选择。
然后我们打开 LCD_Init() 函数,先修改里面的第一句:

	SPI2_Init(); //硬件SPI初始化

打开函数定义,修改如下:

/*****************************************************************************
 * @name       :void SPI2_Init(void)	
 * @date       :2018-08-09 
 * @function   :Initialize the STM32 hardware SPI1
 * @parameters :None
 * @retvalue   :None
******************************************************************************/
void SPI2_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;

    // 1. 启用 GPIOB 和 GPIOC 的时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 启用 GPIOB 时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); // 启用 GPIOC 时钟

    // 2. 启用 SPI2 的时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);  // 启用 SPI2 时钟

    // 3. 初始化 PC2 和 PC3 为 MISO 和 MOSI
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;  // PC2 -> MISO, PC3 -> MOSI
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;            // 设置为复用模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;          // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;      // 100MHz 速度
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;            // 上拉
    GPIO_Init(GPIOC, &GPIO_InitStructure);                  // 初始化 GPIOC

    // 4. 初始化 PB10 为 SCK
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;              // PB10 -> SCK
    GPIO_Init(GPIOB, &GPIO_InitStructure);                  // 初始化 GPIOB

    // 5. 配置引脚的复用功能为 SPI2 
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_SPI2);  // PC2 -> SPI2_MISO
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_SPI2);  // PC3 -> SPI2_MOSI
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2); // PB10 -> SPI2_SCK

    // 6. 初始化 SPI2
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  // 全双工模式
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  // 主模式
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  // 8 位数据帧
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  // 时钟空闲高电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  // 第二个边沿采样
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  // 软件控制 NSS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;  // 预分频 2
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  // MSB 先传输
    SPI_InitStructure.SPI_CRCPolynomial = 7;  // CRC 多项式

    SPI_Init(SPI2, &SPI_InitStructure);  // 初始化 SPI2

    // 7. 启用 SPI2 外设
    SPI_Cmd(SPI2, ENABLE);  // 使能 SPI2
}
3.3.2 修改GPIO初始化
	LCD_GPIOInit();//LCD GPIO初始化			

打开函数定义,修改如下:

void LCD_GPIOInit(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	      
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB ,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12| GPIO_Pin_13|GPIO_Pin_14| GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   //推挽输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	LCD_LED=1;  //点亮背光
}

然后可以打开剩余的函数再看看,可以发现基本上都用的宏定义函数,这里我会直接打开 lcd.h文件,直接修改宏定义。
在这里插入图片描述
如果你修改了GPIO口,就修改对应的GPIO_TYPE,如果你修改了引脚,就修改对应的LCD_CS 、LCD_RS、 LCD_RST。
然后用全局搜索功能,将原来的SPI*修改为现在的SPI2(我自己是SPI2)。
执行到这一步,是可以运行main函数测试里除最后一个函数之外的所有函数的。
注意测试的时候最好给用5V的引脚给屏幕供电,否则可能电压不够!!

3.4 修改Touch_Test相关函数

触摸相关的引脚如下:
在这里插入图片描述
可以看出触摸用的是I2C通信。

打开Touch_Test的定义,再打开init的定义,会看到以下代码:

/*****************************************************************************
 * @name       :u8 TP_Init(void)
 * @date       :2018-08-09 
 * @function   :Initialization touch screen
 * @parameters :None
 * @retvalue   :0-no calibration
								1-Has been calibrated
******************************************************************************/  
u8 TP_Init(void)
{			    		   
	if(FT6336_Init())
	{
		return 1;
	}
	tp_dev.scan=FT6336_Scan;	//扫描函数指向GT911触摸屏扫描
	return 0;
}

然后我们再打开**FT6336_Init()**函数

/*****************************************************************************
 * @name       :u8 FT5426_Init(void)
 * @date       :2020-05-13 
 * @function   :Initialize the ft5426 touch screen
 * @parameters :none
 * @retvalue   :0-Initialization successful
								1-initialization failed
******************************************************************************/		
u8 FT6336_Init(void)
{
	u8 temp[2]; 	
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC,ENABLE);//使能GPIOB和GPIOC时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;				 //PB1->CTP_INT
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
	GPIO_Init(GPIOB, &GPIO_InitStructure);				  

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //PC5->CTP_RST
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 	 //输出	  
	GPIO_Init(GPIOC, &GPIO_InitStructure);					

	CTP_IIC_Init();      	//初始化电容屏的I2C总线  
	FT_RST=0;				//复位
	delay_ms(10);
 	FT_RST=1;				//释放复位		    
	delay_ms(500);  	
//	temp[0]=0;
//	FT6336_WR_Reg(FT_DEVIDE_MODE,temp,1);	//进入正常操作模式 
//	FT6336_WR_Reg(FT_ID_G_MODE,temp,1);		//查询模式 
	//temp[0]=40;								//触摸有效值,22,越小越灵敏	
	//FT6336_WR_Reg(FT_ID_G_THGROUP,temp,1);	//设置触摸有效值
	FT6336_RD_Reg(FT_ID_G_FOCALTECH_ID,&temp[0],1);
	if(temp[0]!=0x11)
	{
		return 1;
	}
	FT6336_RD_Reg(FT_ID_G_CIPHER_MID,&temp[0],2);
	if(temp[0]!=0x26)
	{
		return 1;
	}
	if((temp[1]!=0x00)&&(temp[1]!=0x01)&&(temp[1]!=0x02))
	{
		return 1;
	}
	FT6336_RD_Reg(FT_ID_G_CIPHER_HIGH,&temp[0],1);
	if(temp[0]!=0x64)
	{
		return 1;
	}
//	temp[0]=12;								//激活周期,不能小于12,最大14
//	FT6336_WR_Reg(FT_ID_G_PERIODACTIVE,temp,1); 
	//读取版本号,参考值:0x3003
//	FT6336_RD_Reg(FT_ID_G_LIB_VERSION,&temp[0],2);  
//	if(temp[0]==0X10&&temp[1]==0X01)//版本:0X3003
//	{ 
//		printf("CTP ID:%x\r\n",((u16)temp[0]<<8)+temp[1]);
//		return 0;
//	} 
	return 0;
}

TP_Init可知我们希望它返回0,那么我们看这段函数主要执行了什么操作,主要总结为下:

  1. 初始化了I2C的四个引脚。
  2. 向芯片发送命令。
  3. 读取芯片发回的信息。
  4. 校验芯片发回的信息。
    那么移植的话,只有第一二步是需要修改的。
3.4.1 修改I2C的四个引脚初始化

修改中断和复位引脚:


 	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC,ENABLE);//使能GPIOB和GPIOC时钟
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;				 //PB1->CTP_INT
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
	GPIO_Init(GPIOB, &GPIO_InitStructure);				  

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //PC5->CTP_RST
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 	 //输出	  
	GPIO_Init(GPIOC, &GPIO_InitStructure);		

修改SDA和SCL:

/*****************************************************************************
 * @name       :void CTP_IIC_Init(void)
 * @date       :2020-05-13 
 * @function   :Initialize IIC
 * @parameters :None
 * @retvalue   :None
******************************************************************************/
void CTP_IIC_Init(void)
{	
		GPIO_InitTypeDef GPIO_Initure;

    	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOA, ENABLE);
	
    	GPIO_Initure.GPIO_Pin=GPIO_Pin_0; 	//PB0->CTP_SCL
		GPIO_Initure.GPIO_Mode = GPIO_Mode_OUT;//输出
		GPIO_Initure.GPIO_OType = GPIO_OType_PP;//推挽
		GPIO_Initure.GPIO_Speed = GPIO_Speed_100MHz;
		GPIO_Initure.GPIO_PuPd = GPIO_PuPd_UP;//上拉		
		GPIO_Init(GPIOB, &GPIO_Initure);	
		
		GPIO_Initure.GPIO_Pin=GPIO_Pin_6; 	//PA6->CTP_SDA
		GPIO_Init(GPIOA, &GPIO_Initure);	
		
		CTP_IIC_SCL=1;
		CTP_IIC_SDA=1;
}

修改宏定义函数:

//IIC IO方向设置
#define CTP_SDA_IN()  {GPIOA->MODER &= ~(3 << (6 * 2)); GPIOA->MODER |= 0 << (6 * 2);}
#define CTP_SDA_OUT() {GPIOA->MODER &= ~(3 << (6 * 2)); GPIOA->MODER |= 1 << (6 * 2);}


//IO操作函数	 
#define CTP_IIC_SCL    PBout(0) 			//SCL     
#define CTP_IIC_SDA    PAout(6) 			//SDA	 
#define CTP_READ_SDA   PAin(6)  			//输入SDA

这些位移操作的原型在sys.c文件中有详细说明。

实验现象:
在这里插入图片描述

链接: STM32F407ZET6触摸屏移植链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值