Forum: Mikrocontroller und Digitale Elektronik I2C / TWI mit AT91SAM7


von Schmidi (Gast)


Lesenswert?

Guten Morgen!

Hat hier vielleicht schon jemand mal das TWI Interface vom AT91SAM7
programmiert (z.B. in C). Bin grad dabei das ganze zu versuchen, hab
aber jede Menge Probleme. z.B. kann ich einen PIO vom SAM7 aus als
Master ansprechen - klappt aber nur ca. 10-300 mal. Dannach gibts kein
TXRDY mehr. Auch am Oszi sieht man nichts mehr. Wenn man TXRDY
ignoriert und nach einem Timeout TWI neu initialisiert aendert das auch
nichts mehr...

Vielleicht hat ja wer Erfahrung mit dem SAM7 TWI Interface...

Viele Gruesse,
Schmidi

von Philip K. (praktikant)


Lesenswert?

hm, so wies scheint hat keiner was?! bin daran natürlich auch sehr 
interessiert, sitze auch extrem auf dem trockenen mit meinem 
AT91SAM7S256 und TWI

von Dirk D. (dirkd)


Lesenswert?

Wenn Du mal Code postet kann man Dir auch besser helfen.

Code-Beispiele für TWI findest Du z. B. auf www.at91.com

Dort

KIT->AT91SAM7S64-IAR

auswählen. Dort gibt es Source-Code für Flash, ADC, Interrupt, PDC und 
auch für TWI

von Philip K. (praktikant)


Lesenswert?

Hallo!

Habe bei mir grade vor, durch den folgenden Code, den ich aus der 
IAR-Vorlage und meinem Basiswissen C zusammengepfriemelt habe, einfach 
nur das Clock-Signal und immer eine Zahl von 0...200 auszugeben.
Funktioniert aber nicht. Was hab ich daran falsch gemacht? Vergessen, 
noch wichtige Register zu programmieren?!




#include "board.h"
#include "lib_twi.h"
#include "AT91SAM7S256.h"
//#include "main.h"

#define ERROR (AT91C_TWI_NACK)

AT91S_TWI * pTWI = AT91C_BASE_TWI;
//*=========================================================
//*    INIT
//*=========================================================
//*--------------------------------------------------------------------- 
-------
//* \fn    AT91F_SetTwiClock
//* \brief Initialization
//*--------------------------------------------------------------------- 
-------
void AT91F_SetTwiClock(void)
{
  int sclock;

  /* Here, CKDIV = 1 and CHDIV=CLDIV  ==> CLDIV = CHDIV = 
1/4*((Fmclk/FTWI) -6)*/

  sclock = (10*MCK /AT91C_TWI_CLOCK);
  if (sclock % 10 >= 5)
    sclock = (sclock /10) - 5;
  else
    sclock = (sclock /10)- 6;
  sclock = (sclock + (4 - sclock %4)) >> 2;  // div 4

    pTWI->TWI_CWGR  = ( 1<<16 ) | (sclock << 8) | sclock  ;
}
void AT91F_StartTWI(void)
{
   pTWI->TWI_CR = 0x05;
}

void AT91F_StopTWI(void)
{
   pTWI->TWI_CR = 0x06;
}

int send_INT(void)
{
  int i=0;

   AT91F_StartTWI();
  AT91F_StopTWI();

  for (i=0; i<200; i++)
  {
    i=pTWI->TWI_THR;
  }
  return 0;
}

int main(void)
{
  while(1)
  {
    AT91F_SetTwiClock();
    send_INT();
  }
  return 0;
}

von Dirk D. (dirkd)


Lesenswert?

> Was hab ich daran falsch gemacht?

Ok, fangen wir mal an:

1. Vernünftige Fehlerbeschreibung.
 "Funktioniert nicht" ist nicht sehr aussagekräftig. Ich nehme mal an, 
daß Du das ganze mit einem Oszi überprüfst, aber nicht einmal ein 
Clock-Signal siehst. Richtig?

2. Start. Dann Stop. Dann Daten lesen?????

Bist Du sicher, daß es das ist was Du willst?

Dann veränderst Du auch noch in der for-Schleife  die Schleifenvariable 
i. Das willst Du bestimmt nicht. So wie es da steht wird die Schleife 
vermutlich nur einmal ausgeführt (Wenn pTWI->TWI_THR 0xFF liefer; wie 
ich jetzt einfach mal annehme).

3. Kein Initialisieren des TWI

Ist Dir die Methode

void AT91F_TWI_Open(void)

aus dem Beispiel entgangen? Und warum hast Du nicht die anderen Methoden 
verwendet (AT91F_TWI_ReadByte, AT91F_TWI_WriteByte)? Die machen doch 
genau das was Du willst



von Philip K. (praktikant)


Lesenswert?

Hallo Dirk.
Mal wieder ein Dankeschön an dich zwecks deines Beitrags.

Dirk Dörr wrote:
> 1. Vernünftige Fehlerbeschreibung.
>  "Funktioniert nicht" ist nicht sehr aussagekräftig. Ich nehme mal an,
> daß Du das ganze mit einem Oszi überprüfst, aber nicht einmal ein
> Clock-Signal siehst. Richtig?

Richtig g

