|
以前都CodeVision自带的LCD库,下午花两个小时自己写了一个LCD1602的程序,遇到些问题想请教你。
程序如下:
#include<mega64.h>
#include<delay.h>
//////////////////////LCD1602硬件接口//////////////////////////////
#define SET_BIT(port,a) port |= 1<<a //置I/O口PORT A位为1
#define CLI_BIT(port,b) port &= (~(1<<b)) //清I/O口PORT B位
#define LCD_RS 0
#define SET_LCD_RS() SET_BIT(PORTA,LCD_RS)
#define CLI_LCD_RS() CLI_BIT(PORTA,LCD_RS)
#define LCD_RW 1
#define SET_LCD_RW() SET_BIT(PORTA,LCD_RW)
#define CLI_LCD_RW() CLI_BIT(PORTA,LCD_RW)
#define LCD_EN 2
#define SET_LCD_EN() SET_BIT(PORTA,LCD_EN)
#define CLI_LCD_EN() CLI_BIT(PORTA,LCD_EN)
#define LCD_DATA_PORT PORTA //the next three port should be the same
#define LCD_DATA_DDR DDRA //must use the high 4bit
#define LCD_DATA_PIN PINA
#define LCD_DATA 0xf0 //DATA PORT
/*
#define LCD_RS PORTA.0 //RS lcd
#define LCD_WR PORTA.1//WR lcd
#define LCD_EN PORTA.2 //EN lcd */
/////////////////LCD1602指令集定义////////////////////////////////
#define LCD_CLEAR 0x01 ///< Clear display
#define LCD_HOME 0x02 ///< Display and cursor home
#define LCD_ENTRY_CURSOR_INC 0x06 ///< Cursor move direction increment
#define LCD_ENTRY_CURSOR_DEC 0x04 ///< Cursor move direction decrement
#define LCD_ENTRY_DISP_SHIFT_ON 0x05 ///< Display shift on
#define LCD_ENTRY_DISP_SHIFT_OFF 0x04 ///< Display shift off
#define LCD_DISP_DISP_ON 0x0C ///< Display on
#define LCD_DISP_DISP_OFF 0x08 ///< Display off
#define LCD_DISP_CURSOR_ON 0x0A ///< Cursor on
#define LCD_DISP_CURSOR_OFF 0x08 ///< Cursor off
#define LCD_DISP_BLINK_ON 0x09 ///< Blinking on
#define LCD_DISP_BLINK_OFF 0x08 ///< Blinking off
#define LCD_SHIFT_DISP_LEFT 0x18 ///< Shift display left
#define LCD_SHIFT_DISP_RIGHT 0x1C ///< Shift display right
#define LCD_SHIFT_CURSOR_LEFT 0x10 ///< Shift cursor left
#define LCD_SHIFT_CURSOR_RIGHT 0x14 ///< Shift cursor right
#define LCD_MODE_BIT_8 0x38 ///< 8-bit interface data 2-line display
#define LCD_MODE_BIT_4 0x28 ///< 4-bit interface data 2-line display
void LCD_en_write(void) //enable LCD
{
SET_LCD_EN();//EN=1
delay_us(10);
CLI_LCD_EN();//EN=0
}
void LCD_WriteCommand(unsigned char data) //write data
{
delay_us(50); //标注3
CLI_LCD_RS();//RS=0,write command
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=data&0xf0; //wirte high 4bit
LCD_en_write();
data=data<<4; //turn the low 4bit to high 4bit
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=data&0xf0; //write low 4bit
LCD_en_write();
}
void LCD_WriteData(unsigned char data) //write data
{
delay_us(50); //标注4
SET_LCD_RS();//RS=1,write data
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=data&0xf0; //wirte high 4bit
LCD_en_write();
data=data<<4; //turn the low 4bit to high 4bit
LCD_DATA_PORT&=0X0f; //clr high 4bit
LCD_DATA_PORT|=data&0xf0; //write low 4bit
LCD_en_write();
}
void LCD_init(void) //lcd init
{
LCD_DATA_DDR=0xff;
LCD_DATA_PORT = 0; //PORTA 方向为输出
CLI_LCD_RW(); //LCD只写
//delay_ms(10);
// LCD_WriteCommand(LCD_MODE_BIT_4); //4bit show
// delay_ms(15);
LCD_WriteCommand(LCD_MODE_BIT_4); //4bit show
delay_ms(1);
LCD_WriteCommand(LCD_DISP_DISP_ON); //do now show cursor
LCD_WriteCommand(0x80);
delay_ms(1);
LCD_WriteCommand(LCD_CLEAR); //clr
delay_ms(2);
LCD_WriteCommand(LCD_ENTRY_CURSOR_INC);
}
//orientation a dress
//x:0 or 1
//y:0-15
void LCD_set_xy( unsigned char x, unsigned char y ) //write address funcation
{
unsigned char address;
if (y==0) address=0x80+x;
else address=0xc0+x;
LCD_WriteCommand(address);
}
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char flash *s)
{
LCD_set_xy(X,Y); //write address
while (*s) // write the char to show
{
LCD_WriteData(*s);
s++;
}
}
void LCD_clear()
{
LCD_WriteCommand(0x01);
// delay_us(50);
}
void main(void)
{
// Declare your local variables here
//init();
LCD_init(); /////////////////////
//write_flash_string(1,2,"Resetting....","Laser Show");
////////////////////////上电后从EEPROM中读出地址、工作模式、速度等级、X/Y停转状态及位置参数///////////////////
/*dmx_address = address_eep;
master_slave = master_slave_eep;
x_speed_rate = x_speed_rate_eep;
y_speed_rate = y_speed_rate_eep;
x_run_state = x_run_state_eep;
y_run_state = y_run_state_eep;
color = color_eep;
show_mode=show_mode_eep;
x_position_data = x_position_data_eep;
y_position_data = y_position_data_eep;
dmx_slave = dmx_slave_eep;
add[0] = dmx_address/100 + '0';
add[1] = (dmx_address/10)%10 + '0';
add[2] = dmx_address%10 + '0';
if(master_slave == MASTER_MODE)
{
RXD_TXD_UART0 = 1;
master_work_mode = work_mode_eep;
}
else if(master_slave == SLAVE_MODE)
{
RXD_TXD_UART0 = 0;
if(dmx_slave==SLAVE)
{
uart0_slave_recv_flag=0;
EIMSK &= ~(1<<INT0);
}
}
//TIMSK&=~(1<<TOIE1);
//ETIMSK&=~(1<<TOIE3);
reset_function(); // Global enable interrupts
//x_count=0;
//y_count=0;
//x_current_back=0;
//y_current_back=0;
//TIMSK|=(1<<TOIE1);
//ETIMSK|=1<<TOIE3;*/
#asm("sei")
LCD_clear();
LCD_write_string(0,0,"this lcd test");
LCD_write_string(0,1,"test OK!"); //////标注1
delay_ms(2000);
LCD_clear(); ///标注2
LCD_write_string(0,1,"this lcd test");
LCD_write_string(0,0,"test OK!");
while (1)
{
/////////////////////Place your flash here//////////////////////////
if(key_flag) //表示有键按下。
{
key_flag=0;
LCD_clear();
LCD_write_string(0,6,"write");
// delay_ms(100); //标注5
LCD_write_string(0,1,"Welcome to use");
// get_menu();
}
/* get_maxspeed_position();
x_motor_control();
y_motor_control();
animal_play();
if(master_slave==MASTER_MODE)
uart0_send_data();
uart1_send_data();
};*/
//
}
问题描述:
程序运行至标注1,LCD1602显示正常,但延时2S,清屏后运行标注2时,LCD1602为空白,白屏不显示,这是什么原因所致?谢谢!
调试过程中,改变LCD初始化中延时时间长短,会发现运行标注1的时候就会出乱码现像或者白屏不显示,改变标注3、标注4的延时时间,现像与改变LCD初始化中延时时间长短一样。
在主程序WHILE{}中,任意按键按下时(按键程序没有帖出),如果不加标注5 的延时,现像同样是白屏不显示,而加入标注5的延时后,只是在第LCD1602第二行显示Welcome to use,第一行还是白屏不显示,而不是我想要显示的write。
请傻孩子及各位高手们分析下。
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|