piątek, 19 lutego 2016

AVR cz6 - rejestr przesuwny 74hc595 i realizacja sprzętowa przez SPI.

Po rozgryzieniu teorii rejestru przesuwnego przyszedł czas na realizację praktyczną.Na początek postanowiłem wykorzystać sprzętową realizację magistrali SPI na procesorze Atmega8A. Na płytce stykowej zbudowałem układ jak na schemacie:



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