www.mikrocontroller.net

Forum: Compiler & IDEs Probleme mit AT90CAN64 SPI Übertragung


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Für meine Arbeit muss ich einen AT90CAN64 programmieren. Habe leider 
damit keinerlei Erfahrung...

Das Programm soll den MAX1148 ADC auslesen. Da dieser nur 8 Kanäle hat, 
ich aber insgesamt 64 auslesen möchte, werden zudem über Port A 
Multiplexer gesteuert. Ich benutze die von Atmel für diesen MC zur 
Verfügung gestellt CAN software Libraries 
([[http://www.atmel.com/dyn/products/product_card.asp...]])

Mein Problem ist, dass ich mit dem Scope keinerlei Signale am SPI sehe.
Hier mein Code
//_____ I N C L U D E S ________________________________________________________
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/iocan64.h>
#include "compiler.h"
#include "at90can_drv.h"
#include "spi_lib.h"
#include "can_lib.h"

//_____ D E F I N I T I O N S __________________________________________________
    // -------------- MCU LIB CONFIGURATION
#define FOSC           8000                      // 8.000 MHz External cristal
#define F_CPU          (FOSC*1000)               // Need for AVR GCC

    // -------------- CAN LIB CONFIGURATION
#define CAN_BAUDRATE   250                       // in kBit

    // -------------- MISCELLANEOUS
#define ADCSTART       0x8e                      // c.f. MAX1146-1149 datasheet
#define ADCSSTRB       PINB4
#define NUM_CHANNELS   64
#define NUM_DATA       (NUM_CHANNELS*2)

volatile U8 channelSelect[8] = {0,4,1,5,2,6,3,7}; // c.f. MAX1146-1149 datasheet

U8 init(void)
{ 
  // --- enable interrupts
  Enable_interrupt();                         

  // --- init SPI; c.f. "spi_lib.c"
  U8 spi_config = (SPI_MASTER|SPI_MSB_FIRST|SPI_DATA_MODE_0|SPI_CLKIO_BY_64);
  if( spi_init(spi_config) ){
    Spi_init_ss();                              
    Spi_disable_ss();
  }
  else return (0);
                           
  // --- configure port A
  DDRA = (1<<DDA2)|(1<<DDA1)|(1<<DDA0);
  PORTA = 0x00;

  return (1);
}

void readAdc(unsigned int channel, U8 *result)
{
  U8 buffer[3];

  buffer[0] = ADCSTART | (channelSelect[channel%8] << 4);
  buffer[1] = 0; buffer[2] = 0;

  Spi_enable_ss();

  // --- Send control byte
  spi_transmit_master(buffer[0]);

  // --- Wait for conversion complete
  while(ADCSSTRB == 0);

  buffer[1] = spi_getchar();
  buffer[2] = spi_getchar();

  Spi_disable_ss();

  result[2*channel] = buffer[1];
  result[2*channel+1] = buffer[2];

  return;
}

int main(void)
{
  U8 meanValues[NUM_DATA];
  int channel;

  if(init()==0) return (0);

  while(1){
    for(channel=0; channel<NUM_CHANNELS; channel++){
      int value = channel/8;
      if((value != PORTA) && (value <= 7))
        PORTA = value;
      readAdc(channel,meanValues);
    } // for channel
    
  } // while(1)

}

Hat jemand eine Idee, woran es liegen könnte? Wenn ich die 3 Zeilen, in 
der ich Daten auf dem SPI hin und her schicke, auskommentiere, läuft 
alles so wie es soll...

Gruss
Florian

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mein Problem ist, dass ich mit dem Scope keinerlei Signale am SPI sehe.

Der wichtigste Teil des Programmes fehlt mal wieder :(
Nutzt du auch den SS Pin für das Slaveselect?

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies dir doch meinen Code durch!
Da kommen Kommandos vor die heißen
    Spi_init_ss();                              
    Spi_disable_ss();
Spi_enable_ss();

Auch ohne die "CAN Software Libraries" zu kennen, könnte man doch 
annehmen, dass das es sich um den SlaveSelect handelt, oder etwa nicht?!
(Sorry wenns ned eindeutig war)

Autor: codesuchender (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wo ist deine spi_lib.c ? Wo sind deine SPI-Makros definiert? Gibts nen 
Schaltplan? Glaskugel ist leider kaputt sorry ;-)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Lies dir doch meinen Code durch!

Habe ich getan.

>Da kommen Kommandos vor die heißen
>
>    Spi_init_ss();
>    Spi_disable_ss();
>Spi_enable_ss();

Benutzt du nun den SS Pin vom ATMega64 oder nicht?
Das kann ich dort nicht sehen.

>Auch ohne die "CAN Software Libraries" zu kennen, könnte man doch
>annehmen, dass das es sich um den SlaveSelect handelt, oder etwa nicht?!

Annehmen heisst nicht wissen.

Autor: Florian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sorry für meine Faulheit. Die spi_lib.c ist in den atmel libraries. der 
link ist oben...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Benutzt du nun den SS Pin vom ATMega64 oder nicht?

Sorry, vom AT90CAN..

Autor: Florian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
>Benutzt du nun den SS Pin vom ATMega64 oder nicht?
>Das kann ich dort nicht sehen.

es ist der at90can64, nicht der atmega....aber die o.g. Macros verwenden 
den SlaveSelect Pin...

So. Nun hab ich auch mal die Files aus den Atmel Libs mit angehangen

Autor: Florian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Auf die Frage nach dem Schaltplan, ist angehängt.
(Das Value des Crystals ist allerdings falsch. Der hat 8 und nicht 16 
MHz)
Mal ne Frage, kann man auch mehr als eine Datei an nen Post anhängen, 
oder muss man die dazu in nen Archiv parken?!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich seh nix, außer das

Bool spi_init (U8 config)

so aussehen müsste wegen der Clock Macros

Bool spi_init (U16 config)

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich seh nix, außer das
>
>Bool spi_init (U8 config)
>
>so aussehen müsste wegen der Clock Macros
>
>Bool spi_init (U16 config)

Ne! Wenn man mal durchzählt:
SPI_MASTER      1 Bit
SPI_MSB_FIRST   1 Bit
SPI_DATA_MODE_0 2 Bit
SPI_CLKIO_BY_64 3 Bit
SPI_enable      1 Bit
Macht insgesamt 8 Bit...
demnach ist U8 richtig

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups! Hab mich vertan! spi_enable gehört ja gar ned zur variable 
config...
Aber dann passt U8 immernoch

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber dann passt U8 immernoch
    // ---------- Pre-definitions for relationship between SCK and CLKIO (16-bit)
    // ---------- (The 9th is the Double SPI Speed Bit: SPI2X of SPSR)
#define SPI_CLKIO_BY_2            ((1<<(SPI2X+8))|(0<<SPR1)|(0<<SPR0)) // -- 0x100

Und was sagt dir das?
Aber hast recht, bei seiner Clockeinstellung reicht U8.

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Aber dann passt U8 immernoch
    // ---------- Pre-definitions for relationship between SCK and CLKIO (16-bit)
    // ---------- (The 9th is the Double SPI Speed Bit: SPI2X of SPSR)
#define SPI_CLKIO_BY_2            ((1<<(SPI2X+8))|(0<<SPR1)|(0<<SPR0)) // -- 0x100
>Und was sagt dir das?
>Aber hast recht, bei seiner Clockeinstellung reicht U8.

Mkay! Vom MC und seinen Registern her sind es 16 Bit. Das stimmt.

Aber ich denke mal, dass Atmel das schon richtig macht, da die diese 
Libs selber zum Programmieren verwenden...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Aber ich denke mal, dass Atmel das schon richtig macht, da die diese
>Libs selber zum Programmieren verwenden...

Dann hat von denen aber noch niemand versucht
SPI_CLKIO_BY_2 einzustellen ;)

Hier ist auch noch ein Tippfehler (macht aber nix)
#define Spi_enable_ss()           (PORTB &= ~(1<<DDB0))  // -- Can be user re-defined 

Und da sind die Kommentare falsch
#define SPI_CLKIO_BY_64           ((0<<(SPI2X+8))|(1<<SPR1)|(0<<SPR0)) // -- 0x102
#define SPI_CLKIO_BY_128          ((0<<(SPI2X+8))|(1<<SPR1)|(1<<SPR0)) // -- 0x103


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hier ist auch noch ein Tippfehler (macht aber nix)
#define Spi_enable_ss()           (PORTB &= ~(1<<DDB0))  // -- Can be user re-defined 
Was denn?! Habe diese Variante beim Googlen schon des öfteren gesehen, 
nicht nur von Atmel...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was denn?! Habe diese Variante beim Googlen schon des öfteren gesehen,
>nicht nur von Atmel...

Ist ja auch nur ein Schönheitsfehler ;)

Hier ist das Problem
  buffer[1] = spi_getchar();
  buffer[2] = spi_getchar();

Vor jedem spi_getchar(); muß ein Dummybyte gesendet werden.
spi_getchar(); macht das nicht.

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hier ist das Problem

>  buffer[1] = spi_getchar();
>  buffer[2] = spi_getchar();

>Vor jedem spi_getchar(); muß ein Dummybyte gesendet werden.
>spi_getchar(); macht das nicht.

Ok! Hab ich eingebaut!
Und auch den Fehler mit dem U16 bei der Funktion spi_init hab ich 
behoben!
(Hab das nochmal nachgeguckt, und du hattest recht mit dem 16 bit...)

Allerdings funktioniert es immernoch ned...So wie es aussieht (habe zum 
debuggen nach jedem Schritt den Wert von Port c erhöht) kommt er nicht 
mal über das
  // --- Send control byte
  spi_transmit_master(buffer[0]);
von oben hinaus...

Jemand ne Idee wo der Fehler liegen könnte?!

Gruss
Florian

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void  spi_transmit_master(U8 ch)
{
    //-- Wait for transmission complete
    Spi_wait_eot();
//An dieser Stelle wird es vermutlich klemmen
//Einfach mal auskommentieren zum probieren
    
    //-- Start new transmission
    Spi_send_byte(ch);
}

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Holger!!!
Es funktioniert!!

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo euch allen,

ich bin schon seit einiger Zeit auf der Suche nach einem CAN-Bootlader
für den AT90CAN. Leider konnte ich dazu aber kein fertiges Projekt
finden.
Genauere Informationen gibt es unter fogendem Link:

Titel - Beitrag "CAN BUS Bootloader AT90CAN"

Ich hoffe es finden sich einige um dieses Projekt zu realisieren oder
die dabei helfen können.

Grüße martin

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.