芯片采用STM32F103C8T6,JLX LCD12864带中文字库,完整版驱动程序,可直接创建LCD12864.h,存放下面代码块。
#include <stdio.h>
#include “stm32f1xx_hal_spi.h”
#include “stdint.h”
SPI_HandleTypeDef hspi1;
void delay_us(int n_us) //短延时
{
int j,k;
for(j=0;j<n_us;j++)
for(k=0;k<1;k++);
}
//led串行写命令
void Lcd_WriteCmd(uint8_t cmd)
{
uint8_t i;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //LCD片选
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET); //写命令
for(i = 0; i< 8; i++)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET); //时钟低电平
delay_us(10);
if((cmd&0x80)==0x80)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET); //高电平写入
}
else
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET); //低电平写入
}
cmd=cmd<<1;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET); //时钟高电平
delay_us(10);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET); //时钟低电平
delay_us(10);
}
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET); //LCD片选取消
}
//led串行写数据
void Lcd_WriteData(uint8_t date )
{
uint8_t i;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET); //LCD片选
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET); //写数据
for(i = 0; i< 8; i++)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET); //时钟低电平
delay_us(10);
if((date&0x80)==0x80)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET); //高电平写入
}
else
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET); //低电平写入
}
date=date<<1;
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_RESET); //时钟高电平
delay_us(10);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_11,GPIO_PIN_SET); //时钟低电平
delay_us(10);
}
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET); //LCD片选取消
}
//清屏
void LCD_Clear(void)
{
unsigned char i,j;
for(i=0;i<9;i++)
{
Lcd_WriteCmd(0xb0+i);
Lcd_WriteCmd(0x10);
Lcd_WriteCmd(0x00);
for(j=0;j<132;j++)
{
Lcd_WriteData(0x00);
}
}
}
void lcd_address(uint8_t page,uint8_t column)
{
column=column-0x01;
Lcd_WriteCmd(0xb0+page-1); //设置页地址,每 8 行为一页,全屏共 64 行,被分成 8 页
Lcd_WriteCmd(0x10+(column>>4&0x0f)); //设置列地址的高 4 位
Lcd_WriteCmd(column&0x0f); //设置列地址的低 4 位
}
/*
led12864串行初始化
*/
void Lcd_Init(void)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET); //复位
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET); //复位结束
HAL_Delay(100);
Lcd_WriteCmd(0xe2); //软复位
HAL_Delay(5);
Lcd_WriteCmd(0x2c); //升压步聚 1
HAL_Delay(50);
Lcd_WriteCmd(0x2e); //升压步聚 2
HAL_Delay(50);
Lcd_WriteCmd(0x2f); //升压步聚 3
HAL_Delay(5);
Lcd_WriteCmd(0x23); //粗调对比度,可设置范围 0x20~0x27
Lcd_WriteCmd(0x81); //微调对比度
Lcd_WriteCmd(0x28); //微调对比度的值,可设置范围 0x00~0x3f
Lcd_WriteCmd(0xa2); //1/9 偏压比(bias)
Lcd_WriteCmd(0xc8); //行扫描顺序:从上到下
Lcd_WriteCmd(0xa0); //列扫描顺序:从左到右
Lcd_WriteCmd(0x40); //起始行:第一行开始
Lcd_WriteCmd(0xaf); //开显示
}
//显示 128x64 点阵图像
void display_128x64(unsigned char *dp)
{
uint8_t i,j;
for(j=0;j<8;j++)
{
lcd_address(j+1,1);
for (i=0;i<128;i++)
{
Lcd_WriteData(*dp); //写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1
dp++;
}
}
}
//显示 16x16 点阵图像、汉字、生僻字或 16x16 点阵的其他图标
void display_graphic_16x16(unsigned char page,unsigned char column,unsigned char *dp)
{
uint8_t i,j;
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for (i=0;i<16;i++)
{
Lcd_WriteData(*dp); //写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1
dp++;
}
}
}
//显示 8x16 点阵图像、ASCII, 或 8x16 点阵的自造字符、其他图标
void display_graphic_8x16(unsigned char page,unsigned char column,unsigned char *dp)
{
uint8_t i,j;
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for (i=0;i<8;i++)
{
Lcd_WriteData(*dp); //写数据到 LCD,每写完一个 8 位的数据后列地址自动加 1
dp++;
}
}
}
//显示 5X8 点阵图像、ASCII, 或 5x8 点阵的自造字符、其他图标
void display_graphic_5x8(unsigned char page,unsigned char column,unsigned char *dp)
{
uint8_t i;
lcd_address(page,column);
for (i=0;i<6;i++)
{
Lcd_WriteData(*dp);
dp++;
}
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_16x16(unsigned long fontaddr,unsigned char page,unsigned char column)
{
unsigned char i,j,disp_data;
unsigned char cmd=0x03, addr_h8=((fontaddr&0xff0000)>>16), addr_m8=((fontaddr&0xff00)>>8), addr_l8=(fontaddr&0xff);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET); //字库片选
HAL_SPI_Transmit(&hspi1,&cmd,1,10);
HAL_SPI_Transmit(&hspi1,&addr_h8,1,10); //地址的高 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_m8,1,10); //地址的中 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_l8,1,10); //地址的低 8 位,共 24 位
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for(i=0; i<16; i++ )
{
HAL_SPI_Receive(&hspi1,&disp_data,1,10);
Lcd_WriteData(disp_data); //写数据到 LCD,每写完 1 字节的数据后列地址自动加 1
}
}
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //取消字库片选
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_8x16(unsigned long fontaddr,unsigned char page,unsigned char column)
{
unsigned char i,j,disp_data;
unsigned char cmd=0x03, addr_h8=((fontaddr&0xff0000)>>16), addr_m8=((fontaddr&0xff00)>>8), addr_l8=(fontaddr&0xff);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET); //字库片选
HAL_SPI_Transmit(&hspi1,&cmd,1,10);
HAL_SPI_Transmit(&hspi1,&addr_h8,1,10); //地址的高 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_m8,1,10); //地址的中 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_l8,1,10); //地址的低 8 位,共 24 位
for(j=0;j<2;j++)
{
lcd_address(page+j,column);
for(i=0; i<8; i++ )
{
HAL_SPI_Receive(&hspi1,&disp_data,1,10);
Lcd_WriteData(disp_data); //写数据到 LCD,每写完 1 字节的数据后列地址自动加 1
}
}
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //取消字库片选
}
//从指定地址读出数据写到液晶屏指定(page,column)座标中
void get_and_write_5x8(unsigned long fontaddr,unsigned char page,unsigned char column)
{
unsigned char i,disp_data;
unsigned char cmd=0x03, addr_h8=((fontaddr&0xff0000)>>16), addr_m8=((fontaddr&0xff00)>>8), addr_l8=(fontaddr&0xff);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET); //字库片选
HAL_SPI_Transmit(&hspi1,&cmd,1,10);
HAL_SPI_Transmit(&hspi1,&addr_h8,1,10); //地址的高 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_m8,1,10); //地址的中 8 位,共 24 位
HAL_SPI_Transmit(&hspi1,&addr_l8,1,10); //地址的低 8 位,共 24 位
lcd_address(page,column);
for(i=0;i<5;i++)
{
HAL_SPI_Receive(&hspi1,&disp_data,1,10);
Lcd_WriteData(disp_data); //写数据到 LCD,每写完 1 字节的数据后列地址自动加 1
}
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //取消字库片选
}
void display_GB2312_string(unsigned char page,unsigned char column,unsigned char *text)
{
unsigned char i= 0;
unsigned long fontaddr=0;
while((text[i]>0x00))
{
if(((text[i]>=0xb0) &&(text[i]<=0xf7))&&(text[i+1]>=0xa1))
{
fontaddr = (text[i]- 0xb0)94;
fontaddr += (text[i+1]-0xa1)+846;
fontaddr = (unsigned long)(fontaddr32);
get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
i+=2;
column+=16;
}
else if(((text[i]>=0xa1) &&(text[i]<=0xa3))&&(text[i+1]>=0xa1))
{
fontaddr = (text[i]- 0xa1)94;
fontaddr += (text[i+1]-0xa1);
fontaddr = (unsigned long)(fontaddr32);
get_and_write_16x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
i+=2;
column+=16;
}
else if((text[i]>=0x20) &&(text[i]<=0x7e))
{
fontaddr = (text[i]- 0x20);
fontaddr = (unsigned long)(fontaddr*16);
fontaddr = (unsigned long)(fontaddr+0x3cf80);
get_and_write_8x16(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
i+=1;
column+=8;
}
else
i++;
}
}
void display_string_5x8(unsigned char page,unsigned char column,unsigned char *text)
{
unsigned char i= 0;
unsigned long fontaddr=0;
while((text[i]>0x00))
{
if((text[i]>=0x20) &&(text[i]<=0x7e))
{
fontaddr = (text[i]- 0x20);
fontaddr = (unsigned long)(fontaddr*8);
fontaddr = (unsigned long)(fontaddr+0x3bfc0);
get_and_write_5x8(fontaddr,page,column); //从指定地址读出数据写到液晶屏指定(page,column)座标中
i+=1;
column+=6;
}
else
i++;
}
}