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