LCD12864使用(驱动芯片UC1701x,四线模式)

LCD12864使用(驱动芯片UC1701x,四线模式)

1. 控制说明

CS芯片使能
RST复位信号,低电平有效
A01:数据。0:命令
SCLK串口时钟输入
SDA串口数据输入
1.1UC1701x 四线模式通讯时序

在这里插入图片描述

​ 从引脚配置和时序图可以看出,与LCD屏幕通讯分为两种通讯模式,一、命令。二、数据。发送数据。通过SCLK时钟线和SDA数据线发送。发送数据依据高位(MSB)在前,SCLK上升沿发送。只发不读。

代码实现。

/**
*		value要发送的数据
*/
void writeToLcd(uint8_t value)
{
  uint8_t i;
  for(i=0; i < 8; i++)
	{
		SCLK_Switch(0); //  拉低SCLK
    
		if(value&0x80)  //  稳定数据,确保上升沿前数据有效
      		SDA_Switch(1);
		else 
      		SDA_Switch(0);
    
		SCLK_Switch(1); //  发送数据
		value<<=1;
	}
}

/**
*	type 命令字节选择
*	value 要发送的数据
*/
void lcdWrite(LCD_WRITE_TYPE type, uint8_t value)
{
  CS_Switch(0);
  A0_Switch(type);		//	选择命令、数据模式
  writeToLcd(value);	//	发送数据
  CS_Switch(1);
}

//	模式
typedef enum
{
  LCD_WRITE_TYPE_COMMAND = 0,
  LCD_WRITE_TYPE_DATA,
}LCD_WRITE_TYPE;

2. 命令

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AazA01kR-

2.1 屏幕映射地址

在这里插入图片描述
从屏幕地址映射表中可以看出,LCD屏幕整个被分为8个page,每页又被分为八行,实际还是64行。列数根据屏幕大小而定,最大132列。要想在屏幕上面显示内容,我们需要根据地址映射进行配置。我们简单的根据表中的Page0分析。
在这里插入图片描述

屏幕区域显示分为3个步骤:
一、设置页地址

命令表第七条

7.Set Page Address 命令

D7D6D5D4D3D2D1D0
1011####

D7 - D4:高四位固定位0xB0

D3 - D0:为页面地址 Page0 为 0000,

即设置页地址时,需要向UC1701发送命令0xB0

二、设置列地址

根据命令表看出设置列地址时需要分为设置列高地址、列低地址
在这里插入图片描述
设置高地址的高四位为0x00,低地址高四位为0x10,第四位为列起始地址

设置多列数据时,只需要设置首列地址的命令,然后循环填充数据即可

即设置第0,1列的数据时只需要写入指令0x00,0x10,然后写入两次数据即可。

三、发送数据

这里的数据起始只的是行数据,LCD屏幕只有开关两种模式,每页分为八行,每行对应发送的数据的一位。

示例中第一行数据为 ‭00011111‬(0x1F)

​ 第二行数据为:‭11001100‬(0xCC)

代码实现

void lcdSetAddress(uint8_t page,uint8_t column)
{
	lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xb0 + page);   			      
    // 设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1*/
	
  lcdWrite(LCD_WRITE_TYPE_COMMAND, ((column>>4)&0x0f) + 0x10);	
    // 设置列地址的高4位
	lcdWrite(LCD_WRITE_TYPE_COMMAND, column&0x0f);				      
    // 设置列地址的低4位
}

void test(void)
{
  lcdSetAddress(0,0); //  0页,0列
  lcdWrite(LCD_WRITE_TYPE_DATA, 0x1F);
  lcdWrite(LCD_WRITE_TYPE_DATA, 0xCC);
}

只显示两列效果不明显,我们可以修改一下测试函数显示全部页面

void test(void)
{
    for(uint8_t i = 0; i < 8; i++)
    {
        lcdSetAddress(i,0); //  0页,0列
        for(uint8_t j = 0; j < 132; j += 2)
        {
            lcdWrite(LCD_WRITE_TYPE_DATA, 0x1F);
            lcdWrite(LCD_WRITE_TYPE_DATA, 0xCC);
        }
    }
}

验证效果好像并不是太明显,大概意思是这。。。

3.初始化

在这里插入图片描述
不想细究了直接配置吧

