新手入门
- 积分
- 17
- 金钱
- 17
- 注册时间
- 2020-8-9
- 在线时间
- 3 小时
|
论坛和网上大部分关于TFT-LCD的驱动基本都是16位或者SPI方式,而且关于读LCD的内容很少。最近闲来无事就在原子的基础上改了改做了个屏,顺便发出来,就当做下笔记,有不对的地方希望大家指正。
主要是读LCD的部分。
单片机: MM32
LCD: 480*320
驱动芯片:ST7796S
驱动方式:8bit
颜色格式:16bit(565)
参考资料:正点原子Mini开发板&ST7796S 数据手册
IO口初始化:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD, ENABLE); //开启GPIOC/D时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);
IO口宏定义:
#define LCD_CS_SET GPIOD->BSRR=1<<2 //不片选 PD2
#define LCD_WR_SET GPIOD->BSRR=1<<3 //写数据 PD3
#define LCD_RD_SET GPIOD->BSRR=1<<4 //使能 PD4
#define LCD_RS_SET GPIOD->BSRR=1<<5 //数据 PD5
#define LCD_RST_SET GPIOD->BSRR=1<<6 //不复位 PD6
#define LCD_CS_CLR GPIOD->BRR=1<<2 //片选 PD2
#define LCD_WR_CLR GPIOD->BRR=1<<3 //读数据 PD3
#define LCD_RD_CLR GPIOD->BRR=1<<4 //失能 PD4
#define LCD_RS_CLR GPIOD->BRR=1<<5 //命令 PD5
#define LCD_RST_CLR GPIOD->BRR=1<<6 //复位 PD6
数据口为:PC7~0
/*数据发送
*因为C口的其它引脚另有用途,所以就这样写了
*用起来也没毛病
*/
void DATAOUT(u8 data)
{
GPIOC->ODR = (GPIOC->ODR & 0xFF00) + (u16)data;
}
/*读LCD数据*/
u8 LCD_RD_DATA(void)
{
u8 data;
GPIOC->CRL=0X88888888; //PC0-7 上拉输入
GPIOC->ODR = GPIOC->ODR & 0xFF00; //全部输出0
LCD_RS_SET;
LCD_CS_CLR;
LCD_WR_SET;
LCD_RD_CLR;
__NOP();
__NOP();
data=(u8)(GPIOC->IDR & 0xFF);
LCD_RD_SET;
LCD_CS_SET;
GPIOC->CRL=0X33333333; //PB0-7 上拉输出
GPIOC->ODR=GPIOC->ODR | 0xFF; //全部输出高
return data;
}
/*写LCD寄存器(命令)*/
void LCD_WR_REG(u8 reg)
{
LCD_RS_CLR;
LCD_CS_CLR;
LCD_RD_SET;
DATAOUT(reg);
LCD_WR_CLR;
__NOP();
__NOP();
LCD_WR_SET;
LCD_CS_SET;
}
/*写8位数据到LCD*/
void LCD_WRITE_8B(u8 data)
{
LCD_RS_SET;
LCD_CS_CLR;
LCD_RD_SET;
DATAOUT(data);
LCD_WR_CLR;
__NOP();
__NOP();
LCD_WR_SET;
LCD_CS_SET;
}
/*写16位数据到LCD*/
void LCD_WRITE_16B(u16 data)
{
LCD_RS_SET;
LCD_CS_CLR;
LCD_RD_SET;
DATAOUT((u8)(data >> 8));
LCD_WR_CLR;
__NOP();
__NOP();
LCD_WR_SET;
DATAOUT((u8)(data & 0xFF));
LCD_WR_CLR;
__NOP();
__NOP();
LCD_WR_SET;
LCD_CS_SET;
}
/*读驱动ID*/
u16 read_id(void)
{
u8 idH,idL;
LCD_WR_REG(0xD3);
LCD_RD_DATA();
LCD_RD_DATA();
idH = LCD_RD_DATA();
idL = LCD_RD_DATA();
return ((u16)idH << 8) + idL;
}
/*读LCD对应坐标点颜色*/
u16 LCD_ReadPoint(u16 x,u16 y)
{
u8 dataH,dataL;
if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回
LCD_SetCursor(x,y);
LCD_WR_REG(0x2E);
LCD_RD_DATA(); //Dummy read
dataH = LCD_RD_DATA();
dataL = LCD_RD_DATA();
return (((u16)dataH) << 8) + dataL;
}
|
|