STM32 使用LCD12864显示屏(串行方式)

LCD12864

简介

12864LCD液晶显示模块是一款4位/8位并行、2线或3线接口方式,内部含有国际一级、二级简体中文字库的图形点阵液晶模块。显示分辨率为12864,内置8198个1616点汉字,和128个16*8点ASCII字符集。

功能引脚图

STM32 使用LCD12864显示屏(串行方式)_第1张图片

串口通讯需要使用的引脚

  1. CS片选信号 (如果只有一款屏,可以将CS直接接到VCC上,实现两线通讯。)
  2. SID数据传输引脚
  3. CLK时钟
  4. PSB(低电平表示串行通讯,串口通讯时可以直接接地。)
  5. VSS、VDD电源脚

原理图

工作电压:5V
驱动电压:0-7V
逻辑电平:2.7-5.5V
工作温度:0-55°C
STM32 使用LCD12864显示屏(串行方式)_第2张图片

串行时序图

  1. 在操作液晶屏前,将CS片选信号拉高。
  2. SID前8位是控制字符,1-5位固定为1。
    RW为0时,表示写操作。RS为1时,表示写数据,RS为0时,表示写指令。
    因此写指令CMD固定为0xF8,写数据DAT固定为0xFA。
  3. 发送数据分为两组,将发送的8位数据截取成两段,第一段发送给1byte的高4位,第二段发送给2byte的高4位。
    STM32 使用LCD12864显示屏(串行方式)_第3张图片

基本指令说明

  1. 功能设定
    本设计使用(0x30),表示8位MPU控制,选择基本指令集。
    STM32 使用LCD12864显示屏(串行方式)_第4张图片

  2. 显示开关设置
    本设计使用(0x0C),表示设定显示开,关闭光标,正常显示。
    STM32 使用LCD12864显示屏(串行方式)_第5张图片

  3. 进入设定点
    本设计使用(0x06),表示显示数据的读写时,设定游标方向右移,DDRAM地址计数器加1。
    STM32 使用LCD12864显示屏(串行方式)_第6张图片

  4. 清楚显示
    本设计使用(0x01),表示清除显示。
    在这里插入图片描述

  5. 设定DDRAM地址
    本设计使用(0x80),表示设置启动位置到地址计数器。
    128x64点阵原理上等同于256x32点阵,第三行对应的DDRAM地址紧接着第一行,第四行对应的DDRAM地址紧接着第二行。在使用反白功能时,第一行反白,第三行必然反白。
    STM32 使用LCD12864显示屏(串行方式)_第7张图片

6. 屏幕与DDRAM地址的对应关系

STM32 使用LCD12864显示屏(串行方式)_第8张图片

代码配置

lcd12864.h

#ifndef __LCD12864_H
#define __LCD12864_H

#include "stm32f10x.h"
#include "Delay.h"

#define CS 	GPIO_Pin_0	//片选信号
#define SID GPIO_Pin_1	//数据传输
#define CLK GPIO_Pin_2	//时钟
#define PSB GPIO_Pin_3	//串并选择 低电平为串行
#define CMD_PROT GPIOC	//GPIO分组

#define CS_HIGH GPIO_SetBits(CMD_PROT,CS)
#define CS_LOW GPIO_ResetBits(CMD_PROT,CS)
#define SID_HIGH GPIO_SetBits(CMD_PROT,SID)
#define SID_LOW GPIO_ResetBits(CMD_PROT,SID)
#define CLK_HIGH GPIO_SetBits(CMD_PROT,CLK)
#define CLK_LOW GPIO_ResetBits(CMD_PROT,CLK)
#define PSB_HIGH GPIO_SetBits(CMD_PROT,PSB)
#define PSB_LOW GPIO_ResetBits(CMD_PROT,PSB)

#define CMD 0xF8	//写指令
#define DAT 0xFA	//写数据

typedef struct{
	uint8_t com;	//地址
	uint8_t num;	//长度
	uint8_t *dat;	//数据
}LCD_InitTypeDef;	//定义写文字用的结构体

void LCD12864_UserConfig(void);/*用户配置*/
void LCD12864_Write_Init(void);/*LCD12864上电初始化流程*/
void LCD12864_Write_CMD_Data(uint8_t cmd,uint8_t data);/*LCD12864写函数 传入指令写指令,传入数据写数据*/
void LCD12864_Write_Word(LCD_InitTypeDef LCD_InitStructure);/*LCD12864写文字*/
void LCD12864_Write_Number(uint8_t com,uint8_t num);/*LCD12864写数字*/
void LCD12864_Open(void);/*屏幕开显示*/
void LCD12864_Shut(void);/*屏幕关显示,进入睡眠*/

#endif

lcd12864.c

#include "lcd12864.h"

/*用户配置*/
void LCD12864_UserConfig(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin	= CS|SID|CLK|PSB;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(CMD_PROT,&GPIO_InitStructure);
}