void LCD_Init(void)
{
  GPIO_InitTypeDef GPIO_Init;
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  
  GPIO_Init.Pin = LCD_CS_PIN | LCD_RST_PIN;
  GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_Init.Pull = GPIO_PULLUP;
  GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LCD_CS_PORT, &GPIO_Init);
  
  GPIO_Init.Pin = LCD_A0_PIN;
  HAL_GPIO_Init(LCD_A0_PORT, &GPIO_Init);
  
  GPIO_Init.Pin = LCD_SCLK_PIN | LCD_SDA_PIN | LCD_BACKLIGHT_PIN;
  HAL_GPIO_Init(LCD_SCLK_PORT, &GPIO_Init);
  
  HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN | LCD_RST_PIN, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LCD_A0_PORT,  LCD_A0_PIN, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LCD_SCLK_PORT, LCD_SCLK_PIN | LCD_SDA_PIN | LCD_BACKLIGHT_PIN, GPIO_PIN_RESET);

  RST_Switch(0);      // 重置RESET
  bsp_delay_ms(10);
  RST_Switch(1);     // 恢复重置RESET
  bsp_delay_ms(10);

  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xe2);// System Reset
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2c);// Power Rise Step1
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2e);// Power Rise Step2
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2f);// Power Rise Step3
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x23);

  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa2);// Bias 1/9
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xc0);// Set COM(row) Direction
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa1);// Set SEG(column) Direction
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x40);// Set Scroll Line: the first line
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xaf);// Display Enable
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa4);// Display Enable
  
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x81);
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x1f);
  
  LEDA_Switch(0); //  关闭背光
  clearScreen(); //  清屏
}

/*全屏清屏*/
void clearScreen(void)
{
	uint8_t i,j;
 	for(i = 0; i < 8; i++)
	{
		lcdSetAddress(i,0);
    
		for(j = 0;j < 132;j++)
		{
			lcdWrite(LCD_WRITE_TYPE_DATA, 0x00);
		}
	}
}

4.字库

下面是以 PCtolLCD2002完美版-字符模式软件为基础,制作宋体、16x16、汉字字库为例

4.1实现在指定区域显示汉字

代码

void DisplayChinese16x16(uint8_t page,uint8_t column,uint8_t reverse,uint8_t *dp)
{
  uint8_t i,j,*data_temp;
  data_temp = dp;
  for(j = 0; j < 2;j++)
  {
    lcdSetAddress(page+j,column);
    for (i=0;i < 16;i++)
    {	
      reverse == 1? *data_temp = ~*data_temp : *data_temp;
      lcdWrite(LCD_WRITE_TYPE_DATA, *data_temp);
      data_temp++;
    }
  }
}
4.2PCtolLCD2002生成字库

重点关注红框内的设置
在这里插入图片描述

生成字模、保存

在这里插入图片描述

可以根据单个字符组合成单个字符的字模的,也可以生成字库

单个字符字模刷新

/**
* 显示16x16汉字字符
* page 页地址
* column 列地址
* reverse 反显
* *dp 字模数组
*/
void DisplayChinese16(uint8_t page,uint8_t column,uint8_t reverse,uint8_t *dp)
{
  uint8_t i,j,*data_temp;
  data_temp = dp;
  for(j = 0; j < 2;j++)
  {
    lcdSetAddress(page+j,column);
    for (i=0;i < 16;i++)
    {	
      reverse == 1? *data_temp = ~*data_temp : *data_temp;
      lcdWrite(LCD_WRITE_TYPE_DATA, *data_temp);
      data_temp++;
    }
  }
}

生成字库

分为两个部分,一是、font_16_list[]字库列表。二、font_16_point[]。字模数组

char font_16_list[] = 
{
  "风急天高猿啸哀渚清沙白鸟飞回无边落木萧下不尽长江滚来"  //  26字符 52 字节
};

