Code-Rätsel: SPI in Bascom und C mit Atmega8

#3851378
Lesenswert?

Hallo zusammen,

ich steuere mit meinem Atmega8 einen Trinamic TMC429 über SPI an. Alles 
funktioniert wunderbar mit meinem kleinen Bascom-Programm:
1
$regfile = "M8def.dat"
2
$crystal = 16000000
3

4
Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 16 , Noss = 1
5

6
Config Portb.2 = Output   'SS as Output
7

8
Dim Re1 As Byte
9
Dim Re2 As Byte
10
Dim Re3 As Byte
11
Dim Re4 As Byte
12

13
Spiinit
14

15
Portb.2 = 0
16
Re1 = Spimove(126)
17
Re2 = Spimove(1)
18
Re3 = Spimove(7)
19
Re4 = Spimove(33)
20
Portb.2 = 1


Ich möchte nun das Ganze nach C übersetzen. Mein C-Code sieht so aus:
1
#include <avr/io.h>   
2

3
unsigned char spi_tranceiver (unsigned char data)
4
{
5
    SPDR = data;
6
    while(!(SPSR)&(1<<SPIF));
7
    return(SPDR);
8
}
9

10

11
int main (void)
12
{            
13
  DDRB |= (1<<DDB2)|(1<<DDB3)|(1<<DDB5);    // SS, MOSI and SCK as outputs
14
  DDRB &= ~(1<<DDB4);                     // MISO as input
15

16
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL)|(1<<CPHA);
17

18
  PORTB &= ~(1<<PB2);
19
  spi_tranceiver(126);
20
  spi_tranceiver(1);
21
  spi_tranceiver(7);
22
  spi_tranceiver(33);
23
  PORTB = (1<<PB2); 
24
}

In C scheint die SPI-Übertragung nicht zu funktionieren, da sich die 
angeschlossenen Schrittmotoren nicht rühren. Vielleicht kann mir jemand 
von euch auf die Sprünge helfen. Wo liegt der entscheidende Unterschied 
zum Bascom-Programm?
Gast #3851418
Lesenswert?

PORTB = (1<<PB2);

sollte eher

PORTB |= (1<<PB2);

heissen. Daran wird es aber vermutlich nicht liegen.
Hast du ein Speicher-Oszilloskop zur Verfügung?
Dann würde ich an deiner Stelle damit mal die Kommunikation 
(SS/MOSI/SCK) beider Programme mitschneiden und vergleichen.
Gast #3851484
Lesenswert?

Rudolph schrieb:
> Bist Du sicher, dass an dieser Stelle das Programm aufhören soll?
> Damit geht der Controller alle paar Dutzend µs durch den Reset.

warum sollte er in den Reset gehen?

hinter der main baut der linker eine Endlosschleife ein, es passiert als 
nichts danach.
#3851774
Lesenswert?

Micael schrieb:
> C is nix für Leute die mit Basic rumspielen.

C ist vor allen Dingen nix für Leute, die meinen man müsse alle 
Möglichkeiten ausnutzen, die einem die dichte Schreibweise von C bietet.

Mit ein paar Leerzeichen, auch wenn sie syntaktisch nicht notwendig 
sind, wird so mancher Fehler auch schon aus der Ferne sichtbar.

So geschrieben
1
   while( !(SPSR) & (1<<SPIF) )
2
     ;

wär wahrscheinlich früher aufgefallen, dass das ! den falschen Bezug 
hat.

Aber: irgendwann lernts jeder, dass Schreibweisen einen Einfluss auf die 
Fehlerhäufigkeit haben.
Genauso wie es die meisten früher oder später lernen, dass ein 'return' 
kein Funktionsaufruf ist, und daher die Klammerung des Rückgabewertes 
unnötig ist
1
   return(i);
1
   return i;
Zweiteres ist sogar trotz weniger Tippaufwand dann sogar noch einfacher 
zu lesen.
Oder schreibst du auch
1
   i = (j);
und klammerst die rechte Seite einer Zuweisung auf jeden Fall immer ein?
Nichts anderes beim return. Dei Syntax ist
1
   return Expression
und die Expression ist genau dieselbe Expression, die überall in C an 
den verschiedensten Stellen vorkommt und dort nirgends generell 
eingeklammet wird. Nur beim return ist irgendwie alles anders, wohl weil 
K&R in ihrem Buch das so vorgemacht haben.

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