I2C / TWI mit AT91SAM7

Gast #333616
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
#472271
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;
}
#472651
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


#472828
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
#472882
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
#473647
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
#474168
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
Gast #1765212
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

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