uint8_t font_16_point[] = 
{
  0x00,0x00,0xFE,0x02,0x12,0x22,0xC2,0x02,0xC2,0x32,0x02,0xFE,0x00,0x00,0x00,0x00,
  0x80,0x60,0x1F,0x00,0x20,0x10,0x0C,0x03,0x0C,0x30,0x00,0x0F,0x30,0x40,0xF8,0x00,/*"风",0*/

  0x00,0x10,0x08,0x94,0x93,0x92,0x92,0x92,0x92,0x9A,0x96,0x90,0xF0,0x00,0x00,0x00,
  0x40,0x30,0x04,0x74,0x84,0x84,0x8C,0xB4,0x84,0x84,0x84,0xE4,0x07,0x10,0x60,0x00,/*"急",1*/

  0x40,0x40,0x42,0x42,0x42,0x42,0x42,0xFE,0x42,0x42,0x42,0x42,0x42,0x40,0x40,0x00,
  0x80,0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x03,0x0C,0x10,0x20,0x40,0x80,0x80,0x00,/*"天",2*/

  0x04,0x04,0x04,0x04,0xF4,0x94,0x95,0x96,0x94,0x94,0xF4,0x04,0x04,0x04,0x04,0x00,
  0x00,0xFE,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x4A,0x4A,0x7A,0x02,0x82,0xFE,0x00,0x00,/*"高",3*/

  0x22,0x14,0x08,0xF6,0x00,0x10,0xD4,0x54,0x54,0x5F,0x54,0x54,0xD4,0x10,0x10,0x00,
  0x44,0x82,0x41,0x3F,0x20,0x20,0x13,0xFA,0x46,0x22,0x0E,0x12,0x2B,0x44,0x40,0x00,/*"猿",4*/

  0x00,0xFC,0x04,0x04,0xFC,0x10,0x54,0x54,0x54,0xFF,0x54,0x54,0x7C,0x10,0x10,0x00,
  0x00,0x0F,0x04,0x04,0x8F,0x40,0x3F,0x08,0x04,0xFF,0x04,0x08,0xFF,0x00,0x00,0x00,/*"啸",5*/

  0x04,0x04,0x04,0xE4,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0xE4,0x04,0x04,0x04,0x00,
  0x20,0x20,0x10,0x11,0x09,0xFD,0x43,0x21,0x03,0x05,0x09,0x11,0x28,0x44,0x40,0x00,/*"哀",6*/

  0x10,0x60,0x02,0x8C,0x20,0x24,0x24,0xA4,0x7F,0x24,0x34,0x28,0x26,0x20,0x20,0x00,
  0x04,0x04,0x7E,0x01,0x04,0x02,0xFF,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00,/*"渚",7*/

  0x10,0x60,0x02,0x8C,0x00,0x44,0x54,0x54,0x54,0x7F,0x54,0x54,0x54,0x44,0x40,0x00,
  0x04,0x04,0x7E,0x01,0x00,0x00,0xFF,0x15,0x15,0x15,0x55,0x95,0x7F,0x00,0x00,0x00,/*"清",8*/

  0x10,0x60,0x02,0x8C,0x00,0x80,0x60,0x18,0x00,0xFF,0x00,0x00,0x88,0x10,0x60,0x00,
  0x04,0x04,0x7E,0x01,0x00,0x80,0x80,0x40,0x40,0x23,0x10,0x0C,0x03,0x00,0x00,0x00,/*"沙",9*/

  0x00,0x00,0xF8,0x08,0x08,0x0C,0x0A,0x09,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,
  0x00,0x00,0xFF,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0xFF,0x00,0x00,0x00,/*"白",10*/

  0x00,0x00,0x00,0xFC,0x04,0x04,0x16,0x65,0x04,0x44,0x84,0x7C,0x00,0x00,0x00,0x00,
  0x00,0x10,0x10,0x13,0x12,0x12,0x12,0x12,0x12,0x12,0x52,0x82,0x42,0x3E,0x00,0x00,/*"鸟",11*/

  0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x40,0xA0,0x10,0x08,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x21,0x42,0xF0,0x00,/*"飞",12*/

  0x00,0x00,0xFE,0x02,0x02,0xF2,0x12,0x12,0x12,0xF2,0x02,0x02,0xFE,0x00,0x00,0x00,
  0x00,0x00,0x7F,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x7F,0x00,0x00,0x00,/*"回",13*/

  0x00,0x40,0x42,0x42,0x42,0xC2,0x7E,0x42,0xC2,0x42,0x42,0x42,0x40,0x40,0x00,0x00,
  0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x70,0x00,0x00,/*"无",14*/

  0x40,0x40,0x42,0xCC,0x00,0x00,0x08,0x08,0x88,0x7F,0x08,0x08,0x08,0xF8,0x00,0x00,
  0x00,0x40,0x20,0x1F,0x20,0x50,0x48,0x46,0x41,0x40,0x48,0x50,0x48,0x47,0x40,0x00,/*"边",15*/

  0x84,0x04,0x14,0x64,0x0F,0x04,0x84,0x44,0xB4,0x24,0x2F,0xA4,0x64,0x04,0x04,0x00,
  0x08,0x0B,0xF8,0x04,0x03,0x04,0x04,0xFA,0x4A,0x49,0x49,0x4A,0xFA,0x04,0x04,0x00,/*"落",16*/

  0x00,0x10,0x10,0x10,0x10,0xD0,0x30,0xFF,0x30,0xD0,0x10,0x10,0x10,0x10,0x00,0x00,
  0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x00,/*"木",17*/

  0x84,0x84,0xA4,0xA4,0xAF,0xA4,0xA4,0xF4,0xA4,0xA4,0xAF,0xA4,0xE4,0x84,0x84,0x00,
  0x80,0x40,0x3A,0x02,0x22,0x1A,0x02,0xFF,0x02,0x0A,0x32,0x02,0xFB,0x00,0x00,0x00,/*"萧",18*/

  0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x02,0x02,0x42,0x82,0x02,0x02,0x02,0x02,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x01,0x06,0x00,0x00,0x00,/*"下",20*/

  0x00,0x02,0x02,0x02,0x02,0x82,0x42,0xF2,0x0E,0x42,0x82,0x02,0x02,0x02,0x00,0x00,
  0x10,0x08,0x04,0x02,0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0x01,0x02,0x0C,0x00,0x00,/*"不",21*/

  0x00,0x00,0x00,0xFE,0x22,0x22,0x22,0x22,0x22,0xE2,0x22,0x22,0x7E,0x00,0x00,0x00,
  0x10,0x08,0x06,0x01,0x10,0x10,0x22,0x22,0x44,0x80,0x01,0x02,0x04,0x08,0x08,0x00,/*"尽",22*/

  0x80,0x80,0x80,0x80,0xFF,0x80,0x80,0xA0,0x90,0x88,0x84,0x82,0x80,0x80,0x80,0x00,
  0x00,0x00,0x00,0x00,0xFF,0x40,0x21,0x12,0x04,0x08,0x10,0x20,0x20,0x40,0x40,0x00,/*"长",23*/

  0x10,0x60,0x02,0x0C,0xC0,0x04,0x04,0x04,0x04,0xFC,0x04,0x04,0x04,0x04,0x00,0x00,
  0x04,0x04,0x7C,0x03,0x20,0x20,0x20,0x20,0x20,0x3F,0x20,0x20,0x20,0x20,0x20,0x00,/*"江",24*/

  0x10,0x60,0x02,0x8C,0x00,0x24,0x94,0xCC,0xA5,0x96,0xC4,0x8C,0x14,0x24,0x00,0x00,
  0x04,0x04,0x7E,0x01,0x20,0x10,0x08,0xFC,0x42,0x24,0x08,0x15,0x22,0x40,0x40,0x00,/*"滚",25*/

  0x00,0x08,0x08,0x28,0xC8,0x08,0x08,0xFF,0x08,0x08,0x88,0x68,0x08,0x08,0x00,0x00,
  0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x11,0x11,0x21,0x21,0x00,/*"来",27*/
};