/*LCD12864写一个字节*/
void LCD12864_Write_Byte(uint8_t data)
{
	uint8_t WBi;
	CS_HIGH;	//写之前拉高片选信号
	for(WBi=0;WBi<8;WBi++)
	{
		(data<<WBi&0x80)?SID_HIGH:SID_LOW;	//移位,判断高位
	
		CLK_LOW;	//拉低时钟
		CLK_HIGH;	//拉高时钟
	}
	CS_LOW;		//释放片选,不再占据总线
}
	
/*LCD12864写函数 传入指令写指令,传入数据写数据*/
void LCD12864_Write_CMD_Data(uint8_t cmd,uint8_t data)
{
	LCD12864_Write_Byte(cmd);
	LCD12864_Write_Byte(data&0xf0);			//根据时序图,传入数据的高4位变成发送数据的高4位,发送的数据低4位为0。例0x38 0011 1000 & 1111 0000
	LCD12864_Write_Byte((data<<4)&0xf0);	//再取传入数据的低4位,变成发送数据的高4位,发送的数据低4位为0。例0x38<<4 1000 & 1111 0000
	Delay_ms(2);	//设置传输延时
}

/*LCD12864上电初始化流程*/
void LCD12864_Write_Init(void)
{
	PSB_LOW;								//设置串行通讯
	LCD12864_Write_CMD_Data(CMD,0x30);		//功能设定,8位MCU接口,基本指令集
	LCD12864_Write_CMD_Data(CMD,0x06);		//显示数据的读写时,设定游标方向右移,DDRAM地址计数器加1
	LCD12864_Write_CMD_Data(CMD,0x0C);		//开显示,关闭光标
	LCD12864_Write_CMD_Data(CMD,0x01);		//清除显示
	LCD12864_Write_CMD_Data(CMD,0x80);		//设置启动位置
}
	
/*屏幕开显示*/
void LCD12864_Open(void)
{
	LCD12864_Write_CMD_Data(CMD,0x0C);	
}

/*屏幕关显示,进入睡眠*/
void LCD12864_Shut(void)
{
	LCD12864_Write_CMD_Data(CMD,0x08);		//进入睡眠模式
}

/*LCD12864写文字*/
void LCD12864_Write_Word(LCD_InitTypeDef LCD_InitStructure)
{
	uint8_t LWWi;
	LCD12864_Write_CMD_Data(CMD,LCD_InitStructure.com);		//写指令:写入地址
	
	for(LWWi=0;LWWi<LCD_InitStructure.num;LWWi++)
	{
		LCD12864_Write_CMD_Data(DAT,*LCD_InitStructure.dat++);	//根据数据长度写入字节
		Delay_ms(200);
	}
}
	
/*LCD12864写数字*/
void LCD12864_Write_Number(uint8_t com,uint8_t num)
{
	const uint8_t number[] = {"0123456789"};
	LCD12864_Write_CMD_Data(CMD,com);					//写地址
	
	LCD12864_Write_CMD_Data(DAT,number[num/1000]);		//1234 1
	LCD12864_Write_CMD_Data(DAT,number[num%1000/100]);	//1234 2
	LCD12864_Write_CMD_Data(DAT,number[num%100/10]);	//1234 3
	LCD12864_Write_CMD_Data(DAT,number[num%100%10]);	//1234 4
}

main.c

#include "stm32f10x.h"   // Device header
#include "lcd12864.h"
#include "Delay.h"

LCD_InitTypeDef LCD_InitStructure;

int main(void)
{
	LCD12864_UserConfig();		//LCD12864用户配置初始化
	LCD12864_Write_Init();		//LCD12864流程初始化
	
	LCD_InitStructure.com = 0x80;	//0x80-0x87 16 8
	LCD_InitStructure.num =16;
	LCD_InitStructure.dat = (u8*)&"桃之夭夭灼灼其华";
	LCD12864_Write_Word(LCD_InitStructure);
	
	LCD_InitStructure.com = 0x90;	//0x90-0x97 16 8
	LCD_InitStructure.num =16;
	LCD_InitStructure.dat = (u8*)&"之子于归宜其室家";
	LCD12864_Write_Word(LCD_InitStructure);
	
	LCD_InitStructure.com = 0x88;	//0x88-0x8F 16 8
	LCD_InitStructure.num =16;
	LCD_InitStructure.dat = (u8*)&"桃之夭夭有蕡其实";
	LCD12864_Write_Word(LCD_InitStructure);
	
	LCD_InitStructure.com = 0x98;	//0x98-0x9F 16 8
	LCD_InitStructure.num =16;
	LCD_InitStructure.dat = (u8*)&"之子于归宜其家室";
	LCD12864_Write_Word(LCD_InitStructure);
	
	Delay_ms(500);	//等待500ms
	
	LCD12864_Write_CMD_Data(CMD,0x01);	//清屏
	while(1)
	{
		uint8_t i;
		for(i=0;i<200;i++)
		{
			LCD12864_Write_Number(0x90,i);		//第二行显示动态的数字
			Delay_ms(200);
		}
	}
}

你可能感兴趣的:(stm32,单片机,嵌入式硬件)