Probleme mit AT90CAN64 SPI Übertragung

Gast #1329550
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?PN=AT90CAN64]])

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

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

15
    // -------------- CAN LIB CONFIGURATION
16
#define CAN_BAUDRATE   250                       // in kBit
17

18
    // -------------- MISCELLANEOUS
19
#define ADCSTART       0x8e                      // c.f. MAX1146-1149 datasheet
20
#define ADCSSTRB       PINB4
21
#define NUM_CHANNELS   64
22
#define NUM_DATA       (NUM_CHANNELS*2)
23

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

26
U8 init(void)
27
{ 
28
  // --- enable interrupts
29
  Enable_interrupt();                         
30

31
  // --- init SPI; c.f. "spi_lib.c"
32
  U8 spi_config = (SPI_MASTER|SPI_MSB_FIRST|SPI_DATA_MODE_0|SPI_CLKIO_BY_64);
33
  if( spi_init(spi_config) ){
34
    Spi_init_ss();                              
35
    Spi_disable_ss();
36
  }
37
  else return (0);
38
                           
39
  // --- configure port A
40
  DDRA = (1<<DDA2)|(1<<DDA1)|(1<<DDA0);
41
  PORTA = 0x00;
42

43
  return (1);
44
}
45

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

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

53
  Spi_enable_ss();
54

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

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

61
  buffer[1] = spi_getchar();
62
  buffer[2] = spi_getchar();
63

64
  Spi_disable_ss();
65

66
  result[2*channel] = buffer[1];
67
  result[2*channel+1] = buffer[2];
68

69
  return;
70
}
71

72
int main(void)
73
{
74
  U8 meanValues[NUM_DATA];
75
  int channel;
76

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

79
  while(1){
80
    for(channel=0; channel<NUM_CHANNELS; channel++){
81
      int value = channel/8;
82
      if((value != PORTA) && (value <= 7))
83
        PORTA = value;
84
      readAdc(channel,meanValues);
85
    } // for channel
86
    
87
  } // while(1)
88

89
}

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
Gast #1329572
Lesenswert?

Lies dir doch meinen Code durch!
Da kommen Kommandos vor die heißen
1
    Spi_init_ss();                              
2
    Spi_disable_ss();
3
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)
Gast #1329579
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.
Gast #1329585
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
Angehängte Dateien:
Gast #1329626
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
Gast #1329631
Lesenswert?

>Aber dann passt U8 immernoch
1
    // ---------- Pre-definitions for relationship between SCK and CLKIO (16-bit)
2
    // ---------- (The 9th is the Double SPI Speed Bit: SPI2X of SPSR)
3
#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.
Gast #1329640
Lesenswert?

>>Aber dann passt U8 immernoch
1
    // ---------- Pre-definitions for relationship between SCK and CLKIO (16-bit)
2
    // ---------- (The 9th is the Double SPI Speed Bit: SPI2X of SPSR)
3
#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...
Gast #1329646
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)
1
#define Spi_enable_ss()           (PORTB &= ~(1<<DDB0))  // -- Can be user re-defined

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

>Hier ist auch noch ein Tippfehler (macht aber nix)
1
#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...
Gast #1329655
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
1
  buffer[1] = spi_getchar();
2
  buffer[2] = spi_getchar();

Vor jedem spi_getchar(); muß ein Dummybyte gesendet werden.
spi_getchar(); macht das nicht.
Gast #1332386
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
1
  // --- Send control byte
2
  spi_transmit_master(buffer[0]);
von oben hinaus...

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

Gruss
Florian
Gast #1332421
Lesenswert?

1
void  spi_transmit_master(U8 ch)
2
{
3
    //-- Wait for transmission complete
4
    Spi_wait_eot();
5
//An dieser Stelle wird es vermutlich klemmen
6
//Einfach mal auskommentieren zum probieren
7
    
8
    //-- Start new transmission
9
    Spi_send_byte(ch);
10
}
Persönliche Seite #1581266
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

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