📄 lcd12864.c
字号:
/*
LCD12864液晶屏驱动模块
1、可直接嵌入到项目中使用
2、晶振频率:1M
3、如晶振提高低层驱动延时要作相应修改
AVR_AFA
www.iccavr.com
*/
#include <iom16v.h>
#include "font.h"
#define RS_CLR PORTD &= ~(1 << PD3)/*命令或数据选择*/
#define RS_SET PORTD |= (1 << PD3)/*RS = 1命令,RS = 0数据*/
#define RW_CLR PORTD &= ~(1 << PD4)/*读取或写入选择*/
#define RW_SET PORTD |= (1 << PD4)/*RW = 1读,RW = 0写*/
#define EN_CLR PORTD &= ~(1 << PD6)/*读写使能信号*/
#define EN_SET PORTD |= (1 << PD6)/*下降沿有效*/
#define RST_CLR PORTD &= ~(1 << PD7)/*芯片复位脚*/
#define RST_SET PORTD |= (1 << PD7)/*高电平复位*/
#define CSA_CLR PORTC &= ~(1 << PC6)/*左半屏片选*/
#define CSA_SET PORTC |= (1 << PC6)/*高电平选中*/
#define CSB_CLR PORTC &= ~(1 << PC7)/*右半屏片选*/
#define CSB_SET PORTC |= (1 << PC7)/*高电平选中*/
/*延时函数*/
void delay_us(unsigned int n) {
if (n == 0) {
return ;
}
while (--n);
}
/*延时函数*/
void delay_ms(unsigned char i) {
unsigned char a, b;
for (a = 1; a < i; a++) {
for (b = 1; b; b++) {
;
}
}
}
/*显示屏命令写入函数前半屏*/
void LCD0_write_com(unsigned char com) {
RS_CLR;
RW_CLR;
CSA_SET;
CSB_CLR;
EN_SET;
PORTB = com;
delay_us(1);
EN_CLR;
}
/*显示屏命令写入函数后半屏*/
void LCD1_write_com(unsigned char com) {
RS_CLR;
RW_CLR;
CSA_CLR;
CSB_SET;
EN_SET;
PORTB = com;
delay_us(1);
EN_CLR;
}
/*显示屏命令写入函数*/
void LCD0_write_data(unsigned char data) {
RS_SET;
RW_CLR;
CSA_SET;
CSB_CLR;
EN_SET;
PORTB = data;
delay_us(1);
EN_CLR;
}
/*显示屏命令写入函数*/
void LCD1_write_data(unsigned char data) {
RS_SET;
RW_CLR;
CSA_CLR;
CSB_SET;
EN_SET;
PORTB = data;
delay_us(1);
EN_CLR;
}
/*显示屏清空显示*/
void disp_clear(unsigned char x0, unsigned char x1, unsigned char y) {
unsigned char x;
/*清除高位*/
x = x0;
if (x < 63) { /*地址在左半屏范围内*/
LCD0_write_com(y | 0xB8);
LCD0_write_com(x | 0x40);
}
while (x < x1) {
LCD0_write_data(0x00);
x ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
if (x < x1) { /*地址进入左半屏范围*/
LCD1_write_com(y | 0xB8);
LCD1_write_com(x | 0x40);
}
while (x < x1) {
LCD1_write_data(0x00);
x ++;
}
/*清除低位*/
x = x0;
if (x < 63) { /*地址在左半屏范围内*/
LCD0_write_com((y+1) | 0xB8);
LCD0_write_com(x | 0x40);
}
while (x < x1) {
LCD0_write_data(0x00);
x ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
if (x < x1) { /*地址进入左半屏范围*/
LCD1_write_com((y+1) | 0xB8);
LCD1_write_com(x | 0x40);
}
while (x < x1) {
LCD1_write_data(0x00);
x ++;
}
}
/*在指定位置显示一个ASCII 字符*/
void disp_char(unsigned char x, unsigned char y, unsigned char ascii) {
unsigned char i = 0x00;
const unsigned char *q; /*取字库指针*/
ascii -= 0x20;
q = &ENGLISH_FONT[ascii * 16];/*定位指针地址*/
/*显示高8位*/
i = 0x00;
if (x < 64) { /*地址在左半屏范围内*/
LCD0_write_com(y | 0xB8);
LCD0_write_com(x | 0x40);
while (i < 8) {
LCD0_write_data(*q);
q ++;
x ++;
i ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
}
if (i < 8) { /*地址进入左半屏范围*/
LCD1_write_com(y | 0xB8);
LCD1_write_com(x | 0x40);
while (i < 8) {
LCD1_write_data(*q);
q ++;
x ++;
i ++;
}
}
/*显示低8位*/
i = 0x00;
x -= 8;
if (x < 64) { /*地址在左半屏范围内*/
LCD0_write_com((y+1) | 0xB8);
LCD0_write_com(x | 0x40);
while (i < 8) {
LCD0_write_data(*q);
q ++;
x ++;
i ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
}
if (i < 8) { /*地址进入左半屏范围*/
LCD1_write_com((y+1) | 0xB8);
LCD1_write_com(x | 0x40);
while (i < 8) {
LCD1_write_data(*q);
q ++;
x ++;
i ++;
}
}
CSA_CLR;
CSB_CLR;
}
/*在指定位置显示一个汉字*/
void disp_word(unsigned char x, unsigned char y, unsigned char word) {
unsigned char i = 0x00;
const unsigned char *q; /*取字库指针*/
q = &CHINESE_FONT[word * 32];/*定位指针地址*/
/*显示高16位*/
i = 0x00;
if (x < 64) { /*地址在左半屏范围内*/
LCD0_write_com(y | 0xB8);
LCD0_write_com(x | 0x40);
while (i < 16) {
LCD0_write_data(*q);
q ++;
x ++;
i ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
}
if (i < 16) { /*地址进入左半屏范围*/
LCD1_write_com(y | 0xB8);
LCD1_write_com(x | 0x40);
while (i < 16) {
LCD1_write_data(*q);
q ++;
x ++;
i ++;
}
}
/*显示低16位*/
i = 0x00;
x -= 16;
if (x < 64) { /*地址在左半屏范围内*/
LCD0_write_com((y+1) | 0xB8);
LCD0_write_com(x | 0x40);
while (i < 16) {
LCD0_write_data(*q);
q ++;
x ++;
i ++;
if (x > 63) { /*判断地址是否越界*/
break;
}
}
}
if (i < 16) { /*地址进入左半屏范围*/
LCD1_write_com((y+1) | 0xB8);
LCD1_write_com(x | 0x40);
while (i < 16) {
LCD1_write_data(*q);
q ++;
x ++;
i ++;
}
}
CSA_CLR;
CSB_CLR;
}
/*显示一串字符*/
void disp_char_str(unsigned char x, unsigned char y, unsigned char *str) {
while (*str != 0) {
disp_char(x, y, *str);
x += 8;
str ++;
}
}
/*显示屏初始化函数*/
void disp_init(void) {
DDRB = 0xFF; /*I/O口方向设置*/
DDRC |= (1 << PC6) | (1 << PC7);
DDRD |= (1 << PD3) | (1 << PD4) | (1 << PD6) | (1 << PD7);
RST_CLR;
delay_ms(10);
RST_SET;
LCD0_write_com(0xC0); /*显示起行设置*/
LCD1_write_com(0xC0);
LCD0_write_com(0x3F); /*开显示设置*/
LCD1_write_com(0x3F);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -