Forum: Mikrocontroller und Digitale Elektronik TWI-ATmega32-Master-Problem


von Chriss (Gast)


Angehängte Dateien:

Lesenswert?

Abend zusammen,

ich versuche nun schon seit ein paar Tagen (C-Newbie) den folgenen 
"LED-PWM-Controller" ans laufen zu bekommen:
Beitrag "18- Kanal PWM Controller TWI(IIC)Interface FW. V.3"

Zuerst habe ich ein Programm mit MikroC geschrieben (Projektarchiv im 
Anhang). Folgendermaßen siehts aus:
1
void main()
2
{
3
  int a = 0x00;
4
  TWI_Init(100000);         // initialize TWI communication
5
6
  while(1)
7
  {
8
    TWI_Start();              // issue TWI start signal
9
    TWI_Write(0x02);          // send byte via TWI (device address + W)
10
    TWI_Write(0x0D);          // send byte (address of EEPROM location)
11
    TWI_Write(a);             // send data (data to be written)
12
    TWI_Stop();               // issue TWI stop signal
13
14
    a++;
15
    Delay_10ms();
16
  }
17
}

Im Grunde total einfach. TWI starten, Adresse, Register und Wert 
schicken, Wert um eins erhöhen und wieder von vorne. Bewirkt beim LED 
Controller  dass eine LED immer hoch-dimmt bis zum Maximalwert und dann 
wieder von vorne anfängt -> Funktioniert auch tadellos.
Jetzt will ich das ganze in ein anderes Programm einbauen. Schön dachte 
ich mir, krall ich mir das Header-File vom TWI aus dem Programm was ja 
irgendwo im Mikroelektronika-Ordner liegen wird. Allerdings hat der 
Hersteller der Entwicklungsumgebung seine Headerfiles irgendwie so 
geschrieben dass ich damit mal garnichts anfangen kann.
Dann habe ich versucht mit Peter Fleurys TWI Libary weiter zu kommen. 
Das Makefile habe ich einfach mal auf ATmega32 geändert und folgendes 
Programm geschrieben:
1
int main(void)
2
{
3
  i2c_init();
4
  lcd_init();
5
  lcd_clear();
6
7
  while(1)
8
  {
9
    lcd_print(0,0,"1");
10
11
    i2c_start_wait(0x02 + I2C_WRITE);
12
    i2c_write(0x0D);                         
13
    i2c_write(0xFF);        
14
    i2c_stop();                          
15
16
    lcd_print(0,0,"2");
17
    _delay_ms(2000);
18
  }
19
}

Zu Debug-Zwecken habe ich mal ein LCD mit eingebaut (habe leider keine 
Möglichkeit auf Hardware-Debugging). Auf diesem bleibt aber immer eine 
"1" stehen. Heißt für mich dass der Controller in irgendeiner 
Unterroutine "aufhängt". Ich hänge das ganze Archiv mal an. Ich glaube 
(wie gesagt Newbie), dass der die Masterroutine eine Antwort erwartet 
die sie nicht bekommt. Wäre nett wenn mal jemand drüber gucken würde.

Oder kennt vllt jemand noch eine Alternative zu Peter Fleurys Routine? 
Habe schon sehr viel gegooglet und das Forum hier bis zum Ende 
durchforstet aber im Grunde beruht fast alles auf Fleurys Routinen.

Alles was ich will sind drei Werte zu versenden mit einem Atmega32 bei 
16Mhz und 100kHz I2C Frequenz. Adresse, Register und Wert.

So verzweifle ich wie man vllt merkt...

Ich hoffe auf eure Hilfe und schonmal vielen Dank schonmal im vorraus!
Chriss

von Stephan W. (sir_wedeck)


Lesenswert?

Hi,
bin etwas verwirrt: DU hast die DeviceAdr. auf 0x02 geändert???

Wenn JA, dann darfst du bei "Peter Fleurys Routine" nicht 0x02 
schreiben!!!!
Diese Software erwartet das Commandbyte und NICHT die DeviceAdr. !!!!!

Also die DeviceAdr um 1(eins) noch links schieben und mit "I2C_WRITE" 
oder xxx_Read verodern.

Versuchsmal.

Stephan

von H.Joachim S. (crazyhorse)


Lesenswert?

TWI_Init(100000);         // initialize TWI communication

hm, ob das wirklich so gedacht ist, wie es da steht? Das wären 0x186a0?
Habe keine Ahnung, was die init bewirken soll, aber zumindest sehr 
unüblich mit einem 32bit-Wert...

von Chriss (Gast)


