Forum: Mikrocontroller und Digitale Elektronik EEPROM mit Codevision ansteuern


von Tobias A. (Gast)


Lesenswert?

Hi

ich muss mich momentan im Rahmen meines berufspraktischen
Semesters mit AVRs beschäftigen.
Klappt so weit alles ganz prima, jedoch bekomme ich es einfach
nicht auch die Rolle ein 24LC65 anzusteuern.
Als Entwicklungsumgebung nehme ich das STK500 und Codevision AVR.

Jetzt meine Frage:
Wie steuere ich das EEPROM denn nun an?
Ich habe jetzt einfach mittels Code Generator und dem
Beispielcode für das 24C02 versuch das 24LC65 anzusteuern,
aber nix passiert.
Die Pullups an SCL und SDA sind dran, A0-A2 liegen auf Masse und
mit dem STK ist der ganze kram auch verbunden.
Hier der entsprechende Auszug aus dem Quellcode

// *************** der Kopf *************
#include <mega32.h>

// I2C Bus functions
#asm
   .equ __i2c_port=0x1B
   .equ __sda_bit=3
   .equ __scl_bit=2
#endasm
#include <i2c.h>
#include <delay.h>


// ***** die von Codevision gelieferten Routinen *****

#define EEPROM_BUS_ADDRESS 0xa0

/* read a byte from the EEPROM */
unsigned char eeprom_read(unsigned char address) {
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}

/* write a byte to the EEPROM */
void eeprom_write(unsigned char address, unsigned char data) {
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
/* 10ms delay to complete the write operation */
delay_ms(10);
}

// ************* Das Hauptprogramm *****

i2c_init();

while (1)
      {

unsigned char i;

/* initialize the I2C bus */
i2c_init();

/* write the byte 55h at address AAh */
eeprom_write(0xAA,0xAA);
delay_ms(2000);
/* read the byte from address AAh */
i=eeprom_read(0xAA);

PORTB=i;  // DDRB ist mit 0xFF geladen
while (1); /* loop forever */

 };

und was mach ich jetzt falsch???

Vielen Dank für Eure Hilfe

Gruß
  Tobi

von Tom (Gast)


Lesenswert?

Hi,
hast Du wirklich den gesammten Code gepostet? Wenn ja, frage ich mich
wie du den überhaupt ohne fehlermeldung compilieren kontest. Mir fallen
gleich mal 3 fehler auf:
1. Das Programm hat keine main Funktion. Irgenwo musst du mal
void main(void) schreiben, das braucht jedes C-Programm.
2. 2x i2c_init(); das ist nur einmal auserhalb der Hauptschleife
nötig.
3.while (1); /* loop forever */ : Da fehlt zunächst einmal noch "{}"
aber du hast ja schon eine Endlosschleife , wäre also onehin
überflüssig. Soll das ganze Programm nur einmal ausgeführt werden musst
du es VOR die endlosschleife schreiben, ansonsten in die Schleife.
Gruß!

von Tom (Gast)


Lesenswert?

