MDM2802显示模块是一块在飞思卡尔开发板上使用的显示器件,它与MDM2803显示模块是一个系列的产品,MDM2803是采用MCU接口,而MDM2802则是使用SPI接口的方式来工作,其接口如图1所示。
图1 显示接口
通过对比,MDM2802完全可以借用开发板上的显示接口来工作,但驱动显示的难点是开发板上的显示接口成分比较复杂,并非是直接与MCU相连接,而是使用了一些I2C扩展接口及芯片的切换处理,这在前面介绍3个LED灯的控制时已介绍了一些。
为了后面能直接进行接口的对接,先使用显示接口的部分引脚来完成MDM2802的驱动显示,在可驱动的情况下,再逐步解决引脚的匹配与对接问题。
图2 开发板显示接口
就显示接口来讲,它的引脚连接关系如下:
(CS)CS : PA4 (RS--GND)RS : SN74CB3Q3257控制
(SCLK)WR : PB8 (RD--GND)RD : PB9
(RST)RST : TCA9539控制 DB0 : PA6
DB 1:PA7 DB 2:PB0
DB 3:PB1 DB 4:PB10
DB 5:PB12 DB 6:PA12
DB 7:PA5 DB 8:PC4
DB 9:PC5 DB 10:PE12
DB 11:PE13 DB 12:PE14
DB 13:PE15 DB 14:PC7
DB 15:PC8
(BLC)BL:TCA9539控制
(SDA)I2C1--SDA:PE0
由此不难发现:数据引脚基本都是可以直接由GPIO口来控制的,而部分的控制引脚则是间接来控制的。
为此,先以连线的方式直接用GPIO口来驱动MDM2802显示模块的显示驱动。
MDM2802显示模块与开发板的引脚连接关系为:
CS :PC7 ---> PA4
SCK:PA12 ---> PB8
RST:PE14 ---> TCA9539控制
SDA:PC4 ---> PE0 ( 多重性会导致使用困难)
为输出高低电平,所定义的语句为:
#define SET_CS() GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_07) //CS
#define CLR_CS() GPIO_ResetPins(GPIO_PORT_C, GPIO_PIN_07)
#define SET_CLK() GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12) //CLK
#define CLR_CLK() GPIO_ResetPins(GPIO_PORT_A, GPIO_PIN_12)
#define SET_REST() GPIO_SetPins(GPIO_PORT_E, GPIO_PIN_14) //RES
#define CLR_REST() GPIO_ResetPins(GPIO_PORT_E, GPIO_PIN_14)
#define SET_SDA() GPIO_SetPins(GPIO_PORT_C, GPIO_PIN_04) //DIN
#define CLR_SDA() GPIO_ResetPins(GPIO_PORT_C, GPIO_PIN_04)
显示模块对所用引脚的配置函数为:
void Init_TFT(void)
{
stc_gpio_init_tstcGpioInit;
(void)GPIO_StructInit(&stcGpioInit);
stcGpioInit.u16PinState = PIN_STAT_RST;
stcGpioInit.u16PinDir = PIN_DIR_OUT;
(void)GPIO_Init(GPIO_PORT_A, GPIO_PIN_12, &stcGpioInit);
(void)GPIO_Init(GPIO_PORT_C, GPIO_PIN_04, &stcGpioInit);
(void)GPIO_Init(GPIO_PORT_C, GPIO_PIN_07, &stcGpioInit);
(void)GPIO_Init(GPIO_PORT_E, GPIO_PIN_14, &stcGpioInit);
}
向显示模块发送字节的函数为:
void send_byte(uint8_t data)
{
uint8_t count;
for(count = 0; count < 8; count++)
{
CLR_CLK();
if(data & 0x80)
{
SET_SDA();
}
else
{
CLR_SDA();
}
data <<= 1;
SET_CLK();
}
}
向寄存器写入数据的函数为:
void write_register(uint8_t cmd)
{
CLR_CS();
CLR_CLK();
CLR_SDA();
SET_CLK();
send_byte(cmd);
SET_CS();
}
相应的以色彩清除屏幕的函数为:
void ili9341_clear(int c)
{
uint32_t index=0;
set_cursor(0x00, 0x0000);
gram_prepare();
for(index = 0; index < (320*240); index++)
{
write_data(c >> 8);
write_data(c);
}
}
显示字符串的函数为:
void LCD_ShowString(unsigned int x,unsigned int y,const char *p)
{
while(*p!='\0')
{
if(x>LCD_W-16){x=0;y+=16;}
if(y>LCD_H-16){y=x=0;}
GUI_DispChar(*p, x,y);
x=x+8;
p++;
}
}
实现图标显示的函数为:
void showimage(void)
{
int i,j;
set_cursor(10,30);
gram_prepare();
for(j=0;j<50;j++)
{
set_cursor(10,30+j);
gram_prepare();
for(i=0;i<50;i++)
{
write_data(gImage_tb[(j*50+i)*2]);
write_data(gImage_tb[(j*50+i)*2+1]);
}
}
}
进行驱动测试的主程序为:
int32_t main(void)
{
LL_PERIPH_WE(LL_PERIPH_GPIO);
LED_Init();
Init_TFT();
ili9341_init();
ili9341_clear(RED);
LCD_DrawLine(WHITE ,0, 26, 239, 26);
LCD_DrawLine(WHITE,0, 296, 239, 296);
LCD_DrawRectangle(BLUE,40, 140, 160, 260);
Draw_Circle(GREEN,100,200,60);
showimage();
BACK_COLOR=RED;
POINT_COLOR=YELLOW;
LCD_ShowString(60,10,"MDM-2802 & HC32F448");
LCD_ShowString(60,300,"BY: jinglixixi");
LL_PERIPH_WP(LL_PERIPH_GPIO);
for (;;) {
LED_G_TOGGLE();
DDL_DelayMS(DLY_MS);
}
}
经程序的编译和下载,其显示结果如图3所示,说明功能正确。
图3 显示效果
本帖最后由 jinglixixi 于 2023-9-7 08:58 编辑
引用: lugl4313820 发表于 2023-9-6 11:12 老师的外设相当的多呀,经典的LCD驱动教程,感谢分享!
哪里,还在补充着。