TWI Atmega32 Anfang

Gast #3686137
Lesenswert?

Versuche mich nun mit TWI aus dem Tut's werdee ich leider nur langsam 
schlau..deswegen habe ich mir mal eine Funktion zusammen geschrieben um 
es mir selber näher zu bringen...natürlich ist noch einiges vom Tut 
übernommen und ich wollte bevor ich was Eigens schreibe erst mal die 
Funktion testen.

Verwenden tue ich ein PCF8574 an dem ne 7 Segment anzeige hängt.

Es funktioniert aber leider nicht, evtl. stimmt was mit dem Code nicht ?
Oder kann dies überhaupt funktionieren ? Sollte ich lieber Start / Stop 
 Daten  Adresse / Init einzeln als Funktion aufrufen ?
1
unsigned char TWI_Funktion(unsigned char address,unsigned char daten){
2
  
3
   uint8_t   twst;
4
  
5
  
6
  TWSR = 0;                         /* no prescaler */
7
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  
8
  
9
  
10
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
11
  
12
  // wait until transmission completed
13
  while  (!(TWCR & (1<<TWINT))); 
14
  
15
  twst = TW_STATUS & 0xF8;
16
  if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
17
  
18
  // sende address
19
  TWDR = address;
20
  TWCR = (1<<TWINT) | (1<<TWEN);
21
  
22
  // wait until transmission completed
23
  while(!(TWCR & (1<<TWINT)));
24
  
25
  twst = TW_STATUS & 0xF8;
26
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
27
  
28
  /*TWDR ..Daten werden gesendet*/
29
  TWDR = daten;
30
  /*send content of TWDR*/
31
  TWCR = (1<<TWINT) | (1<<TWEN);
32
  // wait until transmission completed
33
  while (!(TWCR & (1<<TWINT)));
34
  
35
  // send stop condition 
36
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
37
  
38
  // wait until stop condition is executed and bus released
39
  while(TWCR & (1<<TWSTO));
40
  
41
  
42
  
43
}


Aufgerufen in der Main mit ...
1
TWI_Funktion(0b01000000,0b11111111);
#3686155
Lesenswert?

Jakob schrieb:

> Es funktioniert aber leider nicht, evtl. stimmt was mit dem Code nicht ?

Das mag schon sein.

> Oder kann dies überhaupt funktionieren ? Sollte ich lieber Start / Stop
>  Daten  Adresse / Init einzeln als Funktion aufrufen ?

Letzten Endes wird es irgendwan darauf hinaus laufen. Allerdings ist das 
nicht dein Problem - es kann nicht dein Problem sein. Denn der Code ist 
ja derselbe, egal ob du jetzt alles in einer Funktion hast, oder ob du 
mehrere Funktionen hast.

Fang halt mal mit Debugging an. Ja, da muss man sich dann eben was dazu 
überlegen. Wenn man gar nichts anderes hat, dann baut man sich eben an 
einen Port ein paar LED und sieht zu, dass man mit Leuchtmustern auf 
diesen LED dem Programm die Information entlocken kann, was es wann und 
warum gemacht hat, bzw. welcher Fehlerzustand aufgetreten ist.

Du gibst hier
1
>   twst = TW_STATUS & 0xF8;
2
>   if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
zb einen Fehlerstatus zurück, benutzt ihn aber an der aufrufenden Stelle 
nicht.
Ichg würde mal meinen, dass sich so ein Fehlerstatus hervorragend dazu 
eignen würde, dir als Entwickler mitzuteilen: Huston, wir haben ein 
Problem und zwar ist der Fehlerstatus 1 aufgetreten.

>   twst = TW_STATUS & 0xF8;
>   if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

Dann wäre es eine gute Idee, hier nicht 1 als Fehlerstatus zu verwenden, 
sondern eine andere Zahl. Denn mit dieser Anderen Zahl erzählen dir dann 
die LED die Geschichte, dass es hier ein Problem gegeben hat.

