因手上有个LCD 1604, 在网上查了很久都是1602的资料,想请教前辈们,1604和1602的区别,不能那位大侠能给个1604的测试程序,基于AVR的。
以下是我在1602的基础上有改动,调试时程序会进入死循环,显示的效果是一和三行全亮,不知那位高人愿意救救小生,帮忙看看程序如何更改才能用,谢谢! winavr 编译器 325v的mcu , 1m内置振荡器
//头文件包含 #include <avr/io.h> //io端口寄存器配置文件,必须包含 #include <util/delay.h> //GCC中的延时函数头文件
//端口位定义 #define RS PA4 //数据/命令控制端 0命令,1数据 #define RW PA5 //读/写选择控制端 0写,1读 #define E PA6 //使能端 下降沿读,高电平写
//全局变量声明 unsigned char LCD_DispBuff1[]="Let's study AVR"; unsigned char LCD_DispBuff2[]=" WWW.LT430.COM"; unsigned char Disp_Number;
//函数声明 void Port_Init(void); //端口初始化 void LCD_Init(void); //LCD初始化 void Write_Com(unsigned char LCD_Com); //LCD写指令 void Write_Data(unsigned char LCD_Data); //LCD写数据 void Check_Busy(void); //读写检测函数,每次对液晶操作前都要进行读写检测
int main(void) { Port_Init(); //端口初始化 //LCD_Init(); //LCD初始化 //在任意位置处显示字符 //Write_Com(0X80+0X05); //发送字符显示位置指令。0x05可以换成00-0f,40-4f之间的任意值 //Write_Data('a'); //发送要显示的字符 //下面这段程序演示在LCD上显示两行字符 while (1) { Write_Com(0X80+0X00); for(Disp_Number = 0;Disp_Number < 15;Disp_Number++) { //Write_Data(LCD_DispBuff1[Disp_Number]); _delay_ms(5); } Write_Com(0X80+0X40); for(Disp_Number = 0;Disp_Number < 14;Disp_Number++) { //Write_Data(LCD_DispBuff2[Disp_Number]); _delay_ms(5); } } /* 下面这段程序演示在LCD上显示两行字符,字符从屏幕右边移动到屏幕左边 Write_Com(0X80+0X10); for(Disp_Number = 0;Disp_Number < 15;Disp_Number++) { Write_Data(LCD_DispBuff1[Disp_Number]); _delay_ms(5); } Write_Com(0X80+0X50); for(Disp_Number = 0;Disp_Number < 14;Disp_Number++) { Write_Data(LCD_DispBuff2[Disp_Number]); _delay_ms(5); } for(Disp_Number = 0;Disp_Number < 16;Disp_Number++) { Write_Com(0X18); _delay_ms(200); } */ /*while(1) { Write_Com(0X80+0X10); for(Disp_Number = 0;Disp_Number < 15;Disp_Number++) { Write_Data(LCD_DispBuff1[Disp_Number]); _delay_ms(5); } Write_Com(0X80+0X50); for(Disp_Number = 0;Disp_Number < 14;Disp_Number++) { Write_Data(LCD_DispBuff2[Disp_Number]); _delay_ms(5); } for(Disp_Number = 0;Disp_Number < 16;Disp_Number++) { Write_Com(0X18); _delay_ms(200); Write_Com(0X80+0X10); for(Disp_Number = 0;Disp_Number < 15;Disp_Number++) { Write_Data(LCD_DispBuff1[Disp_Number]); _delay_ms(5); } Write_Com(0X80+0X50); for(Disp_Number = 0;Disp_Number < 14;Disp_Number++) { Write_Data(LCD_DispBuff2[Disp_Number]); _delay_ms(5); } for(Disp_Number = 0;Disp_Number < 16;Disp_Number++) { Write_Com(0X18); _delay_ms(200); } }*/ }
void Port_Init() { //LCD数据端口设置 PORTB = 0X00; // DDRB = 0X0F; //配置端口PB全部为输出口,LCD数据端口 //LCD控制端口设置 PORTA = 0X00; // DDRA |= (1 << RS) | (1 << RW) | (1 << E); //DDRA |= (1 << RS) | (1 << RW) | (1 << E); //配置端口PA的第4、5、6为输出口 }
void LCD_Init() { Write_Com(0X01); //清屏 _delay_ms(5); Write_Com(0X38); //显示模式设置 16x2显示,5x7点阵,8位数据接口 _delay_ms(5); Write_Com(0X0f); //显示开关控制,开显示,光标显示,光标闪烁 Write_Com(0X0c); //显示开关控制,开显示,光标不显示,光标不闪烁 _delay_ms(5); Write_Com(0X06); //光标设置,读或写一个字符后,地址指针加一,光标加一,整屏不移动 _delay_ms(5); }
void Write_Com(unsigned char LCD_Com) { Check_Busy(); PORTA &= ~(1 << RS); //RS=0,写命令 PORTA &= ~(1 << RW); //RW=0,写指令 PORTA |= (1 << E); //E=1,写操作 _delay_ms(5); PORTB = LCD_Com; //指令送数据端口 PORTA &= ~(1 << E); //E=0,停止写操作 _delay_ms(5); }
void Write_Data(unsigned char LCD_Data) { //Check_Busy();
//PORTA |= (1 << RS); //RS=1,写数据 //PORTA &= ~(1 << RW); //RW=0,写指令 //PORTA |= (1 << E); //E=1,写操作 ////_delay_ms(5); //PORTB = LCD_Data; // 数据送数据端口 //PORTA &= ~(1 << E); //E=0,停止写操作 //_delay_ms(5); }
void Check_Busy() { DDRB = 0X00; //PB口置为输入口,准备读取数据 PORTA &= ~(1 << RS); //RS=0,读命令 PORTA |= (1 << RW); //RW=1,读指令 PORTA |= (1 << E); //E=1,使能 while(0X80 & PINB); //监测忙信号,直到忙信号为0,才能进行读写操作 PORTA &= ~(1 << E); //E=0 DDRB = 0XFF; //PB口置为输出口,准备向端口发送数据 }
|