适用于AT89C51的LM4229驱动代码

关于本文

参考文献：

LM4229 Data sheet (1996/08/05)

T6963C Data sheet (1998/10/20)

环境：Proteus 模拟仿真

关于 LM4229

LM4229 是一个自带东芝 T6963C 驱动芯片的 LCD 显示屏，其中图形分辨率是 240 * 128

电路连接

引脚连接

LM4229 引脚 | 连接目标 | 说明
VSS | 接地 | 接地
VDD | 接 + 5V 电源 | 正电压电源
VO | 置空 | 对比度驱动电压
C/D | AT89C51 P2.2 (其中 D 为低电平可用) | 命令 / 数据切换
RD | AT89C51 P2.1 (其中 RD 为低电平可用) | 读取
WR | AT89C51 P2.0 (其中 WR 为低电平可用) | 写入
D0 ~ D7 | AT89C51 P1.0 ~ P1.7 | 数据线
CE | AT89C51 P2.3 (其中 CE 为低电平可用) | 芯片使能
RST | AT89C51 P2.4 (其中 RST 为低电平可用) | 复位
VEE | 置空 | 负电压电源
MD2 | AT89C51 P2.5 | 模式选择
FS1 | AT89C51 P2.6 | 字体选择
HALT | AT89C51 P2.7 | 停止

驱动代码

Copy
#include <reg51.h>

// define type abbreviation
#define uchar unsigned char
#define uint unsigned int
// define data port
#define DATAPORT P1

// define control pins
sbit halt = P2^7;
sbit fs1 = P2^6;
sbit md2 = P2^5;
sbit rst = P2^4;
sbit ce = P2^3;
sbit cd = P2^2;
sbit rd = P2^1;
sbit wr = P2^0;

// fonts
// method of obtaining: https://www.zhetao.com/fontarray.html
// parameter:
// 字节宽度: 8bit
// 字体高度: 16
// 字列: 2
// 字体: 宋体abc, 大小: 0（自动）
unsigned char code font[][16] = {
/*-- 0 --*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,},
/*-- 1 --*/
{0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,},
/*-- 2 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,},
/*-- 3 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00,},
/*-- 4 --*/
{0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00,},
/*-- 5 --*/
{0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00,},
/*-- 6 --*/
{0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00,},
/*-- 7 --*/
{0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00,},
/*-- 8 --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,},
/*-- 9 --*/
{0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00,},
/*-- space --*/
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
};

// delay function
void delay_lcd(uchar t) {
for (; t != 0; t--);
}

// write data to lcd display
void write_data(uchar dat) {
// The D of the C/D pin is available at low level, so CD = 0;
cd = 0;
// CE (Chip Enable) pin is available at low level, so CE = 0;
ce = 0;
// WR (Write) pin is available at low level, so WR = 0;
wr = 0;
// Send the data of dat to the data port;
DATA_PORT = dat;
delay_lcd(1);
// end write.
wr = 1; ce = 1;
}

// write command to lcd display
void write_cmd(uchar cmd) {
// The C of the C/D pin is available at high level, so CD = 1;
cd = 1;
// CE (Chip Enable) pin is available at low level, so CE = 0;
ce = 0;
// WR (Write) pin is available at low level, so WR = 0;
wr = 0;
// Send the command data of dat to the data port;
DATA_PORT = dat;
delay_lcd(1);
// end write.
wr = 1; ce = 1;
}

// show half-width characters
// x: line position
// y: column position
// flag: whether to display in reverse color
// ch: font index pointer (array)
// count: number of characters
void display_hw(uchar x, uchar y, int flag, uchar ch, int count) {
unsigned int place, i = 0, k;
// iterate over character array
for (i = 0; i < count; i++) {
// One character 8bit width, one line 240bit, 30 characters in total
// y: the vertical offset
place = x * 30 + y;
// half-width character contains 16 rows of 8-bit dot matrix
for (k = 0; k <= 15; k++) {
// write high address
write_data(place & 0xff);
// write low address
write_data(place >> 8);
// set address
write_cmd(0x24);
// Set continuous read and write
write_cmd(0xb0);
// Find the dot matrix data of the corresponding character in the font array according to the element index of ch
write_data(flag ? font[ch[i]][k] : ~font[ch[i]][k]);
place += 30;
}
// A line with more than 30 characters needs to be wrapped
if (y > 30) {
// One character 16bit height
x += 16;
y = 0;
} else {
// Continue write
y += 2;
}
}
}

// initial lcd display
void lcd_initial() {
// When FS1 is at low level, the font is 8*8, So fs1 = 0;
fs1 = 0;
// set graphics area
write_data(30);
write_data(0);
write_cmd(0x43);
// Turn off text display, turn on graphic display
write_cmd(0x98);
}

使用方法

Copy
void main(void) {
unsigned char c[1] = {1};
lcd_init();
while (1) {
display_hw(16, 0, 1, c, 1);
}
}