void lcdinit(void)
{
command1( 0x03 );
command1( 0x03 );
command1( 0x03 );
delay1(20);
command1( 0x02 ); //lcd home
delay1(10);
Command( 0x28 );
delay1(10);
Command( 0x08 ); //display of cursor off
delay1(10);
Command( 0x0C ); //display on and cursor off
delay1(10);
Command( 0x06 ); //shift cursor right
delay1(10);
Command( 0x01 ); //clear display screen
delay1(10);
问:我已经将lcd与atmega32一起使用了。我已经评论了我所知道的命令。这是未注释命令的含义吗?
答案 0 :(得分:0)
也许您应该查看LCD模块的数据表。它将显示它支持的命令集,或者至少为您提供有关命令集的位置的参考。
答案 1 :(得分:0)
这可能是HD44780兼容控制器(不幸的是我们不知道) 我认为0x28是功能集(4位接口,2行,5 * 7像素)
0x03命令是显示器初始化序列的一部分,然后是20 ms的休眠
答案 2 :(得分:0)
这是一些评论很好的4位LCD代码,包括初始化代码。它不是“AVR”C,但如果你将宏移植到它上面应该可以正常工作。
作为参考,“原始”HD44780 LCD控制器数据表可在此处获取:http://crystalfontz.com/controllers/Hitachi/HD44780
(来自https://forum.crystalfontz.com/showthread.php/6119的代码)
//============================================================================
typedef unsigned char ubyte;
typedef signed char sbyte;
typedef unsigned short word;
typedef unsigned long dword;
/============================================================================
//LCD Control line macros
#define SET_LCD_E \
{ \
/* fill out with your port access code */ \
}
#define CLEAR_LCD_E \
{ \
/* fill out with your port access code */ \
}
#define SET_LCD_RS \
{ \
/* fill out with your port access code */ \
}
#define CLEAR_LCD_RS \
{ \
/* fill out with your port access code */ \
}
#define SET_LCD_RW \
{ \
/* fill out with your port access code */ \
}
#define CLEAR_LCD_RW \
{ \
/* fill out with your port access code */ \
}
//Apply the high 4 bits of data to the low four bits of the port.
#define OUT_HIGH_NIBBLE (PRT1DR=(port1=(port1&0xF0)|(data>>4)))
//Apply the low 4 bits of data to the low four bits of the port.
#define OUT_LOW_NIBBLE (PRT1DR=(port1=(port1&0xF0)|(data&0x0F)))
//Read the high nibble of the data is on the low nibble of Port 1.
//Mask off the lower bits and store it.
#define IN_HIGH_NIBBLE (read_data=(PRT1DR&0x0F)<<4)
//Read the low nibble of the data is on the low nibble of Port 1.
#define IN_LOW_NIBBLE (read_data|=PRT1DR&0x0F)
#define SET_PORT1_FOR_LCD_WRITE \
{ \
/* fill out with your port access code */ \
}
#define SET_PORT1_FOR_LCD_READ \
{ \
/* fill out with your port access code */ \
}
#define PORT1_LCD_DATA_BUSY 0x08
//============================================================================
void Wait_For_Not_Busy(void)
{
uword
timeout;
//Poll the LCD's busy line until it is clear.
//Make register select 0
CLEAR_LCD_RS;
//Make R/W 1=read.
SET_LCD_RW;
//Change the data bits to inputs.
SET_PORT1_FOR_LCD_READ;
//Enable the controller's data onto the bus.
SET_LCD_E;
//Test the port's bit, wait for the bit to go low
if(PRT1DR&PORT1_LCD_DATA_BUSY)
for(timeout=1000;(PRT1DR&PORT1_LCD_DATA_BUSY)&&timeout;timeout--);
}
//============================================================================
ubyte Read_LCD_Address(void)
{
ubyte
read_data;
Wait_For_Not_Busy();
//Now the high nibble of the address is on the low nibble of Port 2.
//Mask off the busy bit and the upper bits and store it.
IN_HIGH_NIBBLE;
//Finish the high nibble clock cycle.
CLEAR_LCD_E;
//Strobe enable to clock in the low nibble--finishing the read.
SET_LCD_E;
//Now the low nibble of the address is on the low nibble of Port 2.
//Mask the upper bits and add it to the result.
IN_LOW_NIBBLE;
CLEAR_LCD_E;
//Turn the data bits back to their default output state.
SET_PORT1_FOR_LCD_WRITE;
return(read_data);
}
//============================================================================
void Write_LCD_Data(ubyte data)
{
Wait_For_Not_Busy();
//Finish the high nibble clock cycle.
CLEAR_LCD_E;
//Strobe enable to clock in the low nibble--finishing the read.
SET_LCD_E;
CLEAR_LCD_E;
//Turn the data bits back to their default output state.
SET_PORT1_FOR_LCD_WRITE;
//Make R/W 0=write.
CLEAR_LCD_RW;
//Make register select 1
SET_LCD_RS;
//Apply the high 4 bits of data to the low four bits of the port.
OUT_HIGH_NIBBLE;
//Strobe enable to clock in the high nibble.
SET_LCD_E;
CLEAR_LCD_E;
//Apply the low 4 bits of data to the low four bits of the port.
OUT_LOW_NIBBLE;
//Strobe enable to clock in the low nibble.
SET_LCD_E;
CLEAR_LCD_E;
}
//============================================================================
void Write_LCD_Control(ubyte data)
{
Wait_For_Not_Busy();
//Finish the high nibble clock cycle.
CLEAR_LCD_E;
//Strobe enable to clock in the low nibble--finishing the read.
SET_LCD_E;
CLEAR_LCD_E;
//Turn the data bits back to their default output state.
SET_PORT1_FOR_LCD_WRITE;
//Make R/W 0=write.
CLEAR_LCD_RW;
//Apply the high 4 bits of data to the low four bits of the port.
OUT_HIGH_NIBBLE;
//Strobe enable to clock in the high nibble.
SET_LCD_E;
CLEAR_LCD_E;
//Apply the low 4 bits of data to the low four bits of the port.
OUT_LOW_NIBBLE;
//Strobe enable to clock in the low nibble.
SET_LCD_E;
CLEAR_LCD_E;
}
//============================================================================
void Read_LCD_Data(ubyte length,ubyte address,ubyte *destination)
{
uword
timeout;
ubyte
read_data;
//First we need to write the address to the LCD.
//0x40 is first CGRAM
//0x80 is first DDRAM
Write_LCD_Control(address);
while(length--)
{
Wait_For_Not_Busy();
//Finish the high nibble clock cycle.
CLEAR_LCD_E;
//Strobe enable to clock in the low nibble--finishing the read.
SET_LCD_E;
CLEAR_LCD_E;
//Make register select 1, selecting the data instead of the address.
SET_LCD_RS;
//Enable the controller's data onto the bus.
SET_LCD_E;
//Now the high nibble of the data is on the low nibble of Port 2.
//Mask off the lower bits and store it.
IN_HIGH_NIBBLE;
//Finish the high nibble clock cycle.
CLEAR_LCD_E;
//Strobe enable to clock in the low nibble--finishing the read.
SET_LCD_E;
//Now the low nibble of the data is on the low nibble of Port 1.
IN_LOW_NIBBLE;
CLEAR_LCD_E;
//Store the data
*destination++=read_data;
}
//Turn the data bits back to their default output state.
SET_PORT1_FOR_LCD_WRITE;
}
//============================================================================
//does an "8-bit" write (as seen by the LCD)
void Blind_Write_LCD_Upper_Control_Nibble(ubyte data)
{
//Make R/W 0=write
CLEAR_LCD_RW;
//Make register select 0
CLEAR_LCD_RS;
//Apply the high 4 bits of data to the low four bits of the port.
OUT_HIGH_NIBBLE;
//Strobe enable to clock in the high nibble.
SET_LCD_E;
CLEAR_LCD_E;
}
//============================================================================
void LCD_Position_Cursor(ubyte x, ubyte y)
{
//Valid x is 0-15, valid y is 0-1
if((x<16)&&(y<2))
Write_LCD_Control(0x80|(y<<6)|x);
}
//============================================================================
//Could make this aware of display size & wrapping.
void LCD_puts(const char *input_string)
{
while(*input_string)
Write_LCD_Data(*input_string++);
}
//============================================================================
void LCD_put_dec_3(ubyte input)
{
ubyte
digit;
ubyte
no_blank;
digit=input/100;
if(digit)
{
Write_LCD_Data(digit+'0');
no_blank=1;
}
else
{
Write_LCD_Data(' ');
no_blank=0;
}
input%=100;
digit=input/10;
if(digit|no_blank)
Write_LCD_Data(digit+'0');
else
Write_LCD_Data(' ');
Write_LCD_Data(input%10+'0');
}
//============================================================================
void LCD_Initialize(void)
{
ubyte
i;
ubyte
j;
SET_PORT1_FOR_LCD_WRITE;
//This sequence is from the initialization on page 46 of the HD44780U
//data sheet.
delay_mS(40);
Blind_Write_LCD_Upper_Control_Nibble(0x30);
//Yes, the data sheet says write it twice.
delay_mS(5);
Blind_Write_LCD_Upper_Control_Nibble(0x30);
//Yes, the data sheet says write it three times.
delay_mS(1);
Blind_Write_LCD_Upper_Control_Nibble(0x30);
//Yes, the data sheet says write it four times, but at least this one counts.
//020h is Function set:
//4 bit,
//2 line
//F = (5x8)
delay_mS(1);
//This is last 8-bit write, which is an instruction to put the LCD into 4-bit mode.
Blind_Write_LCD_Upper_Control_Nibble(0x20);
//Here is the 4-bit instruction to set the font and number of lines.
Write_LCD_Control(0x28);
//"Display off"
Write_LCD_Control(0x08);
//"Display clear"
Write_LCD_Control(0x01);
//This delay is needed for at least one version of the Sitronix
//ST7066 Controller. No reasonable explanation, I found it
//empirically.
delay_mS(2);
//006h is Entry mode set, increment, no shift
Write_LCD_Control(0x06);
//Display on, cursor on, blinking
Write_LCD_Control(Cursor_Style=0x0F);
//Clear the display again. This seems to fix a power-up problem
//where the display shows "{{{{{" in a couple of places.
Write_LCD_Control(0x01);
//Why is this needed? Apparently not needed on the 635.
//delay_mS(2);
}
//============================================================================