根据字符列表查询对应的字模数组

uint8_t * fontGetPoint(const char *str)
{
  if(*str > 0x7F)
  {
    /* 一个汉字字符占两个字节  */
    for(uint8_t i = 0, j = 0; i < sizeof(font_16_list); i+= 2, j++)
    {
      if(*str == font_16_list[i])  //  两个字节都相同
      {
        if(*(str+1) == font_16_list[i+1])
        return (uint8_t*)(&font_16_point[j * 32]);
      }
    }
  }
  else  //  可能是英文字符
  {
    //  根据需要填充就行,比汉字简单
  }
  return 0;
}

字库使用

/**
* 显示多个16x16汉字字模
* page 页地址
* column 列地址
* reverse 反显
* *str 字符串
*/
void DisplayManyChinese16(uint8_t page,uint8_t column,uint8_t reverse, const char *str)
{
  char strl[20];      //  一个汉字占2个字节,一行最多有8个16x16的字符
  memcpy(strl, str, strlen(str));
  for(uint8_t len = 0, i = 0; len < strlen(strl); len += 2, i++)  
  //  strlen(strl)获取str1的字节数,假设有7个汉字字符,那么就有14个字节,i计算当前列地址
  {
    DisplayChinese16(page, column+(i*16), reverse, fontGetPoint(&strl[len]));
  }
}

//	测试
void test(void)
{ 
    DisplayManyChinese16(0, 4, 0, "风急天高猿啸哀");
    DisplayManyChinese16(2, 4, 0, "渚清沙白鸟飞回"); 
    DisplayManyChinese16(4, 4, 0, "无边落木萧萧下"); 
    DisplayManyChinese16(6, 4, 0, "不尽长江滚滚来");
}

代码区

1. lcd.c文件

#include "../HARDWARE/LCD/lcd.h"
#include "../HARDWARE/Font/font16/font16.h"
#include "main.h"
#include "stdio.h"
#include "string.h"
// LCD_CS1        PC4
// LCD_RES        PC5     
// LCD_A0         PB11 
// LCD_SCL        PA5
// LCD_SDA        PA7
// LCD_BACKLIGHT  PA6

// CS   使能(低电平)
#define LCD_CS_PORT GPIOC
#define LCD_CS_PIN  GPIO_PIN_4
// RES  复位(低电平)
#define LCD_RST_PORT GPIOC
#define LCD_RST_PIN  GPIO_PIN_5
// A0 数据(1)/命令(0)
#define LCD_A0_PORT  GPIOB
#define LCD_A0_PIN   GPIO_PIN_11
// SCL  串口时钟输入
#define LCD_SCLK_PORT GPIOA
#define LCD_SCLK_PIN  GPIO_PIN_5
// SDA  串口数据输入
#define LCD_SDA_PORT GPIOA
#define LCD_SDA_PIN  GPIO_PIN_7
// BACKLIGHT  背光正极
#define LCD_BACKLIGHT_PORT GPIOA
#define LCD_BACKLIGHT_PIN  GPIO_PIN_6

#define CS_Switch(x)   HAL_GPIO_WritePin(LCD_CS_PORT,   LCD_CS_PIN, (GPIO_PinState)x)
#define RST_Switch(x)  HAL_GPIO_WritePin(LCD_RST_PORT,  LCD_RST_PIN, (GPIO_PinState)x)
#define A0_Switch(x)   HAL_GPIO_WritePin(LCD_A0_PORT,    LCD_A0_PIN, (GPIO_PinState)x)
#define SCLK_Switch(x) HAL_GPIO_WritePin(LCD_SCLK_PORT,  LCD_SCLK_PIN, (GPIO_PinState)x)
#define SDA_Switch(x)  HAL_GPIO_WritePin(LCD_SDA_PORT,  LCD_SDA_PIN, (GPIO_PinState)x)
#define LEDA_Switch(x) HAL_GPIO_WritePin(LCD_BACKLIGHT_PORT,LCD_BACKLIGHT_PIN, (GPIO_PinState)x)

void writeToLcd(uint8_t value)
{
  uint8_t i;
  for(i=0; i < 8; i++)
	{
		SCLK_Switch(0); //  拉低SCLK
    
		if(value&0x80)  //  稳定数据
      SDA_Switch(1);
		else 
      SDA_Switch(0);
    
		SCLK_Switch(1); //  发送数据
		value<<=1;
	}
}

void lcdWrite(LCD_WRITE_TYPE type, uint8_t value)
{
  CS_Switch(0);
  A0_Switch(type);
  writeToLcd(value);
  CS_Switch(1);
}

