LCD Fonctionnel

This commit is contained in:
arnaud.houdelette 2019-09-05 17:02:53 +02:00
parent 044633f59d
commit a75b521dce
8 changed files with 576 additions and 186 deletions

View file

@ -46,7 +46,7 @@
# $Id$ # $Id$
#Bootloader Port #Bootloader Port
PORT = /dev/ttyU0 PORT = /dev/serial/by-id/usb-Arduino__www.arduino.cc__Arduino_Mega_2560_6493534363335111A032-if00
# /dev/serial/by-id/usb-Arduino_LLC_Arduino_Micro-if00 # /dev/serial/by-id/usb-Arduino_LLC_Arduino_Micro-if00
#Device Port (for autoreset) #Device Port (for autoreset)
RESETPORT = /dev/ttyU0 RESETPORT = /dev/ttyU0
@ -54,11 +54,11 @@ RESETPORT = /dev/ttyU0
TARGET = pyrorf TARGET = pyrorf
SRC = main.c i2c.c lcd.c SRC = main.c lcd.c
CXXSRC = CXXSRC =
ASRC = ASRC = i2cmaster.S
MCU = atmega32 MCU = atmega2560
F_CPU = 8000000L F_CPU = 16000000UL
FORMAT = ihex FORMAT = ihex
UPLOAD_RATE = 20000 UPLOAD_RATE = 20000
@ -98,10 +98,10 @@ LDFLAGS = -lm -Wl,--gc-sections
# Programming support using avrdude. Settings and variables. # Programming support using avrdude. Settings and variables.
AVRDUDE_PROGRAMMER = linuxspi AVRDUDE_PROGRAMMER = stk500
AVRDUDE_PORT = /dev/spidev0.0 AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:i AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:i
AVRDUDE_FLAGS = -F -pattiny84 -P$(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b $(UPLOAD_RATE) AVRDUDE_FLAGS = -F -p m2560 -P$(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -b $(UPLOAD_RATE)
# Program settings # Program settings
CC = avr-gcc CC = avr-gcc

115
i2c.c
View file

@ -1,115 +0,0 @@
#include "i2c.h"
#include <util/delay.h>
void i2c_init(void)
{
i2c_sda_hi();
i2c_scl_hi();
_delay_us(i2cbitdelay);
}
void i2c_writebit( uint8_t c )
{
if ( c > 0 ) {
i2c_sda_hi();
} else {
i2c_sda_lo();
}
i2c_scl_hi();
_delay_us(i2cbitdelay);
i2c_scl_lo();
_delay_us(i2cbitdelay);
if ( c > 0 ) {
i2c_sda_lo();
}
_delay_us(i2cbitdelay);
}
uint8_t i2c_readbit(void)
{
i2c_sda_hi();
i2c_scl_hi();
_delay_us(i2cbitdelay);
uint8_t c = bitRead( SDAPORT,SDAPIN);
i2c_scl_lo();
_delay_us(i2cbitdelay);
return c ? 1 : 0;
}
void i2c_start(void)
{
i2c_sda_hi();
i2c_scl_hi();
_delay_us(i2cbitdelay);
i2c_sda_lo();
_delay_us(i2cbitdelay);
i2c_scl_lo();
_delay_us(i2cbitdelay);
}
void i2c_repstart(void)
{
i2c_sda_hi();
i2c_scl_hi();
i2c_scl_lo(); // force SCL low
_delay_us(i2cbitdelay);
i2c_sda_release(); // release SDA
_delay_us(i2cbitdelay);
i2c_scl_release(); // release SCL
_delay_us(i2cbitdelay);
i2c_sda_lo(); // force SDA low
_delay_us(i2cbitdelay);
}
void i2c_stop(void)
{
i2c_scl_hi();
_delay_us(i2cbitdelay);
i2c_sda_hi();
_delay_us(i2cbitdelay);
}
uint8_t i2c_write( uint8_t c )
{
for ( uint8_t i=0;i<8;i++) {
i2c_writebit( c & 128 );
c<<=1;
}
return i2c_readbit();
}
uint8_t i2c_read( uint8_t ack )
{
uint8_t res = 0;
for ( uint8_t i=0;i<8;i++) {
res <<= 1;
res |= i2c_readbit();
}
if ( ack )
i2c_writebit( 0 );
else
i2c_writebit( 1 );
_delay_us(i2cbitdelay);
return res;
}

45
i2c.h
View file

@ -1,45 +0,0 @@
#ifndef defines_i2c
#define defines_i2c
#include <avr/io.h>
#include "defines.h"
#define i2cbitdelay 50
#define I2C_ACK 1
#define I2C_NAK 0
#define SCLPORT PORTD
#define SDAPORT PORTD
#define SDAPIN 7
#define SCLPIN 8
#define SCLDDR DDRD
#define SDADDR DDRD
#define i2c_scl_release() bitClear(SCLDDR,SCLPIN);
#define i2c_sda_release() bitClear(SDADDR,SDAPIN);
// sets SCL low and drives output
#define i2c_scl_lo() bitClear(SCLPORT,SCLPIN); bitSet(SCLDDR,SCLPIN);
// sets SDA low and drives output
#define i2c_sda_lo() bitClear(SDAPORT,SCLPIN); bitSet(SDADDR,SDAPIN);
// set SCL high and to input (releases pin) (i.e. change to input,turnon pullup)
#define i2c_scl_hi() bitClear(SCLDDR,SCLPIN);bitSet(SCLPORT,SCLPIN);
// set SDA high and to input (releases pin) (i.e. change to input,turnon pullup)
#define i2c_sda_hi() bitClear(SDADDR,SDAPIN);bitSet(SDAPORT,SDAPIN);
void i2c_init(void);
void i2c_writebit( uint8_t c );
uint8_t i2c_readbit(void);
void i2c_start(void);
void i2c_repstart(void);
void i2c_stop(void);
uint8_t i2c_write( uint8_t c );
uint8_t i2c_read( uint8_t ack );
#endif

359
i2cmaster.S Normal file
View file

@ -0,0 +1,359 @@
;*************************************************************************
; Title : I2C (Single) Master Implementation
; Author: Peter Fleury <pfleury@gmx.ch>
; based on Atmel Appl. Note AVR300
; File: $Id: i2cmaster.S,v 1.13 2015/09/16 11:21:00 peter Exp $
; Software: AVR-GCC 4.x
; Target: any AVR device
;
; DESCRIPTION
; Basic routines for communicating with I2C slave devices. This
; "single" master implementation is limited to one bus master on the
; I2C bus.
;
; Based on the Atmel Application Note AVR300, corrected and adapted
; to GNU assembler and AVR-GCC C call interface
; Replaced the incorrect quarter period delays found in AVR300 with
; half period delays.
;
; USAGE
; These routines can be called from C, refere to file i2cmaster.h.
; See example test_i2cmaster.c
; Adapt the SCL and SDA port and pin definitions and eventually
; the delay routine to your target !
; Use 4.7k pull-up resistor on the SDA and SCL pin.
;
; NOTES
; The I2C routines can be called either from non-interrupt or
; interrupt routines, not both.
;
;*************************************************************************
#include <avr/io.h>
#undef SCL_PORT
#undef SCL_DDR
;******----- Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA 1 // SDA Port D, Pin 1
#define SCL 0 // SCL Port D, Pin 0
#define SDA_PORT PORTD // SDA Port D
#define SCL_PORT PORTD // SCL Port D
;******----------------------------------------------------------------------
;-- map the IO register back into the IO address space
#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
#ifndef __tmp_reg__
#define __tmp_reg__ 0
#endif
.section .text
;*************************************************************************
; delay half period
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz), use T/2 > 1.25us
;*************************************************************************
.stabs "",100,0,0,i2c_delay_T2
.stabs "i2cmaster.S",100,0,0,i2c_delay_T2
.func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal
i2c_delay_T2: ; 3 cycles
#if F_CPU <= 4000000UL
rjmp 1f ; 2 "
1: rjmp 2f ; 2 "
2: rjmp 3f ; 2 "
3: rjmp 4f ; 2 "
4: rjmp 5f ; 2 "
5: rjmp 6f ; 2 "
6: nop ; 1 "
ret ; 4 " total 20 cyles = 5.0 microsec with 4 Mhz crystal
#elif F_CPU <= 8000000UL
push r24 ; 2 cycle
ldi r24, 7 ; 1 cycle
nop ; 1 cycle
1: sbiw r24, 1 ; 2 cycle
brne 1b ; 2 or 1 cycle, 4 cycles per loop
pop r24 ; 2 ycle
ret ; 4 cycle = total 60 cycles = 5.0 microsec with 12 Mhz crystal
#elif F_CPU <= 12000000UL
push r24 ; 2 cycle
ldi r24, 12 ; 1 cycle
nop ; 1 cycle
1: sbiw r24, 1 ; 2 cycle
brne 1b ; 2 or 1 cycle, 4 cycles per loop
pop r24 ; 2 ycle
ret ; 4 cycle = total 60 cycles = 5.0 microsec with 12 Mhz crystal
#elif F_CPU <= 16000000UL
push r24 ; 2 cycle
ldi r24, 17 ; 1 cycle
nop ; 1 cycle
1: sbiw r24, 1 ; 2 cycle
brne 1b ; 2 or 1 cycle, 4 cycles per loop
pop r24 ; 2 ycle
ret ; 4 cycle = total 80 cycles = 5.0 microsec with 16 Mhz crystal
#else
push r24 ; 2 cycle
ldi r24, 22 ; 1 cycle
nop ; 1 cycle
1: sbiw r24, 1 ; 2 cycle
brne 1b ; 2 or 1 cycle, 4 cycles per loop
pop r24 ; 2 ycle
ret ; 4 cycle = total 100 cycles = 5.0 microsec with 20 Mhz crystal
#endif
.endfunc ;
;*************************************************************************
; Initialization of the I2C bus interface. Need to be called only once
;
; extern void i2c_init(void)
;*************************************************************************
.global i2c_init
.func i2c_init
i2c_init:
cbi SDA_DDR,SDA ;release SDA
sbi SCL_DDR,SCL ;release SCL
cbi SDA_OUT,SDA
sbi SCL_OUT,SCL
ret
.endfunc
;*************************************************************************
; Issues a start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_start(unsigned char addr);
; addr = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_start
.func i2c_start
i2c_start:
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
rcall i2c_write ;write address
ret
.endfunc
;*************************************************************************
; Issues a repeated start condition and sends address and transfer direction.
; return 0 = device accessible, 1= failed to access device
;
; extern unsigned char i2c_rep_start(unsigned char addr);
; addr = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_rep_start
.func i2c_rep_start
i2c_rep_start:
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
rcall i2c_delay_T2 ;delay T/2
cbi SDA_DDR,SDA ;release SDA
sbi SDA_OUT,SDA
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
rcall i2c_delay_T2 ;delay T/2
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
rcall i2c_write ;write address
ret
.endfunc
;*************************************************************************
; Issues a start condition and sends address and transfer direction.
; If device is busy, use ack polling to wait until device is ready
;
; extern void i2c_start_wait(unsigned char addr);
; addr = r24
;*************************************************************************
.global i2c_start_wait
.func i2c_start_wait
i2c_start_wait:
mov __tmp_reg__,r24
i2c_start_wait1:
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
mov r24,__tmp_reg__
rcall i2c_write ;write address
tst r24 ;if device not busy -> done
breq i2c_start_wait_done
rcall i2c_stop ;terminate write operation
rjmp i2c_start_wait1 ;device busy, poll ack again
i2c_start_wait_done:
ret
.endfunc
;*************************************************************************
; Terminates the data transfer and releases the I2C bus
;
; extern void i2c_stop(void)
;*************************************************************************
.global i2c_stop
.func i2c_stop
i2c_stop:
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ;force SDA low
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
rcall i2c_delay_T2 ;delay T/2
cbi SDA_DDR,SDA ;release SDA
sbi SDA_OUT,SDA
rcall i2c_delay_T2 ;delay T/2
ret
.endfunc
;*************************************************************************
; Send one byte to I2C device
; return 0 = write successful, 1 = write failed
;
; extern unsigned char i2c_write( unsigned char data );
; data = r24, return = r25(=0):r24
;*************************************************************************
.global i2c_write
.func i2c_write
i2c_write:
sec ;set carry flag
rol r24 ;shift in carry and out bit one
rjmp i2c_write_first
i2c_write_bit:
lsl r24 ;if transmit register empty
i2c_write_first:
breq i2c_get_ack
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
brcc i2c_write_low
nop
cbi SDA_DDR,SDA ;release SDA
sbi SDA_OUT,SDA
rjmp i2c_write_high
i2c_write_low:
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ;force SDA low
rjmp i2c_write_high
i2c_write_high:
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
rcall i2c_delay_T2 ;delay T/2
rjmp i2c_write_bit
i2c_get_ack:
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
cbi SDA_DDR,SDA ;release SDA
sbi SDA_OUT,SDA
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
i2c_ack_wait:
sbis SCL_IN,SCL ;wait SCL high (in case wait states are inserted)
rjmp i2c_ack_wait
clr r24 ;return 0
sbic SDA_IN,SDA ;if SDA high -> return 1
ldi r24,1
rcall i2c_delay_T2 ;delay T/2
clr r25
ret
.endfunc
;*************************************************************************
; read one byte from the I2C device, send ack or nak to device
; (ack=1, send ack, request more data from device
; ack=0, send nak, read is followed by a stop condition)
;
; extern unsigned char i2c_read(unsigned char ack);
; ack = r24, return = r25(=0):r24
; extern unsigned char i2c_readAck(void);
; extern unsigned char i2c_readNak(void);
; return = r25(=0):r24
;*************************************************************************
.global i2c_readAck
.global i2c_readNak
.global i2c_read
.func i2c_read
i2c_readNak:
clr r24
rjmp i2c_read
i2c_readAck:
ldi r24,0x01
i2c_read:
ldi r23,0x01 ;data = 0x01
i2c_read_bit:
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
cbi SDA_DDR,SDA ;release SDA (from previous ACK)
sbi SDA_OUT,SDA
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
rcall i2c_delay_T2 ;delay T/2
i2c_read_stretch:
sbis SCL_IN, SCL ;loop until SCL is high (allow slave to stretch SCL)
rjmp i2c_read_stretch
clc ;clear carry flag
sbic SDA_IN,SDA ;if SDA is high
sec ; set carry flag
rol r23 ;store bit
brcc i2c_read_bit ;while receive register not full
i2c_put_ack:
cbi SCL_OUT,SCL
sbi SCL_DDR,SCL ;force SCL low
cpi r24,1
breq i2c_put_ack_low ;if (ack=0)
cbi SDA_DDR,SDA ; release SDA
sbi SCL_OUT,SCL
rjmp i2c_put_ack_high
i2c_put_ack_low: ;else
cbi SDA_OUT,SDA
sbi SDA_DDR,SDA ; force SDA low
i2c_put_ack_high:
rcall i2c_delay_T2 ;delay T/2
cbi SCL_DDR,SCL ;release SCL
sbi SCL_OUT,SCL
i2c_put_ack_wait:
sbis SCL_IN,SCL ;wait SCL high
rjmp i2c_put_ack_wait
rcall i2c_delay_T2 ;delay T/2
mov r24,r23
clr r25
ret
.endfunc

178
i2cmaster.h Normal file
View file

@ -0,0 +1,178 @@
#ifndef _I2CMASTER_H
#define _I2CMASTER_H
/*************************************************************************
* Title: C include file for the I2C master interface
* (i2cmaster.S or twimaster.c)
* Author: Peter Fleury <pfleury@gmx.ch>
* File: $Id: i2cmaster.h,v 1.12 2015/09/16 09:27:58 peter Exp $
* Software: AVR-GCC 4.x
* Target: any AVR device
* Usage: see Doxygen manual
**************************************************************************/
/**
@file
@defgroup pfleury_ic2master I2C Master library
@code #include <i2cmaster.h> @endcode
@brief I2C (TWI) Master Software Library
Basic routines for communicating with I2C slave devices. This single master
implementation is limited to one bus master on the I2C bus.
This I2c library is implemented as a compact assembler software implementation of the I2C protocol
which runs on any AVR (i2cmaster.S) and as a TWI hardware interface for all AVR with built-in TWI hardware (twimaster.c).
Since the API for these two implementations is exactly the same, an application can be linked either against the
software I2C implementation or the hardware I2C implementation.
Use 4.7k pull-up resistor on the SDA and SCL pin.
Adapt the SCL and SDA port and pin definitions and eventually the delay routine in the module
i2cmaster.S to your target when using the software I2C implementation !
Adjust the CPU clock frequence F_CPU in twimaster.c or in the Makfile when using the TWI hardware implementaion.
@note
The module i2cmaster.S is based on the Atmel Application Note AVR300, corrected and adapted
to GNU assembler and AVR-GCC C call interface.
Replaced the incorrect quarter period delays found in AVR300 with
half period delays.
@author Peter Fleury pfleury@gmx.ch http://tinyurl.com/peterfleury
@copyright (C) 2015 Peter Fleury, GNU General Public License Version 3
@par API Usage Example
The following code shows typical usage of this library, see example test_i2cmaster.c
@code
#include <i2cmaster.h>
#define Dev24C02 0xA2 // device address of EEPROM 24C02, see datasheet
int main(void)
{
unsigned char ret;
i2c_init(); // initialize I2C library
// write 0x75 to EEPROM address 5 (Byte Write)
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_write(0x75); // write value 0x75 to EEPROM
i2c_stop(); // set stop conditon = release bus
// read previously written value back from EEPROM address 5
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x05); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
ret = i2c_readNak(); // read one byte from EEPROM
i2c_stop();
for(;;);
}
@endcode
*/
/**@{*/
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 304
#error "This library requires AVR-GCC 3.4 or later, update to newer AVR-GCC compiler !"
#endif
#include <avr/io.h>
/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_READ 1
/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_WRITE 0
/**
@brief initialize the I2C master interace. Need to be called only once
@return none
*/
extern void i2c_init(void);
/**
@brief Terminates the data transfer and releases the I2C bus
@return none
*/
extern void i2c_stop(void);
/**
@brief Issues a start condition and sends address and transfer direction
@param addr address and transfer direction of I2C device
@retval 0 device accessible
@retval 1 failed to access device
*/
extern unsigned char i2c_start(unsigned char addr);
/**
@brief Issues a repeated start condition and sends address and transfer direction
@param addr address and transfer direction of I2C device
@retval 0 device accessible
@retval 1 failed to access device
*/
extern unsigned char i2c_rep_start(unsigned char addr);
/**
@brief Issues a start condition and sends address and transfer direction
If device is busy, use ack polling to wait until device ready
@param addr address and transfer direction of I2C device
@return none
*/
extern void i2c_start_wait(unsigned char addr);
/**
@brief Send one byte to I2C device
@param data byte to be transfered
@retval 0 write successful
@retval 1 write failed
*/
extern unsigned char i2c_write(unsigned char data);
/**
@brief read one byte from the I2C device, request more data from device
@return byte read from I2C device
*/
extern unsigned char i2c_readAck(void);
/**
@brief read one byte from the I2C device, read is followed by a stop condition
@return byte read from I2C device
*/
extern unsigned char i2c_readNak(void);
/**
@brief read one byte from the I2C device
Implemented as a macro, which calls either @ref i2c_readAck or @ref i2c_readNak
@param ack 1 send ack, request more data from device<br>
0 send nak, read is followed by a stop condition
@return byte read from I2C device
*/
extern unsigned char i2c_read(unsigned char ack);
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
/**@}*/
#endif

26
lcd.c
View file

@ -1,7 +1,7 @@
#include "lcd.h" #include "lcd.h"
#include "i2c.h"
#include <util/delay.h> #include <util/delay.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include "defines.h"
#define ENPIN 0 #define ENPIN 0
#define RWPIN 1 #define RWPIN 1
@ -13,19 +13,18 @@
uint8_t _numlines; uint8_t _numlines;
uint8_t _cols; uint8_t _cols;
uint8_t _En = (1<<ENPIN); uint8_t _En = 0x04;
uint8_t _Rs = (1<<RSPIN); uint8_t _Rs = 0x01;
uint8_t _Rw = (1<<RWPIN); uint8_t _Rw = 0x02;
uint8_t _Bl = (1<<BLPIN); uint8_t _Bl = 0x08;
uint8_t _BackliteOn = true; uint8_t _BackliteOn = false;
uint8_t _displaymode; uint8_t _displaymode;
uint8_t _displaycontrol; uint8_t _displaycontrol;
void i2csend(uint8_t data){ void i2csend(uint8_t data){
i2c_start(); i2c_start(0x27<<1);
i2c_write(LCD_ADDRESS << 1);
i2c_write(data); i2c_write(data);
i2c_stop(); i2c_stop();
} }
@ -33,12 +32,12 @@ void i2csend(uint8_t data){
void pulseEnable (uint8_t data) void pulseEnable (uint8_t data)
{ {
i2csend (data | _En); // En HIGH i2csend (data | _En); // En HIGH
i2csend (data & ~_En); // En LOW i2csend (data); // En LOW
} }
void write4bits ( uint8_t value, uint8_t mode ) void write4bits ( uint8_t value, uint8_t mode )
{ {
uint8_t data = value << DATASHIFT; uint8_t data = value << 4;
// Is it a command or data // Is it a command or data
// ----------------------- // -----------------------
@ -80,7 +79,6 @@ void lcd_init(uint8_t cols, uint8_t lines)
_cols=cols; _cols=cols;
_numlines=lines; _numlines=lines;
_delay_ms(100); _delay_ms(100);
// this is according to the hitachi HD44780 datasheet // this is according to the hitachi HD44780 datasheet
// figure 24, pg 46 // figure 24, pg 46
@ -102,7 +100,7 @@ void lcd_init(uint8_t cols, uint8_t lines)
_delay_us(150); // wait min of 100us _delay_us(150); // wait min of 100us
command(LCD_FUNCTIONSET | LCD_2LINE); command(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE);
} }
void lcd_clear() void lcd_clear()
@ -250,3 +248,7 @@ void lcd_write(uint8_t value)
{ {
send(value, LCD_DATA); send(value, LCD_DATA);
} }
void lcd_backlight(uint8_t value){
_BackliteOn = value?1:0;
}

4
lcd.h
View file

@ -4,7 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "i2c.h" #include "i2cmaster.h"
// LCD Commands // LCD Commands
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -59,7 +59,7 @@
#define HOME_CLEAR_EXEC 2000 #define HOME_CLEAR_EXEC 2000
#define LCD_ADDRESS 0x37 #define LCD_ADDRESS 0x27
void lcd_init(uint8_t cols, uint8_t lines); void lcd_init(uint8_t cols, uint8_t lines);
void lcd_clear(); void lcd_clear();

19
main.c
View file

@ -15,14 +15,25 @@
void lcdprint( char* ptr){ void lcdprint( char* ptr){
while (*ptr) lcd_write(*ptr); while (*ptr) lcd_write(*ptr++);
} }
int main(void) int main(void)
{ {
bitSet(DDRB,7);
lcd_init(20,4); lcd_init(20,4);
lcd_clear();
_delay_ms(1000);
lcd_home(); lcd_home();
lcdprint("Hello World"); lcd_display();
lcd_setCursor ( 0, 1 ); lcdprint("PyRO RF !");
lcdprint("Hello Me"); lcd_setCursor(0,3);
lcdprint("Arnaud HOUDELETTE");
_delay_ms(3000);
lcd_backlight(1);
lcd_display();
while (1){
}
} }