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位数据。
文章来源:https://www.toymoban.com/news/detail-798567.html
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 实现触摸屏绘画功能
回读触摸屏的坐标,再使用画点函数将该坐标绘制出来,就可以实现一个简单的绘画功能了。文章来源地址https://www.toymoban.com/news/detail-798567.html
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);
}
}
到了这里,关于STM32F407驱动GC9A01+CST816D触摸显示屏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!