LCD12864与STM32F103C8T6软件通讯的设计
时间: 2023-12-14 14:05:22 浏览: 70
LCD12864是一种常见的128x64点阵的液晶显示屏,STM32F103C8T6是STM32系列单片机中的一种,本文将介绍如何通过软件实现LCD12864与STM32F103C8T6的通讯。
硬件连接
LCD12864的引脚定义如下:
| 引脚 | 名称 | 功能 |
| --- | --- | --- |
| 1 | VSS | 地 |
| 2 | VDD | 电源 |
| 3 | VO | 对比度调节 |
| 4 | RS | 数据/指令选择 |
| 5 | R/W | 读写选择 |
| 6 | E | 使能 |
| 7-14 | DB0-DB7 | 数据线 |
| 15 | CS1 | 芯片选择1 |
| 16 | CS2 | 芯片选择2 |
| 17 | RST | 复位 |
STM32F103C8T6的引脚定义如下:
| 引脚 | 名称 | 功能 |
| --- | --- | --- |
| PA0 | LCD_RS | 数据/指令选择 |
| PA1 | LCD_RW | 读写选择 |
| PA2 | LCD_E | 使能 |
| PA3-PA6 | LCD_DB4-LCD_DB7 | 数据线 |
| PA7 | LCD_CS1 | 芯片选择1 |
| PA8 | LCD_CS2 | 芯片选择2 |
| PA9 | 无 | 串口1_TX |
| PA10 | 无 | 串口1_RX |
将STM32F103C8T6的引脚与LCD12864的引脚连接如下:
| LCD12864引脚 | 连接到STM32F103C8T6的引脚 |
| --- | --- |
| VSS | GND |
| VDD | 3.3V |
| VO | 对比度可调 |
| RS | PA0 |
| R/W | PA1 |
| E | PA2 |
| DB0-DB3 | 不连接 |
| DB4 | PA3 |
| DB5 | PA4 |
| DB6 | PA5 |
| DB7 | PA6 |
| CS1 | PA7 |
| CS2 | PA8 |
| RST | 不连接 |
软件设计
在STM32F103C8T6上,我们可以通过GPIO模拟SPI总线来与LCD12864进行通讯。首先需要定义一些宏:
```c
#define LCD_RS_H() GPIO_SetBits(GPIOA,GPIO_Pin_0)
#define LCD_RS_L() GPIO_ResetBits(GPIOA,GPIO_Pin_0)
#define LCD_RW_H() GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define LCD_RW_L() GPIO_ResetBits(GPIOA,GPIO_Pin_1)
#define LCD_E_H() GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define LCD_E_L() GPIO_ResetBits(GPIOA,GPIO_Pin_2)
#define LCD_CS1_H() GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define LCD_CS1_L() GPIO_ResetBits(GPIOA,GPIO_Pin_7)
#define LCD_CS2_H() GPIO_SetBits(GPIOA,GPIO_Pin_8)
#define LCD_CS2_L() GPIO_ResetBits(GPIOA,GPIO_Pin_8)
#define LCD_DB_OUT() GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP
#define LCD_DB_IN() GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU
#define LCD_DB4_H() GPIO_SetBits(GPIOA,GPIO_Pin_3)
#define LCD_DB4_L() GPIO_ResetBits(GPIOA,GPIO_Pin_3)
#define LCD_DB5_H() GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define LCD_DB5_L() GPIO_ResetBits(GPIOA,GPIO_Pin_4)
#define LCD_DB6_H() GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define LCD_DB6_L() GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define LCD_DB7_H() GPIO_SetBits(GPIOA,GPIO_Pin_6)
#define LCD_DB7_L() GPIO_ResetBits(GPIOA,GPIO_Pin_6)
```
然后定义一些函数来进行初始化和数据传输:
```c
void LCD_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 初始化RS、RW、E、CS1、CS2引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7 | GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 初始化DB4-DB7引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 复位LCD
LCD_RST_H();
delay_ms(1);
LCD_RST_L();
delay_ms(1);
LCD_RST_H();
delay_ms(1);
// 初始化LCD
LCD_CS1_L();
LCD_CS2_L();
LCD_RW_L();
LCD_DB_OUT();
LCD_WriteCmd(0x3f);
LCD_WriteCmd(0xc0);
LCD_WriteCmd(0x40);
}
void LCD_WriteCmd(uint8_t cmd)
{
LCD_RS_L();
LCD_RW_L();
LCD_DB_OUT();
// 高4位
if (cmd & 0x80) LCD_DB7_H(); else LCD_DB7_L();
if (cmd & 0x40) LCD_DB6_H(); else LCD_DB6_L();
if (cmd & 0x20) LCD_DB5_H(); else LCD_DB5_L();
if (cmd & 0x10) LCD_DB4_H(); else LCD_DB4_L();
LCD_E_H();
delay_us(1);
LCD_E_L();
// 低4位
if (cmd & 0x08) LCD_DB7_H(); else LCD_DB7_L();
if (cmd & 0x04) LCD_DB6_H(); else LCD_DB6_L();
if (cmd & 0x02) LCD_DB5_H(); else LCD_DB5_L();
if (cmd & 0x01) LCD_DB4_H(); else LCD_DB4_L();
LCD_E_H();
delay_us(1);
LCD_E_L();
delay_us(50);
}
void LCD_WriteData(uint8_t data)
{
LCD_RS_H();
LCD_RW_L();
LCD_DB_OUT();
// 高4位
if (data & 0x80) LCD_DB7_H(); else LCD_DB7_L();
if (data & 0x40) LCD_DB6_H(); else LCD_DB6_L();
if (data & 0x20) LCD_DB5_H(); else LCD_DB5_L();
if (data & 0x10) LCD_DB4_H(); else LCD_DB4_L();
LCD_E_H();
delay_us(1);
LCD_E_L();
// 低4位
if (data & 0x08) LCD_DB7_H(); else LCD_DB7_L();
if (data & 0x04) LCD_DB6_H(); else LCD_DB6_L();
if (data & 0x02) LCD_DB5_H(); else LCD_DB5_L();
if (data & 0x01) LCD_DB4_H(); else LCD_DB4_L();
LCD_E_H();
delay_us(1);
LCD_E_L();
delay_us(50);
}
```
最后在主函数中调用`LCD_Init()`函数进行LCD初始化,然后就可以通过`LCD_WriteCmd()`函数和`LCD_WriteData()`函数来向LCD12864发送指令和数据了。
总结
通过软件模拟SPI总线,我们可以实现STM32F103C8T6与LCD12864的通讯。在实际应用中,还需要注意时序控制和对比度的调节等问题。
阅读全文