Lesenswert?

Das mit dem TWI_Init(100000); ist tatsäclich so gedacht (der code 
funktioniert ja auch so und ist aus einem Beipiel abgeleitet).

Stephan,
was meinst du mit Commandbyte? Ich bin davon ausgegangen dass ich dorf 
die Adresse meines LED Controllers eintragen muss. Was muss ich da jetzt 
hinschreiben? Eins nach links verschieben? Das versteh ich grad nicht 
tut mir Leid...

Die Adresse meines Controllers ist 0x02, das Register in das ich 
schreiben möchte ist 0x0D und dorf möchste ich beispielweise den Wert 
0xFF hineinschreiben.

ICH habe die Adresse nicht geändert... Ich habe mir das ZIP-File aus dem 
vorletzten Beistrag heruntergeladen (PWM18_V7.zip) dort sind sämtliche 
hex-files für sämtliche Adressen vorhanden.

Chriss

von Chriss (Gast)


Lesenswert?

up

von Oliver (Gast)


Lesenswert?

Die TWI-Adresse hat 7 bit. Diese wird über den Bus "linksbündig" 
übertragen, das 8 Bit des Bytes ist das lesen/schreiben-flag.

DIe lib von Peter Fleury erwartet die 7-Bit-Adresse linksbündig. Wenn 
dein Baustein also offiziell die Adresse 0b0000010 = 0x02 hat, musst du 
da draus du da draus 0b00000100 = 0x04 machen.

Oliver

von Chriss (Gast)


Lesenswert?

Ich habe ersteinmal in der i2cmaster.s meine Pins richtig eingestellt 
was ich total übersehen habe. Mit der Adresse 0x02 und folgendem 
Programm funktioniert der Bus auch soweit ich das am Scope beurteilen 
kann:
1
int main(void)
2
{
3
4
i2c_init();
5
lcd_init();
6
lcd_clear();
7
int i = 0x00;
8
9
while(1)
10
{
11
  i2c_start_wait(0x02 + I2C_WRITE);
12
  i2c_write(0x0D);                          // 8bit Information - adresse 0 
13
  i2c_write(i);        // 8bit Information - adresse 1 
14
  i2c_stop();                          // stopt I2C Verbindung
15
16
  _delay_ms(100);
17
  i++;
18
  
19
}
20
}

Am Scope kann ich hier sehen wie das eine Byte immer weiter hochgezählt 
wird. Ändere ich die Adresse auf 0x04 tut sich auf dem Bus nichts mehr 
also scheint der Master den Slave ja schonmal irgendwie zu erkennen 
oder?
Dabei fällt mir allerdings auf das die Clock nicht wirklich das tut was 
sie meiner Meinung nach tun sollte. Sollte die nicht immer gleich 
bleiben? Am Scope siehts so aus als wenn zwischendurch mal ein Puls 
ausgelassen wird.

Chriss

von Chriss (Gast)


Lesenswert?

Habe jetzt nocheinmal den funktionierenden Code von MikroC reingeladen 
und da ist mir aufgefallen dass die Clock von Fleury ca. 4mal so schnell 
ist. Liegt also bei 400 statt 100kHz.
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif
4
5
/* I2C clock in Hz */
6
#define SCL_CLOCK  100000L

Also Quarz und Busfrequenz scheinen richtig eingestellt zu sein. Dann 
habe ich noch das hier gefunden:
1
;*************************************************************************
2
; delay half period
3
; For I2C in normal mode (100kHz), use T/2 > 5us
4
; For I2C in fast mode (400kHz),   use T/2 > 1.3us
5
;*************************************************************************
6
  .stabs  "",100,0,0,i2c_delay_T2
7
  .stabs  "i2cmaster.S",100,0,0,i2c_delay_T2
8
  .func i2c_delay_T2  ; delay 5.0 microsec with 4 Mhz crystal  
9
i2c_delay_T2:        ; 4 cycles
10
  rjmp 1f      ; 2   "
11
1:  rjmp 2f      ; 2   "
12
2:  rjmp 3f      ; 2   "
13
3:  rjmp 4f      ; 2   "
14
4:  rjmp 5f      ; 2   "
15
5:   rjmp 6f      ; 2   "
16
6:  nop          ; 1   "
17
  ret          ; 3   "
18
  .endfunc     ; total 20 cyles = 5.0 microsec with 4 Mhz crystal

Kann es sein dass mein Bus hier als fast eingestellt ist? Wie stell ich 
das um? use T/2 > 5us? Was muss ich hier tun?

von Rene K. (draconix)


