/******************************************************************************* * File: 24C16.c * Title: complete TWI example code for a 24C16 EEPROM * also needs: lcd.h * Compiler: AVR-GCC 3.3.1 * Version: 1.0 * last update: 30-03-2004 * Target: ATmega8 * Author: Christoph Redecker * Company: www.avrbeginners.net *******************************************************************************/ #include #include #include #include "lcd.h" /******************************************************************************* * TWI_init: sets bitrate in TWBR and prescaler in TWSR * TWI_action: writes command to TWCR and takes care of TWINT and TWEN setting * waits for TWI action to be completed and returns status code * TWI_start: generates start condition and returns status code * TWI_stop: generate stop condition and returns status code * TWI_write_data: writes data to TWI bus and returns status code * TWI_read_data: reads data from bus to TWDR and returns status code. * if put_ack > 0, an ACK will be sent after the data has been received. * TWI_wait: waits for a given slave address to be ACKed. Only use if slave has * ACKed its address before. Loops forever if slave not present! * EE_read_data: reads one data byte from a given address * returns different error codes (zero if success) and data in TWDR * EE_write_data: write one data byte to a given address * returns different error codes (zero if success) *******************************************************************************/ void TWI_init(char bitrate, char prescaler); char TWI_action(char command); char TWI_start(void); void TWI_stop(void); char TWI_write_data(char data); char TWI_read_data(char put_ack); void TWI_wait(char slave); char EE_write_byte(const int address, const char data); char EE_read_byte(const int address); #define EE_ADDR 0xA0 /******************************************************************************/ void main (void) { //init LCD LCD_init(); //set TWBR = 32 for 100kHz SCL @ 8MHz TWI_init(32, 0); //write 0x55 @ 513 and print return value on LCD LCD_puthex(EE_write_byte(513, 0x55)); //send stop TWI_stop(); LCD_wait(); LCD_putchar(' '); //wait for the EEPROM to finish the write operation TWI_wait(EE_ADDR); //read the write location again and print return code on LCD LCD_puthex(EE_read_byte(513)); LCD_wait(); LCD_putchar(' '); //print the value read from the EEPROM on the LCD LCD_puthex(TWDR); TWI_stop(); //LCD should now show "0x00 0x00 0x55_" //where the _ is the blinking cursor. } /******************************************************************************/ void TWI_init(char bitrate, char prescaler) //sets bitrate and prescaler { TWBR = bitrate; //mask off the high prescaler bits (we only need the lower three bits) TWSR = prescaler & 0x03; } /******************************************************************************/ char TWI_action(char command) //starts any TWI operation (not stop), waits for completion and returns the status code //TWINT and TWEN are set by this function, so for a simple data transfer just use TWI_action(0); { //make sure command is good TWCR = (command|(1<>7) & 0x000E)) != 0x18) return TWSR; //now send the word address byte if(TWI_write_data((char)(address)) != 0x28) return TWSR; //now send the data byte if(TWI_write_data(data) != 0x28) return TWSR; //if everything was OK, return zero. return 0; } /******************************************************************************/ char EE_read_byte(const int address) { char dummy; //we need this for the first if() dummy = TWI_start(); //as in EE_write_byte, first send the page address and the word address if((dummy != 0x08) && (dummy != 0x10)) return TWSR; if(TWI_write_data(EE_ADDR|((address>>7) & 0x000E)) != 0x18) return TWSR; if(TWI_write_data((char)(address)) != 0x28) return TWSR; //send a repeated start for entering master receiver mode if(TWI_start() != 0x10) return TWSR; //send slave address, now with the read bit set if(TWI_write_data((EE_ADDR|1)|((address>>7) & 0x000E)) != 0x40) return TWSR; //now get the data from the EEPROM, don't return ACK if(TWI_read_data(0) != 0x58) return TWSR; //if everything was OK, return zero return 0; }