液晶屏初始化

发布于 2024-08-31 20:01:47 字数 480 浏览 3 评论 0原文

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);

问:我在atmega32上使用过lcd。我已经注释了我所知道的命令。未注释的命令是什么意思?

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);

Q: i have used lcd with atmega32.I have commented the commands which i know.Whats the meaning of uncommented commands ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蛮可爱 2024-09-07 20:01:47

也许您应该查看 LCD 模块的数据表。它将向您显示它支持的命令集,或者至少为您提供在哪里可以找到该命令集的参考。

Perhaps you should look at the datasheet for your LCD module. It will show you the command set it supports or at least give you a reference on where you can find the command set.

怼怹恏 2024-09-07 20:01:47

这可能是 HD44780 兼容控制器(不幸的是我们不知道)
我认为 0x28 是功能集(4 位接口,2 行,5*7 像素)

0x03 命令是显示器初始化序列的一部分,然后是 20 毫秒的睡眠

this could be a HD44780 compatible controller (we dont know it, unfortunately)
i think 0x28 is Function set (4-bit interface, 2 lines, 5*7 Pixels)

the 0x03 commands are part of the initializing sequence of the display, followed by a sleep of 20 ms

胡大本事 2024-09-07 20:01:47

这里是一些注释良好的 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);
  }
//============================================================================

Here is some well-commented 4-bit LCD code, including the initialization code. It is not "AVR" C but if you port the macros over it should work OK.

For reference, the "original" HD44780 LCD controller data sheet is available here: http://crystalfontz.com/controllers/Hitachi/HD44780

(code from from 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);
  }
//============================================================================
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文