etc. etc.
Ja, auch Debugging und "wie kann ich mir helfen dem Programm zu 
entlocken was Sache ist" muss gelernt werden.

Ich persönlich würde mir ja erst mal vom P.Fleury die TWI Routinen holen 
und mit denen kontrollieren, ob die Hardware in Ordnung ist, ehe ich 
eigene Routinen schreibe
Gast #3686169
Lesenswert?

Ich werd mich mal mit dem Debuggen befassen und gucken ob ich ein Fehler 
finde. Ob der PCF was ausgibt würde ich an der Segment Anzeige sehen.

Die Adresse wäre 0b01000000 da ich an den Adress PINs nix anliegen habe.

Werde jetzt auch erstmal mitn Ozi gucken ob der Atmega überhaupt was 
ausgibt.

Dann auchmal mit der Routine von P.Fleury
#3686174
Lesenswert?

Jakob schrieb:
> Ich werd mich mal mit dem Debuggen befassen und gucken ob ich ein Fehler
> finde. Ob der PCF was ausgibt würde ich an der Segment Anzeige sehen.

Das war mir schon klar :-)

>
> Die Adresse wäre 0b01000000 da ich an den Adress PINs nix anliegen habe.

wörtlich 'nix' oder hast du dort Pulldowns bzw. direkte Verbindungen zu 
GND?

Auf die Schnelle hab ich im Datenblatt nicht gefunden, ob man die Pins 
offen lassen kann. Sicherheitshalber mit GND verbinden (entweder direkt 
oder über einen Pulldown).

> Werde jetzt auch erstmal mitn Ozi gucken ob der Atmega überhaupt was
> ausgibt.

Auch eine gute Idee.
Gast #3686211
Lesenswert?

Sooooo...natürlich hat der Herr hat natürlich die SCl SDA falsch 
angeschlossen...aber arbeiten tut das ganze nicht =D

Am SDA Ausgang liegt was anständiges an, aber am SLC nur Quatsch . Hab 
jetzt für's erste die Routine genommen. Nur die Frequenz auf 16Mhz 
geänder sonst nix...meine Main sieht wie Folgt aus :
1
/*
2
 * i2c_Testlauf.c
3
 *
4
 * Created: 11.06.2014 10:38:10
5
 *  Author: Jakob
6
 */ 
7

8

9
#include <avr/io.h>
10
#define F_CPU 16000000UL
11
#define SCL_CLOCK  100000L
12
#include <util/delay.h>
13
#include <avr/interrupt.h>
14
#include <util/twi.h>
15
#include "i2cmaster.h"
16

17

18
int main(void){
19
  
20
  DDRB = 0xff;
21
  DDRD = 0x00;
22
  DDRA = 0x00;
23
  DDRC = 0x03;
24
  
25
  
26
  
27
  
28
  
29
  
30
  while(1)
31
  {
32
    
33
    i2c_init();
34
    i2c_start(0b01000000);
35
    i2c_write(0xFF);
36
    i2c_stop();
37
  
38
  
39
    _delay_ms(1000);
40
    
41
    i2c_init();
42
    i2c_start(0b01000000);
43
    i2c_write(0x00);
44
    i2c_stop();
45
    
46
    _delay_ms(1000);
47
  }
48
}
Angehängte Dateien:
Gast #3686551
Lesenswert?

Durch das Pull-up setzten von SDA und  SCL hab ich jetzt ein 
vernünftiges  Clock Signal, aber...Das Daten Signal liegt bei ca. 3,3V 
ist ja ok halt die Atmega Spannung aber das Signal liegt nur dann an 
wenn ich Debugge also das Programm starte, stoppe ich dies ist das 
Signal weg, und liegt bei 3,3V (Konstante Spannung) stecke ich den JTAG 
ab liegen die 5V an...

Kann mir das wer helfen hier nochmal der Code
1
/*
2
 * i2c_Testlauf.c
3
 *
4
 * Created: 11.06.2014 10:38:10
5
 *  Author: Jakob
6
 */ 
7

8