Lesenswert?

Chriss schrieb:
> Schön dachte
> ich mir, krall ich mir das Header-File vom TWI aus dem Programm was ja
> irgendwo im Mikroelektronika-Ordner liegen wird. Allerdings hat der
> Hersteller der Entwicklungsumgebung seine Headerfiles irgendwie so
> geschrieben dass ich damit mal garnichts anfangen kann.

Kein Wunder, die "Source" Files sind alle verschlüsselt. Liegen übrigens 
in \\uses\..

Warum nutzt du nicht weiterhin die MikroC Routine mit I2C? Wenn es doch 
tadellos funktioniert?!

Was mich nun aber ein bisschen wundert ist dein delay Aufruf. In MicroC 
wird doch delay_ms() anstatt _delay_ms() geschrieben.

Schonmal mit der Soft_I2C Routine von MikroC probiert? Gerade MikroC ist 
ja was I2C/TWI, UART, SPI etc. angeht relativ zuverlässig.

von Chriss (Gast)


Lesenswert?

Hallo Rene

Ich nutze mikroC nicht da ich die I2C libary in ein vorhandenes Projekt 
einbauen will. MikroC kennst viele Befehle nicht die ich da nutze und 
schiebt mir unmengen von Fehlermeldungen raus. Würde gerne weiter in 
AVRgcc im programmers notepad mit WinAVR programmieren da ich das 
einfach gewohnt bin... Mein nächstes Projekt werde ich wohl mal komplett 
in mikroC versuchen. Vorallem weil hier jemand seine Vollversion (wo 
auch immer der unterschied zu der frei verfügbaren ist) nicht mehr haben 
will ;)

Mit dem _delay_ms hast du recht dass muss natürlich delay_ms heißen ;)
Hatte gestern ein seltsames copy-paste problem und musste von Hand hier 
nochmal reinschreiben dabei hab ich mich wohl vertan ;)

Jemand eine Ahnung wie ich die Taktfrequenz auf 100kHz runter bekomme?

Chriss

von Rene K. (draconix)


Lesenswert?

Chriss schrieb:
> Ich nutze mikroC nicht da ich die I2C libary in ein vorhandenes Projekt
> einbauen will. MikroC kennst viele Befehle nicht die ich da nutze und
> schiebt mir unmengen von Fehlermeldungen raus. Würde gerne weiter in
> AVRgcc im programmers notepad mit WinAVR programmieren da ich das
> einfach gewohnt bin... Mein nächstes Projekt werde ich wohl mal komplett
> in mikroC versuchen. Vorallem weil hier jemand seine Vollversion (wo
> auch immer der unterschied zu der frei verfügbaren ist) nicht mehr haben
> will ;)

Achso... ja jetzt verstehe ich das :D Ich entwickle von Anfang an mit 
MicroC, hat ganz klar seine Vorteile und aber auch Nachtteile - eben auf 
Grund der anderen definitionen zu GCC oder AVRStudio. Ich würde gerne 
mal ein komplettes Projekt in WinAVR machen :D

Der Unterschied Demo-/Vollversion ist übrigens ausschließlich die zu 
compilierende Codegröße. Mit der Demo kannst du ausschließlich 2kb Hex 
Files schreiben.

von Chriss (Gast)


Lesenswert?

Und dann fragen die sich so einen Haufen Geld dafür? Könnten die nicht 
wenigstens ihre TWI Libary freigeben dann wäre mir geholfen...

Ich frage mich gerade ob die falsche Taktfrequenz etwas mit meinem Quarz 
zu tun hat... habe 16MHz drin. Im Originalcode sind 4MHz definiert -> 4 
fache frequenz -> bus 4mal schneller? Aber ich habe im makefile doch 
16MHz eingestellt. Trozdem bekomme ich folgende Fehlermeldung:

#warning "F_CPU not defined for <util/delay.h>

Also scheint das ja nicht zu funktionieren. Ins makefile habe ich 
einfach "F_CPU = 16000000UL" geschrieben wie bei all meinen anderen 
Projekten auch nur hier meckert die delay.h noch rum.

Chriss

von Chriss (Gast)


Angehängte Dateien:

Lesenswert?

ES LÄUFT! ES LÄUFT! ES LÄUFT!!!

Ich weiß nicht warum aber anscheinend hatte das programmers notepad 
irgendein Problem damit. IM AVR Studio läufts einwandfrei! Ich hänge die 
Datei mal an falls die jemand brauchen kann.

Die Software macht nix anderes als eine LED hoch zu dimmen und wieder 
von vorne ;)

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.