I w tym momencie zamotałem się na 3 dni. Okazuje się, że aby funkcjonowała sprzętowa realizacja SPI istotne jest właściwe połączenie pinów MOSI, SS,SCK z pinami SER, RCK i SCK rejestru. Po prostu chciałem pójść na łatwiznę i przepisywałem dowolne piny procesora do pinów rejestru. Oczywiście nic to nie dawało. Dopiero dzięki Internetowi udało mi się rozwiązać ten problem. Ale czy można obsługiwać rejestr z dowolnych pinów procesora? Tak! Ale programowo a nie sprzętowo.Po rozwiązaniu tego problemu przejrzałem notę aplikacyjną Atmegi8 i mogłem rozpocząć pisanie programu.
Po pierwsze definiujemy piny procesora:
#define MOSI (1<<PB3) // SER #define SCK (1<<PB5) // SCK #define LT (1<<PB2) // RCK #define LT_ON PORTB |= LT //odblokowujemy zatrzask #define LT_OFF PORTB &= ~LT //blokujemy zatrzask
Następnie musimy uruchomić sprzętową obsługę SPI:
void InitSPI(void){
DDRB |= MOSI|SCK|LT; // piny SPI jako wyjścia
SPCR |= (1<<SPE)|(1<<MSTR) // w rejestrze SPCR włączamy SPI i ustawiamy na tryb master
SPSR |= (1<<SPI2X); //w rejestrze SPSR ustawiamy szybkość transmisji na fosc/2
}
Więcej na temat rejestrów SPI można przeczytać w nocie katalogowej Atmegi.
Wysłanie bajtu przez interfejs SPI realizuje funkcja:
void SendSpi( uint8_t bajt ) {
SPDR = bajt;
while( !(SPSR & (1<<SPIF)) );
LT_ON;
_delay_ms(1);
LT_OFF;
}
Cały program ma postać:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
/* hardware SPI */
#define MOSI (1<<PB3) // <---- A (SER IN)
#define SCK (1<<PB5) // <---- SHIFT CLOCK (SC)
#define LT (1<<PB2) // <---- LATCH CLOCK (LT)
#define LT_ON PORTB |= LT
#define LT_OFF PORTB &= ~LT
void InitSpi(void);
void SendSpi( uint8_t bajt );
int main( void ) {
uint8_t i;
InitSpi();
while (1){
b=0b10000000;
for(i=7;i>=0;i--){
SendData(b);
b>>=1;
_delay_ms(1000);
}
b=0b00000001;
for(i=7;i>=0;i--){
SendData(b);
b<<=1;
_delay_ms(1000);
}
}
}
void SendSpi( uint8_t bajt ) {
SPDR = bajt;
while( !(SPSR & (1<<SPIF)) );
LT_ON;
_delay_ms(1);
LT_OFF;
}
void InitSpi(void) {
DDRB |= MOSI|SCK|LT; // piny SPI jako wyjťcia
SPCR |= (1<<SPE)|(1<<MSTR); // w-¦cz SPI i ustaw Master
SPSR |= (1<<SPI2X); // fosc/2
}
Efekt działania programu:

Brak komentarzy:
Prześlij komentarz