⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd12864.c

📁 用AVR单片机做的一些程序,包括跑马灯显示,PWM产生,ADC转换等
💻 C
字号:
/*
	LCD12864液晶屏驱动模块
	1、可直接嵌入到项目中使用
	2、晶振频率:1M
	3、如晶振提高低层驱动延时要作相应修改

	AVR_AFA
	www.iccavr.com
*/

#include <iom128v.h>
#include "font.h"

#define RS_CLR	PORTC &= ~(1 << PC2)		/*命令或数据选择*/
#define RS_SET	PORTC |= (1 << PC2)			/*RS = 1命令,RS = 0数据*/

#define RW_CLR	PORTC &= ~(1 << PC3)		/*读取或写入选择*/
#define RW_SET	PORTC |= (1 << PC3)			/*RW = 1读,RW = 0写*/

#define EN_CLR	PORTC &= ~(1 << PC4)		/*读写使能信号*/
#define EN_SET	PORTC |= (1 << PC4)			/*下降沿有效*/

#define RST_CLR	PORTC &= ~(1 << PC5)		/*芯片复位脚*/
#define RST_SET	PORTC |= (1 << PC5)			/*高电平复位*/

#define CSA_CLR	PORTC &= ~(1 << PC7)		/*左半屏片选*/
#define CSA_SET	PORTC |= (1 << PC7)			/*高电平选中*/

#define CSB_CLR	PORTC &= ~(1 << PC6)		/*右半屏片选*/
#define CSB_SET	PORTC |= (1 << PC6)			/*高电平选中*/

/*延时函数*/
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;
	PORTA = com;
	delay_us(1);
	EN_CLR;
}

/*显示屏命令写入函数后半屏*/
void LCD1_write_com(unsigned char com) {
	
	RS_CLR;
	RW_CLR;
	CSA_CLR;
	CSB_SET;
	EN_SET;
	PORTA = com;
	delay_us(1);
	EN_CLR;
}

/*显示屏命令写入函数*/
void LCD0_write_data(unsigned char data) {

	RS_SET;
	RW_CLR;
	CSA_SET;
	CSB_CLR;
	EN_SET;
	PORTA = data;
	delay_us(1);
	EN_CLR;
}

/*显示屏命令写入函数*/
void LCD1_write_data(unsigned char data) {

	RS_SET;
	RW_CLR;
	CSA_CLR;
	CSB_SET;
	EN_SET;
	PORTA = 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) {
	
	DDRA = 0xFF;						/*I/O口方向设置*/
	DDRC = 0xFF;

	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 + -