void LCD_Init(void)
{
  GPIO_InitTypeDef GPIO_Init;
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  
  GPIO_Init.Pin = LCD_CS_PIN | LCD_RST_PIN;
  GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_Init.Pull = GPIO_PULLUP;
  GPIO_Init.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LCD_CS_PORT, &GPIO_Init);
  
  GPIO_Init.Pin = LCD_A0_PIN;
  HAL_GPIO_Init(LCD_A0_PORT, &GPIO_Init);
  
  GPIO_Init.Pin = LCD_SCLK_PIN | LCD_SDA_PIN | LCD_BACKLIGHT_PIN;
  HAL_GPIO_Init(LCD_SCLK_PORT, &GPIO_Init);
  
  HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN | LCD_RST_PIN, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LCD_A0_PORT,  LCD_A0_PIN, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LCD_SCLK_PORT, LCD_SCLK_PIN | LCD_SDA_PIN | LCD_BACKLIGHT_PIN, GPIO_PIN_RESET);

  RST_Switch(0);      // 重置RESET
  bsp_delay_ms(10);
  RST_Switch(1);     // 恢复重置RESET
  bsp_delay_ms(10);

  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xe2);// System Reset
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2c);// Power Rise Step1
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2e);// Power Rise Step2
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x2f);// Power Rise Step3
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x23);

  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa2);// Bias 1/9
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xc0);// Set COM(row) Direction
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa1);// Set SEG(column) Direction
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x40);// Set Scroll Line: the first line
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xaf);// Display Enable
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xa4);// Display Enable
  
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x81);
  lcdWrite(LCD_WRITE_TYPE_COMMAND, 0x1f);
  
  LEDA_Switch(1); //  关闭背光
  clearScreen(); //  清屏
}

/**
*   设置地址
*   page 页地址
*   column 列地址
*/
void lcdSetAddress(uint8_t page,uint8_t column)
{
	lcdWrite(LCD_WRITE_TYPE_COMMAND, 0xb0 + page);   			      // 设置页地址。每页是8行。一个画面的64行被分成8个页。我们平常所说的第1页,在LCD驱动IC里是第0页,所以在这里减去1*/
	
  lcdWrite(LCD_WRITE_TYPE_COMMAND, ((column>>4)&0x0f) + 0x10);	// 设置列地址的高4位
	lcdWrite(LCD_WRITE_TYPE_COMMAND, column&0x0f);				      // 设置列地址的低4位
}

/*全屏清屏*/
void clearScreen(void)
{
	uint8_t i,j;
 	for(i = 0; i < 8; i++)
	{
		lcdSetAddress(i,0);
    
		for(j = 0;j < 132;j++)
		{
			lcdWrite(LCD_WRITE_TYPE_DATA, 0x00);
		}
	}
}

/**
* 显示16x16汉字字符
* page 页地址
* column 列地址
* reverse 反显
* *dp 字模数组
*/
void DisplayChinese16(uint8_t page,uint8_t column,uint8_t reverse,uint8_t *dp)
{
  uint8_t i,j,*data_temp;
  data_temp = dp;
  for(j = 0; j < 2;j++)
  {
    lcdSetAddress(page+j,column);
    for (i=0;i < 16;i++)
    {	
      reverse == 1? *data_temp = ~*data_temp : *data_temp;
      lcdWrite(LCD_WRITE_TYPE_DATA, *data_temp);
      data_temp++;
    }
  }
}


/**
* 显示多个16x16汉字字模
* page 页地址
* column 列地址
* reverse 反显
* *str 字符串
*/
void DisplayManyChinese16(uint8_t page,uint8_t column,uint8_t reverse, const char *str)
{
  char strl[20];      //  一个汉字占2个字节,一行最多有8个16x16的字符
  memcpy(strl, str, strlen(str));
  for(uint8_t len = 0, i = 0; len < strlen(strl); len += 2, i++)  //  strlen(strl)获取str1的字节数,假设有7个汉字字符,那么就有14个字节,i计算当前列地址
  {
    DisplayChinese16(page, column+(i*16), reverse, fontGetPoint(&strl[len]));
  }
}

void test(void)
{ 
    DisplayManyChinese16(0, 4, 0, "风急天高猿啸哀");
    DisplayManyChinese16(2, 4, 0, "渚清沙白鸟飞回"); 
    DisplayManyChinese16(4, 4, 0, "无边落木萧萧下"); 
    DisplayManyChinese16(6, 4, 0, "不尽长江滚滚来");
}

lcd.h文件
#ifndef _LCD_H
#define _LCD_H
#include "stdint.h"

void LCD_Init(void);

void clearScreen(void);

void test(void);

void testValue(uint8_t value);

typedef enum
{
  LCD_WRITE_TYPE_COMMAND = 0,
  LCD_WRITE_TYPE_DATA,
}LCD_WRITE_TYPE;

#endif 
#ifndef  _FONT16_H_
#define  _FONT16_H_
#include "stdint.h"

uint8_t * fontGetPoint(const char *str);


#endif





  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值