Nachtrag:
Noch ein fehler gefunden:
while (1)
      {
unsigned char i;
Die Deklaration einer Variablen muss immer als erstes erfolgen
Also direckt nach deinem (nicht vorhandenen)
void main(void)
{
unsigned char i;
und nicht in der Hauptschleife.
Ich bezweifle immer mehr das dein Compiler daraus ein .hex file
erstellt hat ;-)

von Tobias A. (Gast)


Lesenswert?

Hi

ich habe euch von den gesamten Code verschont.
Das Ding hat ein HEX - File gebacken, ich habe mir
so selbstverständlich Dinge wie void main (void) etc.
gespart.

Dieses 2. while(1) ist alles aus dem Codevision Code
Generator entstanden.
Ich poste jetzt mal den kompletten code...

/*****************************************************
This program was produced by the
CodeWizardAVR V1.24.1c Evaluation
Automatic Program Generator
© Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.ro
e-mail:office@hpinfotech.ro

Project :
Version :
Date    : 27.02.2004
Author  : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type           : ATmega32
Program type        : Application
Clock frequency     : 11,059200 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 512
*****************************************************/

#include <mega32.h>

// I2C Bus functions
#asm
   .equ __i2c_port=0x1B
   .equ __sda_bit=3
   .equ __scl_bit=2
#endasm
#include <i2c.h>
#include <delay.h>
// Declare your global variables here




#define EEPROM_BUS_ADDRESS 0xa0

/* read a byte from the EEPROM */
unsigned char eeprom_read(unsigned char address) {
unsigned char data;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}

/* write a byte to the EEPROM */
void eeprom_write(unsigned char address, unsigned char data) {

i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(address);
i2c_write(data);
i2c_stop();
/* 10ms delay to complete the write operation */
delay_ms(10);
}








void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTB=0x00;
DDRB=0xFF;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In
Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T
State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
// Analog Comparator Output: Off
ACSR=0x80;
SFIOR=0x00;

// 2 Wire Bus initialization
// Generate Acknowledge Pulse: Off
// 2 Wire Bus Slave Address: 0h
// General Call Recognition: Off
// Bit Rate: 394,971 kHz
TWBR=0x06;
TWAR=0x00;
TWCR=0x04;

// I2C Bus initialization
i2c_init();

while (1)
      {

unsigned char i;

/* initialize the I2C bus */
i2c_init();

/* write the byte 55h at address AAh */
eeprom_write(0xAA,0xAA);
delay_ms(2000);
/* read the byte from address AAh */
i=eeprom_read(0xAA);

PORTB=i;
while (1); /* loop forever */






      };
}

von crazy horse (Gast)


Lesenswert?

mit einem 24C02 funktionieren die I2C-Routinen von CV, also schliess
auch erst mal so einen an und teste, ob das auch bei dir funktioniert.

Wenn ja: Datenblatt des LC65 zur Hand nehmen und Unterschiede suchen
Wenn nein: Hardwarefehler

von Tobias A. (Gast)


Lesenswert?

Hi

Wenn ich ja so eins hätte wäre mir ja schon
geholfen...
Muss ich dann mal organisieren, aber das
braucht auch wieder ne Menge Zeit und das ist
grad das was ich nicht habe..
Ich werd mal schauen wo ich so was auftreiben kann.

Gruß
  Tobi

von crazy horse (Gast)


Lesenswert?

ich sehe gerade, der LC65 hat ja 8kbyte, d.h. der braucht 2 Adressbytes
(Blockadresse, Byteadresse). Pro Block lassen sich 256 Bytes
adressieren, d.h. die Blockadresse muss im Bereich 0-31 liegen.
Hast du dir das Datenblatt denn mal angesehen?

von Tobias A. (Gast)


Lesenswert?

Hi ja hab ich...
ich habs nur übersehen.
Das könnte also heissen, das ich ihm einfach eine
4 Hex breite Blockadresse senden muss, oder?
Also anstatt:

/* write the byte 55h at address AAh */
eeprom_write(0x55,0xAA);
so was wie
eeprom_write(0x55,0x00AA);
sehe ich das richtig?

empfangen dann analog

Gruß
  Tobi

von Tobias A. (Gast)


Lesenswert?

Agggr

hab info und Adresse vertauscht
also so was wie

eeprom_write(0x00AA,0x55);


um 55h nach 00AAh zu schreiben?

von crazy horse (Gast)


Lesenswert?

ich habe hier nur ein etwas älteres Programmteil für Software-I2C.

lesen:
i2c_start();
i2c_write (dev_adress);
i2c_write (page_adress);
i2c_write (byte_adress);
i2c_start();
i2c_write (dev_adress+1);
temp=i2c_read(0);
i2c_stop();

schreiben:
i2c_start();
i2c_write (dev_adress);
i2c_write (page_adress);
i2c_write (byte_adress);
i2c_write (data);
i2c_stop ();

von Tobias A. (Gast)


Lesenswert?

Hi

danke für die Info.
Irgendwie war ich extrem verpeilt.
So klappt es endlich. Ich hab mir die Funktionen
nach Deiner Vorgaben angepasst und jetzt klappt das
Prima G

Danke an alle!!!!

Gruß
  Tobi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.