如何与LCD通信(嵌入式C)

时间:2014-11-06 20:36:10

标签: c embedded lcd

我正在尝试使用运行C代码的arduino进行LCD显示。 编译,传输和执行C代码工作正常,尝试了一些LED闪烁。 所有的电线也应该没问题,当使用'原生'Arduino库用于LCD显示器时,一切都很好,所以它一定是我找不到的代码错误:(

我正试图通过4数据线模式与LCD通信。控制和数据引脚位于同一端口。

以下是代码:

//CPU-Clock Frequency
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

// Definitions:

#define LED_PIN PB5 //PB5 = Arduino Pin 13 (with LED)

#define COMPARE_REG OCR0A
#define TIMER_PIN OC0A
#define TIMER_CONTROL_REGISTER TCCR0A

#define LCD_PORT PORTD
#define LCD_PORTDIR DDRD
//controlpins:
#define RS_PIN PD0
#define RW_PIN PD1
#define ENABLE_PIN PD2
//datapins:
#define DB_7 PD7
#define DB_6 PD6
#define DB_5 PD5
#define DB_4 PD4

//Defined command parameters
#define CLEAR 0x01

// Methods
void sleep(uint16_t sleepTime){
for(;sleepTime>0;sleepTime--){ _delay_ms(1);}
}
void lcd_enable(){
LCD_PORT |= (1<<ENABLE_PIN);
//TODO: wait for busy?
sleep(5);
LCD_PORT &= !(1<<ENABLE_PIN);
sleep(5);
}

void lcd_pushOut(unsigned int data){
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0xF0);
lcd_enable();
LCD_PORT &= (0x0F);
LCD_PORT |= (data & 0x0F) << 4;
lcd_enable();
}

void lcd_command(unsigned int command){
unsigned short int tmp = (LCD_PORT & 0x0F); //speichere alte Steuerleitungen
LCD_PORT &= !(1<<RS_PIN);
lcd_pushOut(command);
LCD_PORT |= (1<<RS_PIN);
LCD_PORT |= tmp; //setze Steuerleitungen zurück
}

void lcd_init(){
sleep(15); //wait for LCD init
LCD_PORTDIR = 0xFF; //make port of LCD output.
LCD_PORT &= !(1<<RW_PIN); //write, dont read.
LCD_PORT |= (3<<4); //write '3' to port.
LCD_PORT &= !(1<<RS_PIN); //we give commands, not data!
lcd_enable();
sleep(1);
lcd_enable(); //write '3' to port 2nd time.
LCD_PORT &= 0x0F; //behalte steuersignale bei, setze daten'port' zurück.
LCD_PORT |= (2<<4); //write '2' to port.
lcd_enable();
//from now on LCD is in 4 bit mode.
lcd_pushOut(0x28); // 4 bit, 5x7 pix, 2 line mode
lcd_pushOut(0x06); //cursor rückt weiter, display scrollt
lcd_pushOut(0x0F); //display ein, cursor aus, blinken aus
lcd_pushOut(0x80); //we will write to DDRAM
lcd_pushOut(0x01); //clear display
//begin test writing zeroes.

LCD_PORT |= (1<<RS_PIN); //give data, not commands!
}

void timer_init(){
//DDRA |= (1<<TIMER_PIN); //make timerpin output.
TIMER_CONTROL_REGISTER = 0b10000000; //set timerpin high @bottom, on compare match clear. (0x80)
COMPARE_REG = 256/2; // dutycycle= 50%
}

void setTimerPower(unsigned int percent){   //set PWM Output (high) in %
COMPARE_REG = (percent/100) * 256;
}

int main (void)
{
//INIT
lcd_init();
//timer_init();
while(1){
lcd_command(CLEAR);
}
//now ready to write! let's write 3 zeroes!
lcd_pushOut('0');
lcd_pushOut('0');
lcd_pushOut('0');
/*
sleep(5000);
char c = '0';
while (1) {
lcd_clear();
lcd_pushOut(c++);
sleep(969); // 3x lcd_enable + 1 ms bearbeitungszeit? ... ziemlich großzügig
if(c > 0x7A) //entspricht c > 'z'
c='0';
}
*/
return 0;
}

编辑:大部分时间,LCD只在第一行产生黑色方块。

1 个答案:

答案 0 :(得分:4)

!(1<<BIT_NUMBER)的所有实例都应转换为~(1<<BIT_NUMBER)!是一个布尔值NOT而你基本上都在做!(true)所以你得到0就是结果。

显示问题的示例(在x86上):

int main( int argc, char* argv[] )
{
    printf( "%8.8X %8.8X\n", !(1<<2), ~(1<<2) );
    return 0;
}

输出是:

00000000 FFFFFFFB

改变这一点,你至少会更进一步。您还应该说明LCD上哪个控制器可以进一步帮助。