Forum: Mikrocontroller und Digitale Elektronik SPI-Kommunikation zwischen zwei ATTiny2313


von Jens K. (mister232)


Lesenswert?

Guten Abend,

ich versuche gerade eine SPI-Kommunikation zwischen zwei ATTiny2313 
herzustellen. Ich nutze dafür die USI-Schnittstelle der Mikrocontroller. 
Ich verwende den internen RC-Oszillator. Später werde ich auf einen 
externen Quarz umsteigen, doch ich will erst einmal schauen ob ich 
überhaupt irgendetwas rüber bekomme.

Der Ablauf des Programms ist wie folgt:
1. Der Master bekommt einen Char über die UART-Schnittstelle vom 
Computer (das funktioniert auch soweit)
2. Der Master sendet das Char an den Slave
3. Der Slave lässt entsprechend der Zahl die er empfangen hat eine LED 
aufblinken

Hier mein Quellcode, zunächst nur vom Master:
1
/*
2
 * Communication_via_SPI_Master.c
3
 *
4
 * Created: 21.01.2014 15:02:29
5
 *  Author: Jens
6
 */ 
7
8
9
#include <avr/io.h>
10
#include <stdlib.h>
11
#include <util/delay.h>
12
#include <inttypes.h>
13
14
#define FCPU 1000000L
15
#define USART_BAUD 4800L
16
#define USART_UBBR_VALUE ((FCPU)/(USART_BAUD*16)-1)
17
18
// Initialization for the UART-Interface
19
void USART_vInit(void)
20
{
21
  // Set baudrate
22
  UBRRH = (uint8_t) (USART_UBBR_VALUE>>8);
23
  UBRRL = (uint8_t) USART_UBBR_VALUE;
24
  // Enable receiver and transmitter
25
  UCSRB = (1<<RXEN)|(1<<TXEN);
26
  // Set frame format to 8 data bits, no parity, 2 stop bits
27
  UCSRC = (1<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
28
}
29
30
// Initialization for the SPI-Interface
31
void SPI_init(void)
32
{
33
  //Output: PB7=USCK, PB6=DO, PB4=LED
34
  DDRB |= (1<<PB7)|(1<<PB6)|(1<<PB4);
35
  //Input: PB5=DI
36
  DDRB &= ~(1<<PB5);
37
  // Enable internal pull-up for PB5
38
  PORTB |= (1<<PB5);
39
  // Enable SPI in master mode
40
  USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
41
}
42
43
// Function for receiving data via UART-Interface
44
unsigned char USART_ReceiveByte(void)
45
{
46
  // Wait until a byte has been received
47
  while(!(UCSRA&(1<<RXC)));
48
  // Return received data
49
  return UDR;
50
}
51
52
// Function for transmitting data via SPI-Interface
53
void SPI_Transfer(unsigned char data)
54
{
55
  // Load data into the data-register
56
  USIDR = data;
57
}
58
59
int main (void)
60
{
61
  unsigned char u8Data;
62
  DDRB = 0xFF;
63
  
64
  // Initialize USART and SPI
65
  USART_vInit();
66
  SPI_init();
67
  
68
  while(1)
69
  {
70
    // Receive data via UART
71
    u8Data = USART_ReceiveByte();
72
    while(!(UCSRA & (1<<UDRE)));
73
    UDR = u8Data;
74
    // Transmit the received data to the SPI-Slave
75
    SPI_Transfer(u8Data);
76
    // Led on
77
    PORTB |= (1<<PB4);
78
    _delay_ms(500);
79
    // Led off
80
    PORTB &= !(1<<PB4);
81
    _delay_ms(500);
82
  }
83
}

Leider kann ich beim senden der Daten keine Reaktion des Slave 
feststellen und auch ein Oszi zeigt nichts auf dem Bus an.

Könntet ihr vielleicht mal rüberschauen? Ich bin gerade erst dabei die 
SPI-Kommunikation kennzulernen, also bitte Verständnis für die unsaubere 
Programmierung :-)

von tictactoe (Gast)


Lesenswert?

Jens K. schrieb:
> ich versuche gerade eine SPI-Kommunikation zwischen zwei ATTiny2313
> herzustellen. Ich nutze dafür die USI-Schnittstelle der Mikrocontroller.

Soweit ich im Datasheet gelesen habe, geht bei den ATTiny2313 nix 
automatisch. D.h., das hier:
1
void SPI_Transfer(unsigned char data)
2
{
3
  // Load data into the data-register
4
  USIDR = data;
5
}

bringt so gar nix. Du musst schon für die Clock-Pulses selber sorgen.
Zitat: "When operating as master, clock pulses are software generated by
toggling the PORTA register, while the data direction is set to output. 
The USITC bit in the USICR Register can be used for this purpose."

von c-hater (Gast)


Lesenswert?

Jens K. schrieb:

> Leider kann ich beim senden der Daten keine Reaktion des Slave
> feststellen und auch ein Oszi zeigt nichts auf dem Bus an.

Was nicht anders zu erwarten ist.

> Ich bin gerade erst dabei die
> SPI-Kommunikation kennzulernen, also bitte Verständnis für die unsaubere
> Programmierung :-)

Das ist keine "unsaubere Programmierung", sondern ein deutliches 
Zeichen, daß du schlicht das Datenblatt zum Thema USI nicht gelesen hast 
und deswegen nicht einmal eine näherungsweise Vorstellung davon hast, 
was du da eigentlich tust.

Sonst wußtest du, daß das USI kaum mehr ist als ein dummes 
Schieberegister und ein genauso blöder Zähler. Da mußt du schon noch 
etwas mehr tun, damit sich da irgendwelche Bits bewegen, insbesondere 
z.B. für einen Takt für diese beiden Sachen sorgen...

Welche Möglichkeiten das Teil dazu bietet, steht, wer hätte das gedacht, 
im Datenblatt, also lies' das doch bitte einfach mal, bevor du anfängst, 
planlos drauflos zu programmieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.