avr-chat
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-chat] LCD duty cycles, help please


From: Stephen Wong
Subject: Re: [avr-chat] LCD duty cycles, help please
Date: Mon, 28 Feb 2005 00:00:21 +0800
User-agent: Mozilla Thunderbird 0.9 (Windows/20041103)

Very likely, you don't have to deal with the "duty cycle" of your LCD. The LCD controller will take care of the scanning cycles. If your LCD is character based, and with less than 80 characters in total, the controller will be very likely a HD44780 or similar. You need to connect D0-D7 to Port B of any AVR, and the 3 control pins, E, RW, RS to some pins on Port D. Then, work according to the HD44780 data sheet for commands. There are numerous LCD library routines in ASM/C on the net, but just in case you want to have a look, attached is my brewed version. I connected E to PD4, RS to PD3 and RW to PD2 on a AT90S2313.

Cheers,
Stephen Wong @ Hong Kong

From James Dessart:
I bought an LCD off AllElectronics because it was cheap. I knew very
little about LCD panels at the time, but hey, it was $11. However,
since I am such a noob :), I don't know how to drive the panel. I've
figured out how to latch in the data, but I have no idea how to drive
the panel's 1/242 duty cycle. Is this on the LCD drive voltage? In
other words, do I drive the voltage to its required level only for
1/242nd of a second?

Thanks,
James


_______________________________________________
AVR-chat mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-chat

/* H44780 LCD Module Driver Routines
 * Header File
 *
 * Written by Stephen Wong, GPL software
 *
 * Project starts on 1 Feb 2005, Ver. 0.1
 */

#ifndef _LCD_H
#include <inttypes.h>
#include <avr/io.h>
#define F_CPU 4000000UL
#include <avr/delay.h>
#define _LCD_H
#endif

uint8_t lcd_ck_busy(void); /* read busy flag (data address in low order bits) */
void lcd_wr_inst(const uint8_t i); /* write instruction to LCD Module */
void lcd_wr_data(const uint8_t d); /* write data to LCD Module */
uint8_t lcd_rd_data(void); /* read data from LCD Module */
void lcd_wr_ram(const uint8_t addr, const uint8_t c); /* write c to addr */
void lcd_init(void); /* init LCM module */

/* H44780 LCD Module Driver Routines
 * Implementation File
 *
 * Written by Stephen Wong, GPL software
 *
 * Project starts on 1 Feb 2005, Ver. 0.1
 */

#include "lcd.h"
#ifdef DEBUG
#include "uart.h" /* for output debug info */
#endif

uint8_t lcd_ck_busy(void) { /* read busy flag (data addr in low order bits) */
    uint8_t busy_flag, i;
#ifdef DEBUG
    uint16_t c = 0;
#endif
    DDRB = 0x00;  /* PORT B for input */
    PORTB = 0xFF; /* Pull-Up PORT B pins */
    do {
        PORTD = 0x20; _delay_us(1); /* RW = 1 (R), RS = 0 (inst), E = 0 */
        PORTD = 0x28; _delay_us(1); /* RW = 1 (R), RS = 0 (inst), E = 1 */
        busy_flag = PINB;
        PORTD = 0x20; /* RW = 1 (R), RS = 0 (inst), E = 0 */
#ifdef DEBUG
        c++;
#endif
    } while (busy_flag >= 0x80);
#ifdef DEBUG
    uart_putchar('['); i = c >> 8; uart_puthex(i); 
    i = c; uart_puthex(i); uart_putchar(']');
#endif
    DDRB = 0xFF;  /* PORT B for output */
    _delay_us(1);
    return(busy_flag);
}

void lcd_wr_inst(const uint8_t i) { /* write instruction to LCD Module */
    lcd_ck_busy();
    PORTD = 0x00; _delay_us(1); /* RW = 0 (W), RS = 0 (inst), E = 0 */
    PORTB = i; /* write instruction */
    PORTD = 0x08; _delay_us(1); /* RW = 0 (W), RS = 0 (inst), E = 1 */
    PORTD = 0x20; _delay_us(1); /* RW = 1 (R), RS = 0 (inst), E = 0 */
}

void lcd_wr_data(const uint8_t d) { /* write data to LCD Module */
    lcd_ck_busy();
    PORTD = 0x10; _delay_us(1); /* RW = 0 (W), RS = 1 (data), E = 0 */
    PORTB = d; /* write data */
    PORTD = 0x18; _delay_us(1); /* RW = 0 (W), RS = 1 (data), E = 1 */
    PORTD = 0x20; _delay_us(1); /* RW = 1, RS = 0, E = 0 */
}

uint8_t lcd_rd_data(void) { /* read data from LCD Module */
    uint8_t d;
    lcd_ck_busy();
    DDRB = 0x00; /* PORT B for input */
    PORTB = 0xFF; /* Pull-Up PORT B pins */
    PORTD = 0x30; _delay_us(1); /* RW = 1 (R), RS = 1 (data), E = 0 */
    PORTD = 0x38; _delay_us(1); /* RW = 1 (R), RS = 1 (data), E = 1 */
    d = PINB;
    PORTD = 0x30; _delay_us(1); /* RW = 1 (R), RS = 1 (data), E = 0 */
    DDRB = 0xFF; _delay_us(1); /* PORT B for output */
    return(d);
}

void lcd_wr_ram(const uint8_t addr, const uint8_t c) {
    lcd_wr_inst(addr);
    lcd_wr_data(c);
}

void lcd_init(void) {
    DDRB = 0xFF;     /* Port B, all pins for output */
    DDRD = 0x7F;     /* Port D, all pins for output */
    _delay_ms(20); /* delay 20ms for LCM to init (auto) */
    lcd_wr_inst(0x38); /* init for 8-bit, 2 lines, 5x8 fonts */
    lcd_wr_inst(0x01); /* Clear Display */
    lcd_wr_inst(0x06); /* Entry Mode, Increment, No Display Shift */
    lcd_wr_inst(0x0c); /* Display On, Cursor Off, Blink Off */
}


reply via email to

[Prev in Thread] Current Thread [Next in Thread]