24LC512 I2C™ Serial EEPROM

24LC512 I2C™ Serial EEPROM
Çeşme:
http://embedded-lab.com/blog/lab-14-inter-integrated-circuit-i2c-communication/


C:
http://blog.naver.com/PostView.nhn?blogId=sunset_blvd&logNo=100066622319&parentCategoryNo=22&categoryNo=&viewDate=&isShowPopularPosts=true&from=search
https://www.amobbs.com/thread-5369871-1-1.html
https://playground.arduino.cc/Code/ATMELTWI/
#include <Wire.h> #define disk1 0x50 //Address of 24LC256 eeprom chip void setup(void) { Serial.begin(9600); Wire.begin(); unsigned int address = 0; //writeEEPROM(disk1, address, 99); Serial.print(readEEPROM(disk1, address), DEC); Serial.println(); } void loop(){} void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) { Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.write(data); Wire.endTransmission(); delay(5); } byte readEEPROM(int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF; Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission(); Wire.requestFrom(deviceaddress,1); if (Wire.available()) rdata = Wire.read(); return rdata; }
#include <avr/io.h> #include <string.h> #include <stdio.h> #include <util/twi.h> #include <util/delay.h> #ifndef TWI_FREQ #define TWI_FREQ 100000L #endif #ifndef F_CPU #warning "F_CPU not defined for " #define F_CPU 16000000L #endif #define BAUD 9600 #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif #define HI_UINT16(a) (((a) >> 8) & 0xFF) #define LO_UINT16(a) ((a) & 0xFF) #define disk1 0xa0 //Address of 24LC256 eeprom chip /* USART */ void USART_setup(void); void USART_TransmitString(char str[]); void USART_TransmitChar(unsigned char data); void ERROR(uint8_t ch) { PORTB |= (1<<ch); } /* TWI */ void TWI_writeEEPROM(int deviceaddress, unsigned int eeaddress, uint8_t data); uint8_t TWI_readEEPROM(int deviceaddress, unsigned int eeaddress); /* main */ int main(void) { USART_setup(); char temp[8]; sprintf(temp, "%s\n", "start"); USART_TransmitString(temp); DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5); DDRC |= (1<<PC4)|(1<<PC5); PORTB = 0x00; // Activate the two ports for the TWI, analog input 4 for SDA and 5 for SCL. sbi(PORTC, 4); sbi(PORTC, 5); // Initialize twi prescaler to 1. cbi(TWSR, TWPS0); cbi(TWSR, TWPS1); // Set the TWI bit rate to 100kHz. TWBR = ((F_CPU / TWI_FREQ) - 16) / 2; unsigned int address = 0x00; TWI_writeEEPROM(disk1, address, 123); _delay_ms(5); uint8_t data = TWI_readEEPROM(disk1, address); char temp2[28]; sprintf(temp2, "data: %i\n", data); USART_TransmitString(temp2); while (1); } /* TWI functions */ void TWI_writeEEPROM(int deviceaddress, unsigned int eeaddress, uint8_t data) { //------------------ Start ------------------------ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_START) ERROR(0); //------------------ Sending device address ------------------------ TWDR = deviceaddress+TW_WRITE; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_SLA_ACK) ERROR(1); //------------------ Send eeprom addres ------------------------ TWDR = HI_UINT16(eeaddress); TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(2); TWDR = LO_UINT16(eeaddress); TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(2); //------------------ Send data ------------------------ TWDR = data; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(2); //------------------ Stop ----------------------------------- TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); } uint8_t TWI_readEEPROM(int deviceaddress, unsigned int eeaddress) { //------------------ Start ------------------------ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_START) ERROR(0); //------------------ Sending device address ------------------------ TWDR = deviceaddress+TW_WRITE; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_SLA_ACK) ERROR(1); //------------------ Send eeprom addres ------------------------ TWDR = HI_UINT16(eeaddress); TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(2); TWDR = LO_UINT16(eeaddress); TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MT_DATA_ACK) ERROR(2); //------------------ Restart ------------------------ TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_REP_START) ERROR(3); //------------------ Sending device address ------------------------------- TWDR = deviceaddress+TW_READ; TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MR_SLA_ACK) ERROR(4); //------------------ Receive data ----------------------------------- TWCR = (1<<TWINT) | (1<<TWEN); while (!(TWCR & (1<<TWINT))); if ((TWSR & 0xF8) != TW_MR_DATA_NACK) ERROR(5); // Store receive data uint8_t data_in = TWDR; //------------------ Stop ----------------------------------- TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); return data_in; } /* USART functions */ void USART_TransmitChar(unsigned char data) { // If UDRE0 is one, the buffer is empty, and therefore ready to be written. while (!(UCSR0A & (1<<UDRE0))) {} UDR0 = data; // USART Transmit / Receive Data Buffer } void USART_TransmitString(char str[]) { for (uint8_t i = 0; i < strlen(str); i++) { USART_TransmitChar(str[i]); } } void USART_setup(void) { int speed = ((F_CPU/16/BAUD)-1); // set boud rate UBRR0H = (speed>>8); UBRR0L = speed; UCSR0B = (1<<TXEN0); // Bit 3 – TXEN0: Transmitter Enable 0 UCSR0C = (1<<UCSZ01) | (1<<UCSZ00); // USART Character Size / Data Order = 8-bit }
.nolist .include "./m328Pdef.inc" .list .equ bcdsize = 5 .dseg ; .org SRAM_START bcd: .byte bcdsize #define TWI_FREQ 100000 #define TW_START 0x08 #define TW_REP_START 0x10 #define TW_MT_SLA_ACK 0x18 #define TW_MT_DATA_ACK 0x28 #define TW_MR_SLA_ACK 0x40 #define TW_MR_DATA_NACK 0x58 #define TW_READ 1 #define TW_WRITE 0 ;***** Speed setting ***** .equ F_CPU = 16000000 .equ BAUD = 9600 .equ speed = F_CPU / 16 / BAUD - 1 ; Set the TWI bit rate to 100kHz. .equ TWI_BIT_RATE = ((F_CPU / TWI_FREQ) - 16) / 2 .def temp = r16 .def temp2 = r17 .def data = r18 .cseg .org 0x0000 rjmp start start: ldi temp, high(RAMEND) out sph, temp ldi temp, low(RAMEND) out spl, temp rcall USART_Init ldi temp, 0x1F out DDRB, temp clr temp out PORTB, temp ldi temp, 0x30 out DDRC, temp rcall TWI_Init rcall TWI_Start rcall TWI_Write_Addr ; write eeprom address ldi temp, 0 rcall TWI_Write_Data ldi temp, 0 rcall TWI_Write_Data rcall TWI_Restart rcall TWI_SendAddressSLAR rcall TWI_ReadData rcall TWI_Stop mov zl, data ldi zh, 0 rcall bin2bcd ldi ZL, low(bcd+5) ldi ZH, high(bcd+5) ldi r17, bcdsize echo: ld data, -Z cpi data, 0 brne send brts send rjmp next send: set ori data, 0x30 rcall USART_Transmit next: nop dec r17 brne echo ldi data, $0D rcall USART_Transmit ldi data, $0A rcall USART_Transmit while: nop rjmp while ; BCD --------------------------------------------------------------- .macro yhl ldi @0, low(@1) mov yl, @0 ldi @0, high(@1) mov yh, @0 .endmacro bin2bcd: yhl temp, 0x2710 ; 10k rcall m10k ret .macro bin2bcdmfn clr temp bin2bcdmfn2: sub zl,yl sbc zh,yh brcs PC+3 inc temp rjmp bin2bcdmfn2 sts bcd+@0,temp add zl, yl adc zh, yh .endmacro m10k: bin2bcdmfn 4 yhl temp, 0x3e8 ; 1k rcall m1k ret m1k: bin2bcdmfn 3 yhl temp, 0x64 ; 100 rcall m100 ret m100: bin2bcdmfn 2 yhl temp, 0x0a ; 10 rcall m10 ret m10: bin2bcdmfn 1 sts bcd,zl ret ; TWI --------------------------------------------------------------- TWI_ReadData: ldi temp, (1<<TWINT)|(1<<TWEN) sts TWCR, temp wait5: lds temp, TWCR sbrs temp, TWINT rjmp wait5 lds r16, TWSR andi r16, 0xF8 cpi r16, TW_MR_DATA_NACK breq pc+2 sbi portb, 5 ; Store receive data lds data, TWDR ret TWI_SendAddressSLAR: ldi temp, 0xa0 ldi temp2, TW_READ adc temp, temp2 sts TWDR, temp ldi temp, (1<<TWINT)|(1<<TWEN) sts TWCR, temp wait4: lds temp, TWCR sbrs temp, TWINT rjmp wait4 lds temp, TWSR andi temp, 0xF8 cpi temp, TW_MR_SLA_ACK breq pc+2 sbi portb, 4 ret TWI_Restart: ldi temp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, temp wait33: lds temp, TWCR sbrs temp, TWINT rjmp wait33 lds temp, TWSR andi temp, 0xF8 cpi temp, TW_REP_START breq pc+2 sbi portb, 3 ret TWI_Init: ; Activate the two ports for the TWI, analog input 4 for SDA and 5 for SCL. sbi PORTC, 4 sbi PORTC, 5 ; Initialize twi prescaler to 1. clear bits TWPS0 and TWPS1 lds temp, TWSR cbr temp, 0x03 sts TWSR, temp ldi temp, TWI_BIT_RATE sts TWBR, temp ret TWI_Stop: ldi temp, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO) sts TWCR, temp ret TWI_Start: ; Send START condition ldi r16, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, r16 ; Wait for TWINT Flag set. This indicates ; that the START condition has been ; transmitted. wait1: lds temp, TWCR sbrs temp,TWINT rjmp wait1 ; Check value of TWI Status Register. Mask ; prescaler bits. If status different from ; START go to ERROR. lds temp, TWSR andi temp, 0xF8 cpi temp, TW_START brne ERROR ret ERROR: sbi portb, 0 ret TWI_Write_Data: ; Load DATA into TWDR Register. sts TWDR, temp ; Clear TWINT bit in TWCR to start transmission of data. ldi r16, (1<<TWINT) | (1<<TWEN) sts TWCR, r16 ; Wait for TWINT Flag set. This indicates that the DATA has been transmitted, and ACK/NACK has been received. wait3: lds r16,TWCR sbrs r16,TWINT rjmp wait3 ; Check value of TWI Status Register. Mask prescaler bits. If status different from MT_DATA_ACK go to ERROR. lds r16,TWSR andi r16, 0xF8 cpi r16, TW_MT_DATA_ACK brne ERROR ret TWI_Write_Addr: ldi temp, 0xa0 ;Load SLA_W into TWDR Register. sts TWDR, temp ; Clear TWINT bit in TWCR to start transmission of address. ldi temp, (1<<TWINT) | (1<<TWEN) sts TWCR, temp ; Wait for TWINT Flag set. This indicates that the SLA+W has been transmitted, and ACK/NACK has been received. wait2: lds r16,TWCR sbrs r16,TWINT rjmp wait2 ; Check value of TWI Status Register. Mask prescaler bits. If status different from MT_SLA_ACK go to ERROR. lds r16,TWSR andi r16, 0xF8 cpi r16, TW_MT_SLA_ACK brne ERROR ret ; USART --------------------------------------------------------------- USART_Init: push r16 ; these values are for 9600 Baud with a 16MHz clock ; Set baud rate clr r16 sts UBRR0H, r16 ldi r16, speed sts UBRR0L, r16 ; Enable transmitter ldi r16, (1<<TXEN0) sts UCSR0B, r16 ; Set frame format: Async, no parity, 8 data bits, 1 stop bit ldi r16, (1<<UCSZ01) | (1<<UCSZ00) sts UCSR0C, r16 pop r16 ret USART_Transmit: ; wait for empty transmit buffer lds temp, UCSR0A sbrs temp, UDRE0 rjmp USART_Transmit ; Put data (r18) into buffer, sends the data sts UDR0, data ret