> 2. Start. Dann Stop. Dann Daten lesen?????
>
> Bist Du sicher, daß es das ist was Du willst?

Habe auf www.at91.com im Forum nach TWI working gesucht und das, was da 
kam schien genau so gemeint zu sein.

> Dann veränderst Du auch noch in der for-Schleife  die Schleifenvariable
> i. Das willst Du bestimmt nicht. So wie es da steht wird die Schleife
> vermutlich nur einmal ausgeführt (Wenn pTWI->TWI_THR 0xFF liefer; wie
> ich jetzt einfach mal annehme).
>
> 3. Kein Initialisieren des TWI
>
> Ist Dir die Methode
>
> void AT91F_TWI_Open(void)
>
> aus dem Beispiel entgangen?

Genau die habe ich jetzt verwendet. Nur meckert jetzt natürlich der 
Linker, weil er in keiner Datei die vordefinierten Funktionen
AT91F_TWI_CfgPIO ();
AT91F_TWI_CfgPMC ();
AT91F_TWI_Configure (AT91C_BASE_TWI);
AT91F_SetTwiClock();

findet.

Nun stehe ich wieder da wie der Ochs' vorm Berg.

Habe meinen Quellcode jetzt auch etwas verändert. Wenn dir das hilft, 
kann ich ihn gerne wieder posten.

Gruß

der Praktikant

von Dirk D. (dirkd)


Lesenswert?

Hi,

sicher hilft der Quellcode. Ich habe aber im Moment nicht viel Zeit.

> AT91F_SetTwiClock();

ist auch in der libtwi.c

Der Rest stammt aus dem Standard-Headerfile lib_AT91SAM7S64.h.

von Philip K. (praktikant)


Lesenswert?

Okay, obiges Problem gelöst.

Nur meckert der Compiler nun an der lib_AT91SAM7S256.h rum.

Die neue fehlermeldung bezüglich des lib_AT91SAM7S256.h ist:

lib_AT91SAM7S256.h(52): error:  #77-D: this declaration has no storage 
class or type specifier
lib_AT91SAM7S256.h(52): error:  #65: expected a ";"
lib_AT91SAM7S256.h(2297): warning:  #12-D: parsing restarts here after 
previous syntax error
lib_AT91SAM7S256.h(2300): error:  #169: expected a declaration
D:\Keil\ARM\RV30\INC\stdio.h(301): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(382): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(402): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(529): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(554): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(689): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(690): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(690): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(705): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(706): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(721): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(722): error:  #20: identifier "size_t" is 
undefined
D:\Keil\ARM\RV30\INC\stdio.h(722): error:  #20: identifier "size_t" is 
undefined

was zum Geier ist denn da schon wieder los?

Gruß

der Praktikant

von Dirk D. (dirkd)


Lesenswert?

Vorschlag:

Wenn Du mit dem WinARM gcc arbeitest:

Nimm eines der Beispiele für den Sam7S64. Ändere es so, daß es für 
Deinen ARM passt. Dann füge die libtwi.c + h zu Deinem Projekt und 
verwende sie.

Schritt für Schritt.

von Philip K. (praktikant)


Lesenswert?

Hallo Dirk!

So bin ich ja auch vorgegangen. Schritt für Schritt habe ich die 
benötigten Dateien eingefügt....

von Philip K. (praktikant)


Lesenswert?

Hallo!

Ist mein Projekt, das Display per I2C (TWI) anzusteuern denn mit einem 
AVR (ATmega8 bzw. ATmega128) einfacher zu realiesieren. Bzw. wie würdet 
ihr ein Display vorzugsweise ansteuern?!
Und wie sieht es mit der Handhabeung des AD-Wandlers bei AVRs aus?! 
Klappt das sowohl bei ARM als auch bei AVR gleich problemlos. Denn mit 
meinem AT91SAM7S256 hatte und habe ich sehr große Probleme, das zu 
realisieren....

Gruß

der Praktikant

von Dirk D. (dirkd)


Lesenswert?

Hallo Philip,

es stimmt zwar, daß ein AVR einfacher anzusteuern ist als z. B. ein SAM7 
aber ich fürchte Du wirst auch dann Deine Probleme haben.

Dir fehlt es schlicht an Programmiererfahrung. Vielleicht solltest Du 
erst einmal ein gutes C-Buch mit Übungen besorgen und Dir am PC die 
Grundlagen erarbeiten bevor Du es weiter mit µCs versuchst.

Wenn Du aber doch noch Dein LCD Problem lösen willst, stell einfach mal 
Dein komplettes Projekt als Zip ein.

Gruß

   Dirk

von Klaus (Gast)


Lesenswert?

Hallo,

ich versuche mich auch gerade am I2C des AT91SAM7X256, aber bisher sehe 
ich auf dem Oszi nur den Takt und das Adress-Byte. Nach Fünf weiteren 
Clocks stellt der Controller dann den Sendevorgang ein. Momentan 
verwende ich die Realisierung aus dem Atmel Softwarepackage 1.5 --> Weiß 
jemand, ob die mittlerweile funktioniert? Im ersten Abschnitt dieses 
Artikels steht das ja etwas schwammig: 
http://www.mikrocontroller.net/articles/AT91-TWI

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.