STM32驱动不带字库12864LCD

STM32驱动5V的12864LCD,控制脚和数据较最好接到STM32能容忍5v的IO口,外加上拉电阻时,控制脚和数据脚设置成开漏输出。不加上拉电阻时,控制脚设置为推拉输出,数据脚输出时,设置成推拉输出,输入时设置成上拉输入。加不加上拉电阻都能点亮LCD,关键是脚位配置。

GPIOE的PE0-PE7做数据线,控制线定义如下:

//————-PORTE———————

#define R_S GPIO_Pin_8

#define R_W GPIO_Pin_9

#define EN GPIO_Pin_10

#define _CS1 GPIO_Pin_11

#define _CS2 GPIO_Pin_12

#define _RST GPIO_Pin_13

首先IO口初始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOE, &GPIO_InitStructure);

GPIO_ResetBits(GPIOE, EN );

GPIO_SetBits(GPIOE,_CS1 | _CS2 );

注意_CS1,_CS2初始化是一定要拉高,否则检测忙信号时,忙信号会一直是高。我就是因为这个问题卡了好几天。

以下是LCD驱动程序:

//指令宏定义

#define Display_On 0x3f //显示开指令

#define Display_Off 0x3e //显示关指令

#define Y_Col_Addr 0x40 //定位到第0列指令(列起始地址)(0-63)

#define X_Page_Addr 0xb8 //定位到第0页指令(页起始地址)(0-7)

#define Start_Line 0xc0 //定位从DDROM中的第0行开始往屏幕上显示

u16_t LCD_ReadStatus(void);

#define LCD_Write(x) GPIOE->ODR=(GPIOE->ODR&0xFF00)|(x);

/***********************************************************************

**Delay

************************************************************************/

void Delay(void)

{

u8_t i;

for(i=0;i<125;i++);

}

/************************************************************************

**DATA_Input

*************************************************************************/

void DATA_Input(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure LCD_DATA GPIO Pin as input floating */

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_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOE,&GPIO_InitStructure);

}

/***********************************************************************

**DATA_Output

************************************************************************/

void DATA_Output(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure LCD_DATA GPIO Pin as output push-pull */

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_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_Init(GPIOE,&GPIO_InitStructure);

}

/***********************************************************************

**LCD_Command

************************************************************************/

void Write_Cmd(u8_t Port)

{

DATA_Output();

Delay();

GPIO_ResetBits(GPIOE,EN);

Delay();

GPIO_ResetBits(GPIOE,R_S);

Delay();

GPIO_ResetBits(GPIOE,R_W);

Delay();

LCD_Write(Port);

Delay();

GPIO_SetBits(GPIOE,EN);

Delay();

GPIO_ResetBits(GPIOE,EN);

Delay();

while(LCD_ReadStatus()&0x0080==0x0080);

}

/***********************************************************************

**LCD_ReadStatus

************************************************************************/

u16_t LCD_ReadStatus(void)

{

u16_t Status;

GPIO_ResetBits(GPIOE,EN);

Delay();

DATA_Input();

Delay();

GPIO_ResetBits(GPIOE,R_S);

Delay();

GPIO_SetBits(GPIOE,R_W);

Delay();

GPIO_SetBits(GPIOE,EN);

Delay();

Status=GPIO_ReadInputData(GPIOE);

Delay();

GPIO_ResetBits(GPIOE,EN);

Delay();

return Status;

}

/***********************************************************************

**LCD_WriteData

************************************************************************/

void Write_Data(u8_t Data)

{

DATA_Output();

Delay();

GPIO_ResetBits(GPIOE,EN);

Delay();

GPIO_SetBits(GPIOE,R_S);

Delay();

GPIO_ResetBits(GPIOE,R_W);

Delay();

LCD_Write(Data);

Delay();

GPIO_SetBits(GPIOE,EN);

Delay();

GPIO_ResetBits(GPIOE,EN);

Delay();

while(LCD_ReadStatus()&0x0080==0x0080);

}

/*—————————————————————————————————-*/

//设定行地址(页)–X 0-7

void SetPage(u8_t page)

{

Write_Cmd(0xb8 | page);

}

//设定列地址–Y 0-63

void SetColumn(u8_t column)

{

Write_Cmd(0x40 | column);

}

//设定显示开始行–XX

void SetStartLine(u8_t startline) //0–63

{

Write_Cmd(0xc0 | startline);

}

/*————————————————————–*/

//液晶定位(8*8)

//液晶规划:

//x: 0 – 7 (行)

//y: 0 -15 (列)

void LCD_pos(u8_t x, u8_t y)

