Matrix Orbital LCD and AVR

From pauljmac.com Projects
Jump to: navigation, search

This is a good example of 3 different ways of doing the same thing.

#define F_CPU 20000000UL  //20MHz Clock

#include <avr/io.h>
#include <util/twi.h>
#include <avr/pgmspace.h>

#define LCD_ADDY 0x50   //Write addy for LCD

const char MSG_1[] PROGMEM = "PROGMEM test\0";  //stores the string in ROM

void send_twi(char xyz){
   TWDR = xyz;  // LOAD SLA_W into TWDR reg,
   TWCR = (1<<TWINT) | (1<<TWEN); // CLEAR TWINT bit in TWCR to start transmission
   while (!(TWCR & (1<<TWINT))){ //wait for TWINT flag set. this indicated that SLA+W was transmitted and ACK was received
      ; //wait
      }
   if ((TWSR & 0xF8) != TW_MT_DATA_ACK){ //check value of TWI status reg, mask presacaer buts, if diffrent from MT_DATA_ACK error
      ; //error
      }
}

void string_twi_P(const char *ptr){      //send string to LCD
   while (pgm_read_byte(ptr) != 0x00)
      send_twi(pgm_read_byte(ptr++));
}

void LCD_int(void){
   TWBR=10;
   TWSR=((0<<TWPS0)|(0<<TWPS1));
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //send start cond
   while (!(TWCR & (1<<TWINT))){ //wait for TWINT flag set, which indicates that START was transmited
      ; //wait
      }
   if ((TWSR & 0xF8) != TW_START){ // check value of TWI status, mask prescaler bits,  if diffrent from START error
      ; //error
      }
   send_twi(LCD_ADDY);
   send_twi(0xFE);   //0xFE, 0x58 clears LCD
   send_twi(0x58);
}

void LCD_stop(void){
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //trans stop cond
}
   

int main (void){
   LCD_int();
   string_twi_P(MSG_1);
   send_twi(0xFE);      //select coloum/row
   send_twi(0x47);
   send_twi(0x01);
   send_twi(0x02);
   string_twi_P(PSTR("Hi mom!"));
   send_twi(0xFE);
   send_twi(0x47);
   send_twi(0x01);
   send_twi(0x03);
   string_twi_P(PSTR("It works!"));
   send_twi(0xFE);
   send_twi(0x47);
   send_twi(0x01);
   send_twi(0x04);
   string_twi_P(PSTR("Last row"));
   LCD_stop();
}