本帖最后由 qintian0303 于 2024-7-10 15:37 编辑
本次测试驱动使用的显示模块使用的是1.54寸TFT液晶显示屏,主要参数包括240*240分辨率,确保图像细腻且细节丰富。其核心主控芯片为ST7789,这款芯片以其强大的驱动能力和低功耗特性,广泛应用于各类小屏中。在通信接口方面,该屏幕支持SPI和8080两种主流通信协议,极大地方便了与不同微控制器的连接与兼容。通过IM0-IM2引脚的高低电平配置,用户可以轻松选择所需的通信模式:当IM0-IM2设置为000时,屏幕进入8080并行接口模式;而当设置为011时,则切换至SPI串行接口模式。本次测试中,我们特别选用了SPI串行接口进行控制,用于该开发板的SPI功能的测试。注意对于这款屏幕实际上只使用到了SPI的MOSI引脚和CLK引脚,看一下屏幕的基本控制:
通过接口可以看到除了SPI的配置,还需要WR、RST、CS这些引脚的控制,为什么CS没有直接使用SPI的CS呢,主要原因就是我们需要控制释放的时机,这些额外控制的引脚均是通过GPIO控制就可以。
通过杜邦线连接主要通过这两个座的接口实现,不过我们要注意一下,不是所有的接口都能用的,比如已有的板子资源就尽量避开一下,例如上图板载资源用到的最好尽量不用,而且,板载的Flash用到了一路SPI,用的引脚为PB3-PB5+PA15,通过查看GPIO复用表可以发现,这几个引脚可以连接到SPI1也可以连接到SPI3,通过查看复用表和未使用引脚情况,选择SPI2作为本次驱动用的外设,对应引脚(PB12-PB15):
PB12为CS,普通引脚;
PB13为SPI的SCK;
PB15为SPI的MOSI;
SPI初始化:
void MM_SPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_StructInit(&SPI_InitStruct);
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_DataWidth = 8;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI2, &SPI_InitStruct);
SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Rx);
SPI_BiDirectionalLineConfig(SPI2, SPI_Direction_Tx);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_5);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_5);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
SPI_Cmd(SPI2, ENABLE);
}
其他引脚初始化:
#define TFT_RS_reset GPIO_ResetBits(GPIOC, GPIO_Pin_12)
#define TFT_RS_set GPIO_SetBits(GPIOC, GPIO_Pin_12)
#define TFT_RESET_reset GPIO_ResetBits(GPIOB, GPIO_Pin_0)
#define TFT_RESET_set GPIO_SetBits(GPIOB, GPIO_Pin_0)
#define TFT_BL_SET GPIO_SetBits(GPIOD, GPIO_Pin_2)
#define TFT_BL_RESET GPIO_ResetBits(GPIOD, GPIO_Pin_2)
#define SPI1_CS_OUT0 GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define SPI1_CS_OUT1 GPIO_SetBits(GPIOB, GPIO_Pin_12)
void MM_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOD, &GPIO_InitStruct);
TFT_init();
}
效果如下:
|