{

if(y < 8)

{

GPIO_SetBits(GPIOE,_CS1); //左半屏

GPIO_ResetBits(GPIOE,_CS2);

}

else

{

y -= 8; //右半屏

GPIO_SetBits(GPIOE,_CS2);

GPIO_ResetBits(GPIOE,_CS1);

}

SetPage(x); //页地址

SetColumn(y * 8);//列地址

}

//液晶字符输出(8*16字体)

//x: 0 -3/7 (行)

//y: 0 -15 (列)

void LCD_printc(u8_t x, u8_t y, u16_t c_dat)

{

u8_t i, j;

for(j = 0; j < 2; j++)

{

LCD_pos((x * 2 + j), y);

for(i = 0; i < 8; i++) Write_Data(Font_code[c_dat – 32][8 * j + i]);

}

}

/*————————————————————–*/

//液晶字符串输出

//x: 0 – 3 (行)

//y: 0 -15 (列)

void LCD_prints(u8_t x, u8_t y, u16_t *s_dat)

{

u8_t i;

for(i=0;i<16;i++)

LCD_printc(x, y++, *s_dat++);

}

void DispData(u8_t x,u16_t *s,u8_t num)

{

num = num;

LCD_prints(x-1,0, s);

}

/*————————————————————–*/

//液晶字节定位(8*1)

//液晶规划:

//x: 0 – 7 (行)

//y: 0 -127 (列)

void LCD_byte_pos(u8_t x, u8_t y)

{

if(y < 64)

{

GPIO_SetBits(GPIOE,_CS2); //左半屏

GPIO_ResetBits(GPIOE,_CS1);

}

else

{

y -= 64;

GPIO_SetBits(GPIOE,_CS1); //左半屏

GPIO_ResetBits(GPIOE,_CS2);

} //右半屏

// LCD_write_cmd(Start_Line); //起始行地址

Write_Cmd(X_Page_Addr + x); //页地址0-7

Write_Cmd(Y_Col_Addr + y); //列地址0-63

}

/*————————————————————–*/

//液晶定位写入数据一个字节

//液晶规划:

//x: 0 – 7 (页)

//y: 0 -127 (列)

void LCD_write_dat_pos(u8_t x, u8_t y, u8_t dat)

{

LCD_byte_pos(x, y);

Write_Data(dat);

}

/*————————————————————–*/

//显示128X64图片

//取码规则: 低位在前, 列行扫描, 阴码(1-亮, 0-灭)

void LCD_picture(u8_t const *img_dat)

{

u8_t i, j;

for(j = 0; j < 8; j++)

{

for(i = 0; i < 128; i++)

{

LCD_write_dat_pos(j, i, img_dat[j * 128 + i]);

}

}

}

/*—————————————————————————————————*/

//选择屏幕

//screen: 0-全屏,1-左屏,2-右屏

void SelectScreen(u8_t screen)

{ //北京显示器:负有效 cs1: 0–右; cs2: 0–左

switch(screen)

{

case 0:

GPIO_ResetBits(GPIOE,_CS2);//全屏

Delay();

GPIO_ResetBits(GPIOE,_CS1);

Delay();

break;

case 1:

GPIO_SetBits(GPIOE,_CS1);//左屏

Delay();

GPIO_ResetBits(GPIOE,_CS2);

Delay();

break;

case 2:

GPIO_ResetBits(GPIOE,_CS1); //右屏

Delay();

GPIO_SetBits(GPIOE,_CS2);

Delay();

break;

}

}

/*—————————————————————————————————*/

//清屏

//screen: 0-全屏,1-左屏,2-右

void ClearScreen(u8_t screen)

{

u8_t i,j;

SelectScreen(screen);

for(i=0;i<8;i++)

{

SetPage(i);

for(j=0;j<64;j++)

{

Write_Data(0x00);

}

}

}

/***********************************************************************

**LCD_Init

************************************************************************/

void LCD_Init(void)

{

u16_t s[]={‘0′,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,’a’,’b’,’c’,’d’,’e’,’f’};

Delay();

GPIO_ResetBits(GPIOE,_RST);

Delay();

GPIO_SetBits(GPIOE,_RST);

Delay();

//ClearScreen(0);

Write_Cmd(0x3e); //关显示

SetPage(0);//选择0页

SetColumn(0);//选择0列

SetStartLine(0);//选择起始行

Write_Cmd(0x3f);//开显示

LCD_prints(0, 0, s);

LCD_prints(1, 0, s);

LCD_prints(2, 0, s);

LCD_prints(3, 0, s);

}

发表评论

电子邮件地址不会被公开。 必填项已用*标注