带 Atmega32 的 4 位 4x20 LCD
Posted
技术标签:
【中文标题】带 Atmega32 的 4 位 4x20 LCD【英文标题】:4 bit 4x20 LCD with Atmega32 【发布时间】:2013-01-04 23:30:12 【问题描述】:我的 4x20 LCD 显示器出现问题。 过去几天我一直在查看大量指南和代码 sn-ps,但似乎没有任何帮助。 问题是显示器什么也没有显示。
当我在我的计算机上编译它并在我的屏幕上打印它时,一切似乎都很好。
如果有人能仔细查看是否有任何明显的错误,我将不胜感激。
提前致谢。
// Connection:
//
// Atmega32 LCD
// PB0 -> DB4
// PB1 -> DB5
// PB2 -> DB6
// PB3 -> DB7
// PB4 -> RS
// PB5 -> R/W
// PB6 -> E
// PB7 ->
#include <avr/io.h>
#include <util/delay.h>
#define LCDPort PORTB
#define LCDDDR DDRB
#define enable 6 //Enable = on
#define readWrite 5 //Read = on, Write = off
#define RS 4 //Send command = off, send data = on
void checkBusy(void);
void updateLCD(void);
void sendCommand(unsigned char command);
void sendData(unsigned char character);
void sendInitCommand(unsigned char command);
int main(void)
LCDDDR |= 15;
LCDDDR |= 1 << enable; //Set control lines as output (high)
LCDDDR |= 1 << readWrite;
LCDDDR |= 1 << RS;
_delay_ms(100); //Wait for LCD to boot
sendInitCommand(0x3); //Init function set 1
_delay_ms(100);
sendInitCommand(0x3); //Init function set 2
_delay_us(100);
sendInitCommand(0x3); //Init function set 3
_delay_us(100);
sendInitCommand(0x2); //Function set (set 4 bit mode)
_delay_us(100);
sendInitCommand(0x28); //Funcion set I=1, N=0, F=0
//sendInitCommand(0x8);
_delay_us(60);
sendInitCommand(0x8); //On/off control D=0, C=0, B=0
//sendInitCommand(0x8);
_delay_us(60);
sendCommand(0x01); //Clear display
//sendInitCommand(0x1);
_delay_ms(60);
sendCommand(0x06); //Entry mode set I/D=1, S=0
//sendInitCommand(0x6);
_delay_us(60);
sendCommand(0x0C); //On/off control D=1, C=0, B=0
//sendInitCommand(0xC);
_delay_us(60);
sendData(0x41); //Display "A"
sendData(0x42); //Display "B"
sendData(0x43); //Display "C"
sendData(0x44); //Display "D"
sendData(0x45); //Display "E"
while(1)
return 0;
void checkBusy()
LCDDDR &= ~15; //Set data DDR lines read (low)
/* LCDPort |= 1 << readWrite; //Forget read for now - use delay instead
LCDPort &= ~1 << RS;
while((LCDPort & 15) >= 0x8)
updateLCD();
*/
_delay_ms(50);
LCDDDR |= 15; //Set data lines DDR to write (high)
void updateLCD()
LCDPort |= 1 << enable; //Enable
asm volatile ("nop");
asm volatile ("nop");
LCDPort &= ~1 << enable; //Disable
void sendCommand(unsigned char command)
checkBusy();
LCDPort &= ~(1 << readWrite | 1 << RS); //Set R/W and RS low (write command)
LCDPort |= (command >> 4) & 15; //Send 4 ms bits
updateLCD();
LCDPort &= ~15;
LCDPort |= command & 15; //Send 4 ls bits
updateLCD();
LCDPort &= ~15; //Clear data lines
void sendData(unsigned char character)
checkBusy();
LCDPort &= ~1 << readWrite; //Set R/W low and RS high (write data)
LCDPort |= 1 << RS;
LCDPort |= (character >> 4 & 15); //Send 4 ms bits
updateLCD();
LCDPort &= ~1 << readWrite;
LCDPort &= ~15;
LCDPort |= 1 << RS;
LCDPort |= (character & 15); //Send 4 ls bits
updateLCD();
LCDPort &= ~15; //Clear data lines
void sendInitCommand(unsigned char command)
LCDPort &= ~(1 << readWrite | 1 << RS); //Set R/W and RS low (write command)
LCDPort |= command & 15;
updateLCD();
LCDPort &= ~15; //Clear data lines
【问题讨论】:
是时候打破范围了... 显示器是什么型号或芯片组?你有它的规格表的链接吗? 我是从一个朋友那里得到的,他让它在 4 位模式下工作。我能找到的唯一数据表是:powertipusa.com/pdf/pc2004a.pdf 迟来的更新:上面的代码确实有效。是显示器坏了。我得到了一个新的,并用我的代码对其进行了测试。 【参考方案1】:看来这是一个兼容 HD44780 的控制器。
请注意,每个 4x20 显示器实际上是一个 2x40,中间被切割。这可以通过一个显示控制器来实现,但显示需要多个驱动程序。 看看这个:
不过,您可以在 4 位模式下连接显示器。
以下是如何在位模式下连接 4x20 的示例 (请注意,Pin15 (LED+) 和 Pin16 (LED-) 缺失,这只是背光引脚)。不要忘记将 Pin5 (R/W) 连接到 GND。
Peter Fleury 编写了一个非常好的与 HD44780 4x20 接口的库: http://homepage.hispeed.ch/peterfleury/avr-software.html#libs 在“基于 HD44870 的 LCD 的 LCD 库”部分中尝试一下
【讨论】:
非常感谢 :) 我想知道这一点。当我调整对比度时,我只看到 2 行(第 1 行和第 3 行)上的黑框。那么这是否意味着我的程序已经结束了?我要去研究你现在发布的lib。 不,但是 lib 是一种快速而廉价的方式来了解更多关于连接字符 lcd 的信息。在 lcd.h 中进行一些小的更改,您可以连接每个 HD44780(2x16、4x16、4x20 等...) 当你只看到第 1 行和第 3 行时,请查看 lcd.h 中的“显示尺寸定义”,其中有每行的起始地址。这可以解决您的问题以上是关于带 Atmega32 的 4 位 4x20 LCD的主要内容,如果未能解决你的问题,请参考以下文章