手上刚好有一块JLX12864的点阵屏,刚好用来评估GD32F427,趁着晚上有空,移植了一下JLX12864的程序,代码片段如下:
#include "bsp_lcd.h"
#include "gd32f4xx.h"
#include "systick.h"
#define RESET_PIN GPIO_PIN_3
#define CS_PIN GPIO_PIN_6
#define RS_PIN GPIO_PIN_1
#define SCK_PIN GPIO_PIN_7
#define SDA_PIN GPIO_PIN_9
//液晶1个像素占1个bit,即1个字节含8个像素,在显存中的位置位于同一列,从上到下依次从BIT0~BIT7
//液晶水平共192列, 8页, 即1页为8行
#define BSP_LCD_DELAY_MS(n) delay_1ms(n)
#define BSP_LCD_RESET_CTRL(n) gpio_bit_write(GPIOE, RESET_PIN, (bit_status)n)
#define BSP_LCD_CS(n) gpio_bit_write(GPIOE, CS_PIN, (bit_status)n)
#define BSP_LCD_RS(n) gpio_bit_write(GPIOE, RS_PIN, (bit_status)n)
#define BSP_LCD_SCK(n) gpio_bit_write(GPIOB, SCK_PIN, (bit_status)n)
#define BSP_LCD_SDA(n) gpio_bit_write(GPIOB, SDA_PIN, (bit_status)n)
static void bsp_lcd_reset(void)
{
BSP_LCD_RESET_CTRL(0);
BSP_LCD_DELAY_MS(100);
BSP_LCD_RESET_CTRL(1);
BSP_LCD_DELAY_MS(100);
}
static void bsp_lcd_write_reg(uint8_t reg)
{
uint8_t i;
BSP_LCD_CS(0);
BSP_LCD_RS(0);
for(i = 0; i < 8; i++)
{
BSP_LCD_SCK(0);
if(reg & 0x80) //MSB
{
BSP_LCD_SDA(1);
}
else
{
BSP_LCD_SDA(0);
}
BSP_LCD_SCK(1);
reg <<= 1; //MSB
}
BSP_LCD_CS(1);
}
static void bsp_lcd_write_data(uint8_t dat)
{
uint8_t i;
BSP_LCD_CS(0);
BSP_LCD_RS(1);
for(i = 0; i < 8; i++)
{
BSP_LCD_SCK(0);
if(dat & 0x80) //MSB
{
BSP_LCD_SDA(1);
}
else
{
BSP_LCD_SDA(0);
}
BSP_LCD_SCK(1);
dat <<= 1; //MSB
}
BSP_LCD_CS(1);
}
//设置LCD页和起始列(8行为1页)
static void bsp_lcd_address(uint8_t page, uint8_t column)
{
bsp_lcd_write_reg(0xb0 + (page & 0x0f)); //设置页地址。每页是8行。一个画面的64 行被分成8 个页。
bsp_lcd_write_reg((column >> 4) + 0x10); //设置列地址的高4 位
bsp_lcd_write_reg(column & 0x0f); //设置列地址的低4 位
}
//显示 8x16 点阵图像、ASCII, 或8x16 点阵的自造字符、其他图标
void bsp_lcd_disp_graph_8x16(uint8_t page, uint8_t column, const uint8_t *dp)
{
uint8_t i, j;
for(j = 0; j < 2; j++)
{
bsp_lcd_address(page + j, column);
for (i = 0; i < 8; i++)
{
bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
dp++;
}
}
}
//显示16x16 点阵图像、汉字、生僻字或16x16 点阵的其他图标
void bsp_lcd_disp_graph_16x16(uint8_t page, uint8_t column, const uint8_t *dp)
{
uint8_t i, j;
for(j = 0; j < (16 >> 3); j++)
{
bsp_lcd_address(page + j, column);
for (i = 0; i < 16; i++)
{
bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
dp++;
}
}
}
//显示24x48 点阵图像、汉字、生僻字或24x48 点阵的其他图标
void bsp_lcd_disp_graph_24x48(uint8_t page, uint8_t column, const uint8_t *dp)
{
uint8_t i, j;
for(j = 0; j < (48 >> 3); j++)
{
bsp_lcd_address(page + j, column);
for (i = 0; i < 24; i++)
{
bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
dp++;
}
}
}
//void bsp_lcd_disp_graph_128x64(const uint8_t *dp)
//{
// uint8_t i, j;
// for(i = 0; i < LCD_PAGES; i++)
// {
// bsp_lcd_address(i, 0);
// for(j = 0; j < LCD_COLS; j++)
// {
// bsp_lcd_write_data(*dp);
// dp++;
// }
// }
//}
//显示32x32 点阵图像、汉字、生僻字或32x32 点阵的其他图标
//void bsp_lcd_disp_graph_32x32(uint8_t page, uint8_t column, const uint8_t *dp)
//{
// uint8_t i, j;
// for(j = 0; j < (32 >> 3); j++)
// {
// bsp_lcd_address(page + j, column);
// for (i = 0; i < 32; i++)
// {
// bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
// dp++;
// }
// }
//}
//显示48x48 点阵图像、汉字、生僻字或48x48 点阵的其他图标
void bsp_lcd_disp_graph_48x48(uint8_t page, uint8_t column, const uint8_t *dp)
{
uint8_t i, j;
for(j = 0; j < (48 >> 3); j++)
{
bsp_lcd_address(page + j, column);
for (i = 0; i < 48; i++)
{
bsp_lcd_write_data(*dp); //写数据到LCD,每写完一个8 位的数据后列地址自动加1
dp++;
}
}
}
void bsp_lcd_init(void)
{
gpio_bit_reset(GPIOB, SCK_PIN);
gpio_bit_reset(GPIOB, SDA_PIN);
gpio_bit_reset(GPIOE, RS_PIN);
gpio_bit_set(GPIOE, RESET_PIN);
gpio_bit_set(GPIOE, CS_PIN);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCK_PIN);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SDA_PIN);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS_PIN);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RESET_PIN);
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, CS_PIN);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCK_PIN);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SDA_PIN);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS_PIN);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RESET_PIN);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, CS_PIN);
bsp_lcd_reset();
bsp_lcd_write_reg(0xe2); //软复位
BSP_LCD_DELAY_MS(5);
bsp_lcd_write_reg(0x2c); //升压步骤1
BSP_LCD_DELAY_MS(50);
bsp_lcd_write_reg(0x2e); //升压步骤2
BSP_LCD_DELAY_MS(50);
bsp_lcd_write_reg(0x2f); //升压步骤3
BSP_LCD_DELAY_MS(5);
bsp_lcd_write_reg(0x23); //粗调对比度,可设置范围0x20~0x27
bsp_lcd_write_reg(0x81); //微调对比度
bsp_lcd_write_reg(0x28); //微调对比度的值,可设置范围0x00~0x3f
bsp_lcd_write_reg(0xa2); //1/9 偏压比(bias)
bsp_lcd_write_reg(0xc8); //行扫描顺序:从上到下
bsp_lcd_write_reg(0xa0); //列扫描顺序:从左到右
bsp_lcd_write_reg(0x40); //起始行:第一行开始
bsp_lcd_clear(0x00);
bsp_lcd_write_reg(0xaf); //开显示
}
//全屏清屏
void bsp_lcd_clear(uint8_t color)
{
uint8_t i, j;
for(i = 0; i < LCD_PAGES; i++)
{
bsp_lcd_address(i, 0);
for(j = 0;j < LCD_COLS; j++)
{
bsp_lcd_write_data(color);
}
}
}
void bsp_lcd_draw_rect(uint8_t page_start, uint8_t col, uint8_t pages, uint8_t cols)
{
uint8_t i, j;
if(pages == 0 || cols == 0)
{
return;
}
if(pages == 1)
{
bsp_lcd_address(page_start, col);
bsp_lcd_write_data(0xff);//首列
for(j = col + 1; j < col + cols - 1; j++)//中间列
{
bsp_lcd_write_data(0x81);
}
if(cols > 1)//尾列
{
bsp_lcd_write_data(0xff);
}
}
else
{
//首行
bsp_lcd_address(page_start, col);
bsp_lcd_write_data(0xff);//首列
for(j = col + 1; j < col + cols - 1; j++)//中间列
{
bsp_lcd_write_data(0x01);
}
if(cols > 1)//尾列
{
bsp_lcd_write_data(0xff);
}
//中间行
for(i = page_start + 1; i < page_start + pages - 1; i++)
{
bsp_lcd_address(i, col);
bsp_lcd_write_data(0xff);//首列
for(j = col + 1; j < col + cols - 1; j++)//中间列
{
bsp_lcd_write_data(0x00);
}
if(cols > 1)//尾列
{
bsp_lcd_write_data(0xff);
}
}
//尾行
if(pages > 1)
{
bsp_lcd_address(page_start + pages - 1, col);
bsp_lcd_write_data(0xff);//首列
for(j = col + 1; j < col + cols - 1; j++)//中间列
{
bsp_lcd_write_data(0x80);
}
if(cols > 1)//尾列
{
bsp_lcd_write_data(0xff);
}
}
}
}
uint8_t word_tab[][32] = {
{0x00,0x80,0x60,0xF8,0x07,0x40,0x20,0x18,0x0F,0x08,0xC8,0x08,0x08,0x28,0x18,0x00,
0x01,0x00,0x00,0xFF,0x00,0x10,0x0C,0x03,0x40,0x80,0x7F,0x00,0x01,0x06,0x18,0x00},/*"你",0*/
{0x10,0x10,0xF0,0x1F,0x10,0xF0,0x00,0x80,0x82,0x82,0xE2,0x92,0x8A,0x86,0x80,0x00,
0x40,0x22,0x15,0x08,0x16,0x61,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00},/*"好",1*/
};
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* configure systick */
systick_config();
/* enable the LEDs GPIO clock */
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOE);
/* reset LED2 GPIO pin */
gpio_bit_reset(GPIOC, GPIO_PIN_6);
bsp_lcd_init();
bsp_lcd_draw_rect(0, 0, 8, 128);
bsp_lcd_disp_graph_16x16(1, 1, word_tab[0]);
bsp_lcd_disp_graph_16x16(1, 17, word_tab[1]);
while(1) {
delay_1ms(1000);
}
}
上述代码的逻辑很简单,首先初始化LCD,然后画一个128*64的矩形,最后在屏幕中显示你好中文,详细效果如下
其中有关点阵汉字使用的是16X16的点阵,点阵数据是自己产生的,JLX12864像素点整的排列规则如下:
我们使用的是PCtoLCD2002.exe这款软件
首先配置点阵排列规则,如下图所示,注意选择C51格式
然后输入要生成点阵数据的汉字,点击生成字模,就可以生成对应的点阵数据了
好了,以上就是如何使用GD32驱动JLX12864的视频,除了显示文字,还可以显示点阵图片,原理都是相同的,欢迎感兴趣的小伙伴与我交流分享。