9
#include <avr/io.h>
10
#define F_CPU 16000000UL
11
#define SCL_CLOCK  100000L
12
#include <util/delay.h>
13
#include <avr/interrupt.h>
14
#include <util/twi.h>
15
#include "i2cmaster.h"
16

17

18
int main(void){
19
  
20
  DDRB = 0xff;
21
  DDRD = 0x00;
22
  DDRA = 0x00;
23
  DDRC  = (1<<PC0) | (1<<PC1);
24
  PORTC = (1<<PC0) | (1<<PC1);
25
  
26
  
27
  
28
  
29
  
30
  while(1)
31
  {
32
    
33
    i2c_init();
34
    i2c_start(0b01000000);
35
    i2c_write(0xFF);
36
    i2c_stop();
37
  
38
  
39
    _delay_ms(1000);
40
    
41
    i2c_init();
42
    i2c_start(0b01000000);
43
    i2c_write(0x00);
44
    i2c_stop();
45
    
46
    _delay_ms(1000);
47
  }
48
}
Gast #3687299
Lesenswert?

Die Pull-Up Widerstände benutze ich intern.
Es kommt was am PCF an, messen tue ich das mit einem Ozi.

Aber Ich vermute dass, das Signal was ankommt zu niedrig ist, die Spitze 
ist 3,3V müsste eigentlich ja 5V sein wenn ich mich nicht vertue?

Aber auch nur wenn das Programm läuft wenn ich es stoppe im AVR-Studio 
liegt nur noch die 3,3V Konstante Spannung an, ist der JTAG ab liegen 5V 
an aber kein Signal mehr.
Gast #3687311
Lesenswert?

Hi

>Die Pull-Up Widerstände benutze ich intern.

Die sind um etwa eine Größenordnung zu groß.

>Es kommt was am PCF an, messen tue ich das mit einem Ozi.

>Aber Ich vermute dass, das Signal was ankommt zu niedrig ist, die Spitze
>ist 3,3V müsste eigentlich ja 5V sein wenn ich mich nicht vertue?

>Aber auch nur wenn das Programm läuft wenn ich es stoppe im AVR-Studio
>liegt nur noch die 3,3V Konstante Spannung an, ist der JTAG ab liegen 5V
>an aber kein Signal mehr.

Riecht nach einem Schaltungsfehler.

MfG Spess
Gast #3687501
Lesenswert?

Hi

>Ja aber Pc0 Pc1 leigen auf der Platine ja offen und haben keine
>Verbindung zu anderen Sachen, und selbst wenn ich diese nicht mit dem
>PCF Verbinde kommt das Problem.

Gib dir mal etwas mehr Mühe. Es kann doch nicht so schwer sein auch noch 
den letzten Rest sinnvoller Informationen aus deinen Aussagen zu 
entfernen.

MfG Spess
#3687520
Lesenswert?

spess53 schrieb:
> Hi
>
>>Die Pull-Up Widerstände benutze ich intern.
>
> Die sind um etwa eine Größenordnung zu groß.

Wenn sie im Sondermodus TWI überhaupt funktionieren.

Ich denke, die Atmel Ingenieure haben sich schon etwas dabei gedacht, 
wenn sie im Datenblatt (Seite 169) schreiben
1
The only external hardware needed to implement the bus is a single
2
pull-up resistor for each of the TWI bus lines.
und die entsprechenden Widerstände in den Schaltskizzen auch 
einzeichnen.

Wenn die internen Pullup Widerstände funktionieren würden, dann würden 
sie das wahrscheinlich auch im TWI-Kapitel erwähnen. Tun sie aber nicht.
Gast #3687530
Lesenswert?

Hi

>Wenn die internen Pullup Widerstände funktionieren würden, dann würden
>sie das wahrscheinlich auch im TWI-Kapitel erwähnen.

Die funktionieren auch bei TWI.

Datenblatt, Alternate Port Funktions:

SDA – Port C, Bit 1
...
When this pin is used by the Two-wire Serial Interface, the pull-up can
still be controlled by the PORTC1 bit.

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren