STM32F407驱动GC9A01+CST816D触摸显示屏

STM32F407驱动GC9A01+CST816D触摸显示屏

1 GC9A01简介

GC9A01是一款spi接口的1.28寸圆形屏,分辨率240*240,3.3v供电。

2 CST816D简介

CST816D是一款IIC接口的触摸屏,模块上有4根信号线RST->复位线,INT->触摸中断线,当触摸屏检测到触摸信号后会输出高电平,SCL->数据时钟线,SDA->数据线。如果只是简单的使用INT线可以不使用。

3 SPI驱动GC9A01

3.1 SPI接口初始化

3.1.1 初始化RS、RST、CS、led信号的GPIO

	GPIO_InitTypeDef  GPIO_InitStructure;
	      
	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC ,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_1 |GPIO_Pin_12 | GPIO_Pin_14;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
	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;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
	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);

3.1.2 硬件SPI接口初始化

GPIO_InitTypeDef  GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
	
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能PB时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);//使能SPI2时钟
 
  //PB13--SCL ,PB15--SDI初始化设置, 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;//PB13,PB15复用功能输出	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_SPI2); //PB13复用为 SPI2
	
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_SPI2); //PB15复用为 SPI2
 
	//这里只针对SPI口初始化
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,ENABLE);//复位SPI2
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2,DISABLE);//停止复位SPI2

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:全速双工模式
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;	//设置SPI的数据大小:SPI发送接收8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;	//串行同步时钟的空闲状态为高电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//串行同步时钟的第二个跳变沿(上升或下降)数据被采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;	//定义波特率预分频的值:波特率预分频值为256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
	SPI_Cmd(SPI2, ENABLE); //使能SPI外设
	SPI2_ReadWriteByte(0xff);//启动传输	

3.2 LCD初始化

	Lcd_Reset();    //复位液晶屏

	Lcd_WriteIndex(0x11);//Sleep exit 
	
	delay_ms (200);
	
	LCD_BLK_SET;//打开背光
	delay_ms(100);

	Lcd_WriteIndex(0xEF);
	Lcd_WriteIndex(0xEB);
	Lcd_WriteData(0x14); 
	
  Lcd_WriteIndex(0xFE);			 
	Lcd_WriteIndex(0xEF); 

	Lcd_WriteIndex(0xEB);	
	Lcd_WriteData(0x14); 

	Lcd_WriteIndex(0x84);			
	Lcd_WriteData(0x40); 

	Lcd_WriteIndex(0x85);			
	Lcd_WriteData(0xFF); 

	Lcd_WriteIndex(0x86);			
	Lcd_WriteData(0xFF); 

	Lcd_WriteIndex(0x87);			
	Lcd_WriteData(0xFF);

	Lcd_WriteIndex(0x88);			
	Lcd_WriteData(0x0A);

	Lcd_WriteIndex(0x89);			
	Lcd_WriteData(0x21); 

	Lcd_WriteIndex(0x8A);			
	Lcd_WriteData(0x00); 

	Lcd_WriteIndex(0x8B);			
	Lcd_WriteData(0x80); 

	Lcd_WriteIndex(0x8C);			
	Lcd_WriteData(0x01); 

	Lcd_WriteIndex(0x8D);			
	Lcd_WriteData(0x01); 

	Lcd_WriteIndex(0x8E);			
	Lcd_WriteData(0xFF); 

	Lcd_WriteIndex(0x8F);			
	Lcd_WriteData(0xFF); 


	Lcd_WriteIndex(0xB6);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x20);

	Lcd_WriteIndex(0x36);
	if(USE_HORIZONTAL==0)Lcd_WriteData(0x08);
	else if(USE_HORIZONTAL==1)Lcd_WriteData(0xC8);
	else if(USE_HORIZONTAL==2)Lcd_WriteData(0x68);
	else Lcd_WriteData(0xA8);

	Lcd_WriteIndex(0x3A);			
	Lcd_WriteData(0x05); 


	Lcd_WriteIndex(0x90);			
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x08); 

	Lcd_WriteIndex(0xBD);			
	Lcd_WriteData(0x06);
	
	Lcd_WriteIndex(0xBC);			
	Lcd_WriteData(0x00);	

	Lcd_WriteIndex(0xFF);			
	Lcd_WriteData(0x60);
	Lcd_WriteData(0x01);
	Lcd_WriteData(0x04);

	Lcd_WriteIndex(0xC3);			
	Lcd_WriteData(0x13);
	Lcd_WriteIndex(0xC4);			
	Lcd_WriteData(0x13);

	Lcd_WriteIndex(0xC9);			
	Lcd_WriteData(0x22);

	Lcd_WriteIndex(0xBE);			
	Lcd_WriteData(0x11); 

	Lcd_WriteIndex(0xE1);			
	Lcd_WriteData(0x10);
	Lcd_WriteData(0x0E);

	Lcd_WriteIndex(0xDF);			
	Lcd_WriteData(0x21);
	Lcd_WriteData(0x0c);
	Lcd_WriteData(0x02);

	Lcd_WriteIndex(0xF0);   
	Lcd_WriteData(0x45);
	Lcd_WriteData(0x09);
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x26);
 	Lcd_WriteData(0x2A);

 	Lcd_WriteIndex(0xF1);    
 	Lcd_WriteData(0x43);
 	Lcd_WriteData(0x70);
 	Lcd_WriteData(0x72);
 	Lcd_WriteData(0x36);
 	Lcd_WriteData(0x37);  
 	Lcd_WriteData(0x6F);

	Lcd_WriteIndex(0xF2);   
 	Lcd_WriteData(0x45);
 	Lcd_WriteData(0x09);
 	Lcd_WriteData(0x08);
 	Lcd_WriteData(0x08);
 	Lcd_WriteData(0x26);
 	Lcd_WriteData(0x2A);

	Lcd_WriteIndex(0xF3);   
 	Lcd_WriteData(0x43);
 	Lcd_WriteData(0x70);
 	Lcd_WriteData(0x72);
 	Lcd_WriteData(0x36);
 	Lcd_WriteData(0x37); 
 	Lcd_WriteData(0x6F);

	Lcd_WriteIndex(0xED);	
	Lcd_WriteData(0x1B); 
	Lcd_WriteData(0x0B); 

	Lcd_WriteIndex(0xAE);			
	Lcd_WriteData(0x77);
	
	Lcd_WriteIndex(0xCD);			
	Lcd_WriteData(0x63);		

	Lcd_WriteIndex(0x70);			
	Lcd_WriteData(0x07);
	Lcd_WriteData(0x07);
	Lcd_WriteData(0x04);
	Lcd_WriteData(0x0E); 
	Lcd_WriteData(0x0F); 
	Lcd_WriteData(0x09);
	Lcd_WriteData(0x07);
	Lcd_WriteData(0x08);
	Lcd_WriteData(0x03);

	Lcd_WriteIndex(0xE8);			
	Lcd_WriteData(0x34);

	Lcd_WriteIndex(0x62);			
	Lcd_WriteData(0x18);
	Lcd_WriteData(0x0D);
	Lcd_WriteData(0x71);
	Lcd_WriteData(0xED);
	Lcd_WriteData(0x70); 
	Lcd_WriteData(0x70);
	Lcd_WriteData(0x18);
	Lcd_WriteData(0x0F);
	Lcd_WriteData(0x71);
	Lcd_WriteData(0xEF);
	Lcd_WriteData(0x70); 
	Lcd_WriteData(0x70);

	Lcd_WriteIndex(0x63);			
	Lcd_WriteData(0x18);
	Lcd_WriteData(0x11);
	Lcd_WriteData(0x71);
	Lcd_WriteData(0xF1);
	Lcd_WriteData(0x70); 
	Lcd_WriteData(0x70);
	Lcd_WriteData(0x18);
	Lcd_WriteData(0x13);
	Lcd_WriteData(0x71);
	Lcd_WriteData(0xF3);
	Lcd_WriteData(0x70); 
	Lcd_WriteData(0x70);

	Lcd_WriteIndex(0x64);			
	Lcd_WriteData(0x28);
	Lcd_WriteData(0x29);
	Lcd_WriteData(0xF1);
	Lcd_WriteData(0x01);
	Lcd_WriteData(0xF1);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x07);

	Lcd_WriteIndex(0x66);			
	Lcd_WriteData(0x3C);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0xCD);
	Lcd_WriteData(0x67);
	Lcd_WriteData(0x45);
	Lcd_WriteData(0x45);
	Lcd_WriteData(0x10);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);

	Lcd_WriteIndex(0x67);			
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x3C);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x00);
	Lcd_WriteData(0x01);
	Lcd_WriteData(0x54);
	Lcd_WriteData(0x10);
	Lcd_WriteData(0x32);
	Lcd_WriteData(0x98);

	Lcd_WriteIndex(0x74);			
	Lcd_WriteData(0x10);	
	Lcd_WriteData(0x85);	
	Lcd_WriteData(0x80);
	Lcd_WriteData(0x00); 
	Lcd_WriteData(0x00); 
	Lcd_WriteData(0x4E);
	Lcd_WriteData(0x00);					
	
	Lcd_WriteIndex(0x98);			
	Lcd_WriteData(0x3e);
	Lcd_WriteData(0x07);

	Lcd_WriteIndex(0x35);	
	Lcd_WriteIndex(0x21);

	Lcd_WriteIndex(0x11);
	delay_ms(120);
	Lcd_WriteIndex(0x29);
	delay_ms(20);

