Hallo Leute,
habe folgendes Problem:
Ich versuche gerade zwei Mikrocontroller miteinander über SPI
kommunizieren zu lassen. Ein Kommunikation zwischen zwei ATMega32 ist
mir bereits gelungen. Leider Möchte der ATTiny2313 aber irgendwie nicht
mit dem ATMega32 sprechen :-(
Nach langem Suchen in unzälligen Foren und stundenlanges Wälzen des
Datenblattes habe ich ein Programm geschrieben, welches eigentlich
funktionieren sollte. Vielleicht könnt ihr mir ja mal wieder auf die
Sprünge helfen :-)
Hier der Code des Master (ATMega32):
1
/*
2
* SPI_Master.c
3
*
4
* Created: 06.07.2013 21:05:31
5
* Author: Jens
6
*/
7
8
// This program is for the SPI-Master on an ATMega device
9
10
#include<avr/io.h>
11
#include<util/delay.h>
12
13
// Initialize the SPI-Interface
14
voidinit_spi()
15
{
16
//Set MOSI, clock pin and SS pin as output. Not using
17
// the SS pin at this point.
18
DDRB=(1<<DDB4)|(1<<DDB5)|(1<<DDB7);
19
20
//Enable SPI mode, master and F_CPU/16. Slowed it down so
21
// could see what is going on with scope.
22
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
23
}
24
25
// Send data via SPI
26
voidsend_spi(intdata)
27
{
28
// Load the data into the data register
29
SPDR=data;
30
31
// Wait until data is transmitted
32
while(!(SPSR&(1<<SPIF)));
33
34
// Wait 500ms before sending the next Byte
35
_delay_ms(500);
36
}
37
38
intmain(void)
39
{
40
intdata;
41
42
// Set LED-Port PB2 and PB3 as output
43
DDRB=(1<<DDB3)|(1<<DDB2);
44
45
init_spi();
46
47
data='5';
48
49
// Send 5, 6, 5, 6, 5, ...
50
while(1)
51
{
52
if(data=='5')
53
{
54
// Send '5' and turn on LED1 and off LED2
55
send_spi(data);
56
data='6';
57
PORTB=(1<<PB3);
58
PORTB&=~(1<<PB2);
59
}
60
else
61
{
62
// Send '6' and turn on LED2 and off LED1
63
send_spi(data);
64
data='5';
65
PORTB=(1<<PB2);
66
PORTB&=~(1<<PB3);
67
}
68
}
69
70
return0;
71
}
und hier der des Slave (ATTiny2313):
1
/*
2
* SPI_Slave.c
3
*
4
* Created: 07.07.2013 10:59:29
5
* Author: Jens
6
*/
7
8
// This program is for an SPI-Slave Tiny device
9
10
#include<avr/io.h>
11
#include<avr/interrupt.h>
12
#include<util/delay.h>
13
14
intdata;
15
16
// Initialize SPI-Interface
17
voidinit_spi()
18
{
19
// Set DO as output and DI, USCK as input
20
DDRB=(1<<DDB6);
21
DDRB&=~(1<<DDB5)|~(DDB7);
22
23
// Set 3-wire-mode and external positive clock
24
USICR=(1<<USIWM0)|(1<<USICS1);
25
26
// Set the counter-overflow flag
27
USISR=(1<<USIOIF);
28
29
// Enable interrupt for counter-overflow when data is received
30
USISR=(1<<USISIF);
31
32
}
33
34
ISR(USI_OVERFLOW_vect)
35
{
36
// Wait for reception complete
37
while(!(USISR&(1<<USIOIF)));
38
39
// Return data register
40
data=USIDR;
41
42
}
43
44
intmain(void)
45
{
46
// Set LED-Ports PB2 (LED1) and PB3 (LED2) as output
47
DDRB=(1<<DDB2)|(1<<DDB3);
48
49
init_spi();
50
51
// If data is received via SPI, check if it is an '5' or an '6'.
52
// Then turn on the corresponding LED
53
while(1)
54
{
55
// Check if "data" includes an '5' -> Turn on LED1 PB2
56
if(data=='5')
57
{
58
PORTB=(1<<PB2);
59
PORTB&=~(1<<PB3);
60
}
61
// Check if "data" includes an '6' -> Turn on LED2 PB3
Jens K. schrieb:> // Wait 500ms before sending the next Byte> _delay_ms(500);
So gehts natürlich.
Aber wenn der Master mehrere Bytes hintereinander senden/empfangen soll,
kommt der Slave nicht mehr mit.
Wenns zuverlässig sein soll, brauchst Du einen Slave mit mindestens 1
Byte HW-Puffer (Senden+Empfangen).
Z.B. AT89LP4052
Eine Sache wäre da auch noch: Wenn ich den SPI oder USI initialisiere
und nutze leuchten die LEDs, im gegensatz zu einem vorherigem Programm
wo ich sie nur toggle, sehr schwach. Woran liegt das und wie kann ich
das ändern?
Hi
> // Reset counter-overflow Flag> USISR = (1<<USIOIF);
Ist unnötig. Das Macht der Interrupt schon.
>Eine Sache wäre da auch noch: Wenn ich den SPI oder USI initialisiere>und nutze leuchten die LEDs, im gegensatz zu einem vorherigem Programm>wo ich sie nur toggle, sehr schwach. Woran liegt das und wie kann ich>das ändern?> // Set LED-Ports PB2 (LED1) and PB3 (LED2) as output> DDRB = (1<<DDB2) | (1<<DDB3);>void init_spi()>{> // Set DO as output and DI, USCK as input> DDRB = (1<<DDB6);> DDRB &= ~(1<<DDB5) | ~(DDB7);
Fällt dir etwas auf?
MfG Spess
Hi
>Was fehlt den noch oder ist noch falsch, finde es nicht.
In deiner Main kommt erst:
> DDRB = (1<<DDB2) | (1<<DDB3);
Danach rufst du init_spi() auf, in der steht:
> DDRB = (1<<DDB6);
Welchen Wert hat DDRB danach?
MfG Spess
Eine eigene Frage?
Dieser Thread ist über 13 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.