Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
Brewski
PostPosted: Feb 24, 2012 - 12:39 AM
Wannabe


Joined: Feb 27, 2001
Posts: 84
Location: Huntington, WV

I have written my own HD44780 display functions that do everything I want to do except it usees delays to compensate for the AVR being much faster than the LCD. Everything in my code so far seems to work solidly in both 8-bit and 4-bit mode.

I would like to replace the delays with a function that can be called that waits for the Busy Flag to clear and/or possibly returns the BF.

If it returned the reading of the BF and my own code would use it to delay the program until it clears or display the BF reading on a PORT Pin or something else with it.

All the code I have seen so far needs a lot of other code to set this up and execute. So long as the function knows the data port and the three control pins this should be a simple function.
I'm thinking this could be the simple function:
Change the data port DDRx from output to input.
Clear the LCD RS pin and Set R/W pin.
Set the LCD E pin .
Read the LCD data port, PINx.
Clear the LCD E pin.
Change the data port DDRx back to output.

(Changing back to DDR out could be done elsewhere. However. this is the only place I believe I would ever read from the LCD so by putting it back to output I would not have to make sure of the direction many other times in code.)

I have seen code before that I'm sure does this. I have gone over it but understanding it was beyond me.

Mike
 
 View user's profile Send private message  
Reply with quote Back to top
dksmall
PostPosted: Feb 24, 2012 - 12:44 AM
Raving lunatic


Joined: Apr 16, 2001
Posts: 3544
Location: Phoenix, Arizona

Post what you have tried so far. If you have written everything you described above, then this one more routine should not be that difficult.
 
 View user's profile Send private message  
Reply with quote Back to top
lincoln
PostPosted: Feb 24, 2012 - 01:03 AM
Hangaround


Joined: Jul 22, 2011
Posts: 150
Location: San jose, CA, USA

Code:
#ifdef LCD_CHECK_BUSY
void waitForLcd(void) {
   // adapted form http://www.8051projects.net/lcd-interfacing/busyflag.php
   
   LCD_DATA_DDR = 0x00; // set data bus to input
   LCD_CTRL_PORT &= ~_BV(LCD_RS);  // clear rs
   LCD_CTRL_PORT |= _BV(LCD_RW); // set read
   LCD_CTRL_PORT |= _BV(LCD_E); // set enable    
   while (LCD_DATA_PIN & 0x80) {
      LCD_CTRL_PORT &= ~_BV(LCD_E);
      LCD_CTRL_PORT |= _BV(LCD_E);
   }
   LCD_CTRL_PORT &= ~_BV(LCD_E);
   LCD_CTRL_PORT &= ~_BV(LCD_RW); // clear write flag
   LCD_DATA_DDR = 0xFF; // set data bus to output
}

#else
void waitForLcd(void) {
   _delay_us(50);
}

#endif

_________________
link

i am a NOOO00B!!

Don’t let that undermine what I just said.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
danni
PostPosted: Feb 24, 2012 - 08:09 AM
Raving lunatic


Joined: Sep 05, 2001
Posts: 2617


On my experience LCD output with delay cost no noticeable CPU-load.
So implementing busy test would only cost more code and wires, but has not advantages.

You should rethink your program flow, if you use the LCD 1000 times to often,
so the user was unable to read every new value and see only annoying flicker on the LCD.
A new value every 200-500ms was an ergonomic user friendly rate.


Peter
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Feb 24, 2012 - 08:16 AM
10k+ Postman


Joined: Mar 27, 2002
Posts: 22315
Location: Lund, Sweden

Regardless of if the only read you do is to check the busy flag it still makes sense to divide this into two separate pieces:

- A function that reads a byte from the LCD module, and
- A function that checks the busy flag.

Sketchy:

Code:
uint8_t LCD_ReadAddressBusy()
{
   //...
}

int LcdBusy()
{
   while (LcdReadAddressBusy & 0x80);
}


Do not worry about the extra level of function calls now. Care about efficiency of the code later. Get it to work first.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
pidkits
PostPosted: Feb 24, 2012 - 01:29 PM
Newbie


Joined: Sep 06, 2010
Posts: 18


This code works for me in 4-bit mode:

Code:
// 4-bit parallel interface
#define _DB_PORT PORTB
#define _DB_DDR DDRB
#define _DB7 PB3 // DB bits must be on same port, but not necessarily consecutive
#define _DB6 PB2
#define _DB5 PB1
#define _DB4 PB0
#define _DB_PIN PINB

#define _BF 7 // busy flag is bit 7
#define _DB_BITS (( 1 << _DB7 ) | ( 1 << _DB6 ) | ( 1 << _DB5 ) | ( 1 << _DB4 ))

#define tick() _delay_us(1)
#ifndef bitRead
#define bitRead(x,n) ((x>>n)&0x01) // returns value of bit x.n 0 or 1
#endif

// read the busy flag and address counter from the LCD
// returns 6 bit address plus busy flag (in bit 7)
static uint8_t lcd_readByte() {  // 58 uS at 1MHz
   uint8_t d,b;
   lcd_RW_high(); // RW = 1 to read
   tick();
   lcd_EN_high(); // EN = 1 to enable read
   tick();
   b = _DB_PIN; // read pins while EN is high
   lcd_EN_low();
   tick();
   d =    ( bitRead(b,_DB4) << 4 ); // high nibble
   d |=   ( bitRead(b,_DB5) << 5 );
   d |=   ( bitRead(b,_DB6) << 6 );
   d |=   ( bitRead(b,_DB7) << 7 );
   lcd_EN_high();
   tick();
   b = _DB_PIN;  // read pins while EN is high
   lcd_EN_low();
   tick();
   d |=   ( bitRead(b,_DB4) << 0 ); // low nibble
   d |=   ( bitRead(b,_DB5) << 1 );
   d |=   ( bitRead(b,_DB6) << 2 );
   d |=   ( bitRead(b,_DB7) << 3 );
   lcd_RW_low(); // clear the RW flag
   return d; // contains a full byte read from the LCD
}

// waits until busy flag is cleared
static void lcd_waitBusy() {
   lcd_RS_low(); // RS = 0 for instruction register
   _DB_DDR &= ~_DB_BITS;    // set DB pins for input
   tick();
   while( lcd_readByte() & (1<<_BF) ); // repeat until busy flag is cleared
}


Jim
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Feb 24, 2012 - 03:01 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 29299
Location: Wisconsin USA

This very recent thread has some discussion:
http://www.avrfreaks.net/index.php?name ... t=lcd+busy

And the forum search uncovers similar past threads.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits