www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI - Attiny25 Master --> Atmega8 Slave


Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe folgendes Problem. Habe auf dem Attiny25 per USI einen SPI 
Master realisiert. Dieser schickt jede Sekunde ein Byte an einen Atmega8 
der als SPI Slave eingerichtet ist. Nun kann ich am SCK des Attiny25 
einen takt messen, aber auf dem Atmega8 wird der SPI Interrupt Flag 
(SPIF) nicht gesetzt, das heißt mein Atmega8 springt nie in die 
Empfangsroutine.
Sieht jemand einen fehler in meinem Code?

SPI-Slave auf Atmega8
#define F_CPU 8000000UL    // 8 MHz Takt
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.c"
#include <stdlib.h>

#define DDR_SPI DDRB
#define DD_MOSI DDB3
#define DD_MISO DDB4
#define DD_SCK DDB5
#define DD_SS DDB2

void SPI_SlaveInit(void);
uint8_t SPI_SlaveTransmit(void);

int main(void)
{
  uint16_t keycode=0;
  uint8_t daten=0;
  char keycode_string[4];

  lcd_init();
  SPI_SlaveInit();
  while(1)
  {
    if((SPSR & (1<<SPIF)))
    {
      daten = SPI_SlaveTransmit();
      keycode = daten;
      lcd_init();
      itoa(keycode,keycode_string,10);
      lcd_pos(0,0);
      lcd_text((u8*)"Keycode: ");
      lcd_pos(0,9);
      lcd_text((u8*)keycode_string);
    }
  }
}

void SPI_SlaveInit(void)
{
  /* Set MISO output, all others input */
  DDR_SPI = (1<<DD_MISO);
  /* Enable SPI */
  SPCR = (1<<SPE);
}

uint8_t SPI_SlaveTransmit(void)
{  
  /* Wait for reception complete */
  while(!(SPSR & (1<<SPIF)));
  /* Return data register */
  return SPDR; 
}



SPI-Master auf Attiny25
#define F_CPU 2000000UL    // 2 MHz Takt
#include <util/delay.h>
#include <avr/io.h>
#include <stdint.h>

void SPI_MasterTransmit(void);

int main(void)
{
  // DO und USCK als Ausgänge initialisieren
  DDRB = (1<<DDB1)|(1<<DDB2);
  while(1)
  {
    SPI_MasterTransmit();
    _delay_ms(1000);
  }
}

void SPI_MasterTransmit(void)
{
  USIDR=120;
  USISR = (1<<USIOIF);           
  do
  {
                USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);  
  }
  while(!(USISR & (1<<USIOIF)));
}

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sei();
vergessen.

Autor: max power (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
datenblatt SS Pin Functionality.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Master muß während der Übertragung den /SS Pin des Slave auf low 
setzen, damit der Slave weiß, wann ein Byte anfängt.

SPI mit nem 8-Pinner ist nicht so dolle, da bleiben nur noch 2 IOs 
übrig.


Peter

Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> sei();
> vergessen.
sei() ändert leider nichts. Funktioniert immer noch nicht.

> datenblatt SS Pin Functionality.

> Der Master muß während der Übertragung den /SS Pin des Slave auf low
> setzen, damit der Slave weiß, wann ein Byte anfängt.
soviel ich weiß, hat der Attiny25 kein SS-Pin. Zudem sind bei mir die 
zwei
Schaltungen lediglich über fünf Leitungen miteinanden verbunden:
MOSI,MISO,SCK,GND,PWR --> also kein SS

das müsste doch auch funktioniern wenn beim Master der SS-Pin dauerhaft 
auf LOW liegt, oder?
Ich hatte vorher das ganze andersrum gehabt, also Attiny25=Slave und 
Atmega8=Master. In dieser konstellation hat alles funktioniert, also 
muss es doch andersrum auch gehen.

> SPI mit nem 8-Pinner ist nicht so dolle, da bleiben nur noch 2 IOs
> übrig.
ich benötige nur ein IO-Pin

Autor: max power (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das müsste doch auch funktioniern wenn beim Master der SS-Pin dauerhaft
>auf LOW liegt, oder?
beim slave muss ss auf low liegen.

Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> beim slave muss ss auf low liegen.
sorry, mein Fehler. So war das natürlich gemeint. Aber der Attiny25 hat
doch kein SS-Pin.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cetin A. schrieb:
> das müsste doch auch funktioniern wenn beim Master der SS-Pin dauerhaft
> auf LOW liegt, oder?

Dann braucht man ne andere Synchronisation.
Z.B. wenn ne größere Pause ist, resettet der Slave sein SPI.

Man kann auch den Slave später einschalten (großes Delay nach Reset), 
nachdem der Master sein SPI schon initialisiert hat.
Ist der Slave aber vor dem Master enabled, kann er sich auf der 
floatenden SCK-Leitung Störpulse einfangen und ist dann für immer 
asynchron.

Die sauberste Lösung ist aber, der Master steuert auch die /SS-Leitung 
des Slave.


Peter

Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Dann braucht man ne andere Synchronisation.
> Z.B. wenn ne größere Pause ist, resettet der Slave sein SPI.
wie soll die Pause erkannt werden?

> Die sauberste Lösung ist aber, der Master steuert auch die /SS-Leitung
> des Slave.
Denke ich auch, aber meine Schaltung ist schon verbaut. Leider muß ich 
den
unsauberen Weg gehen.

Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier noch ein Problem bemerkt, der SS-Pin am Slave (Atmega8) 
liegt ja auf PB2. Aber PB2 wird bereits von der LCD-Routine für die 
RS-Leitung benutzt. Kann ich das ganze nicht ohne SS programmieren?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Kann ich das ganze nicht ohne SS programmieren?
Nimm eine RS232 Schnittstelle. Die ist per Definition asynchron und 
braucht nur 2 Leitungen zwischen den Controllern.

Autor: Cetin A. (exaware)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Nimm eine RS232 Schnittstelle. Die ist per Definition asynchron und
> braucht nur 2 Leitungen zwischen den Controllern.
Mein Fehler, ich hätte es am Anfang genauer erzählen sollen. Meine zwei
Schaltungen haben beide eine ISP-Programmierbuchse. Da ich keine 
möglichkeit habe zusätzlich Leitungen anzuschließen, habe ich die zwei 
Schaltungen über die Buchsen 1:1 verbunden. Deshalb wollte ich das ganze 
mit SPI realisieren, da diese auf der Buchse liegen. I²C und USART 
liegen beim Atmega8 auf anderen Pins.

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.