4 IIC驱动

IIC驱动这里是使用GPIO模拟,STM32自带的硬件IIC接口使用时有问题。

4.1 初始化GPIO

4.1.1 配置RST复位引脚

4.1.2 配置IIC引脚

4.2 CST816D读写时序

4.2.1 写时序

	IIC_Start();  //产生一个起始信号
	IIC_Send_Byte(0X2a);//发送器件地址0X2a(手册上写的是0x1a,但使用逻辑分析仪实测出来这个地址是0x2a)
	IIC_Wait_Ack(); //等待应答
	IIC_Send_Byte(addr);   //发送低地址
	IIC_Wait_Ack();//等待应答
	IIC_Send_Byte(data);   
	IIC_Wait_Ack();//等待应答
	IIC_Stop();//产生一个停止条件 
	delay_ms(10);	

4.2.2 读时序

	IIC_Start();  				//产生一个起始信号
	IIC_Send_Byte(0X2a);   	//发送器件地址0X2a 	   
	IIC_Wait_Ack(); 			//等待应答
	IIC_Send_Byte(addr);  	 	//发送地址
	IIC_Wait_Ack();			//等待应答
	IIC_Start();  	 	   		//产生一个起始信号
	IIC_Send_Byte(0X2b); //进入接收模式(写一个0x2b)		   
	IIC_Wait_Ack();			//等待应答
	temp=IIC_Read_Byte(0);		//回读数据
	IIC_Stop();				//产生一个停止信号	   

4.2.3 获取触摸屏坐标

触摸的状态是0x03寄存器的高两位,0x00表示无效,0x01表示无触摸,0x02表示有触摸,xy坐标的精度是12位的,0x03[0:3]+0x04[0:7],0x05[0:3]+0x06[0:7],由于1.28寸屏的分辨率是240*240,所以8位精度就够了,所以只读了8位数据。
寄存器表

	key_mod = (CST_Read_One_Byte(0x03) & 0xc0)>>6;		//获取按下的状态
	*touch_x = CST_Read_One_Byte(0x04);				//获取x坐标
	*touch_y = CST_Read_One_Byte(0x06);				//获取y坐标

5 实现触摸屏绘画功能

回读触摸屏的坐标,再使用画点函数将该坐标绘制出来,就可以实现一个简单的绘画功能了。

while(1)
	{		
		//获取触摸指标
		ret = CST816D_Read(&xdat,&ydat);
		//触摸坐标取反
		xdat = 240-xdat;
		ydat = 240-ydat;
		//显示坐标值
		Lcd_ShowString(50,20,"x=",BLACK,WHITE,12,0);
		Lcd_ShowIntNum(60,20,xdat,3,BLACK,WHITE,12);
		Lcd_ShowString(50,40,"y=",BLACK,WHITE,12,0);
		Lcd_ShowIntNum(60,40,ydat,3,BLACK,WHITE,12);
		Lcd_ShowIntNum(60,60,ret,3,BLACK,WHITE,12);
		//检测到触摸屏被按下
		if(ret == 2)
		{
			//绘制坐标点
			Lcd_DrawPoint(xdat,ydat,DARKBLUE);
			Lcd_DrawRectangle(xdat,ydat,xdat+5,ydat+5,DARKBLUE);
		}
	}
物联沃分享整理
物联沃-IOTWORD物联网 » STM32F407驱动GC9A01+CST816D触摸显示屏

发表评论