niedziela, 7 października 2012

Programowanie AVR w C - podstawy

Zaczynamy od podstaw programowania w C naszych mikro kontrolerów.

Aby zapoznać się z danym mikro kontrolerem , zalecam zapoznanie się z jego kartą katalogową. Będą w niej informacje na temat wszystkich wyprowadzeń, przerwań, timerów, schematy połączeń, komendy, rejestry i wiele innych cennych informacji.

W naszym przypadku zaczynamy zabawę z mikro kontrolerem o nazwie Attiny2313. Kontroler ten posiada 20 pinów we/wy.  Piny pełnią zazwyczaj kilka funkcji i każdy ma swoją nazwę, a w nawiasie alternatywne działanie.
Schemat wyprowadzeń attiny2313
 Jak widać nasz kontroler posiada piny A,B i D.  Nazwane są kolejno PORTA, PORTB i PORTD.

Każdy z portów posiada trzy rejestry: DDRx, PORTx i PINx . W miejsce x wstawiamy nazwy pinów np. DDRA, PORTA, PINA.

Opisanie poszczególnych rejestrów:

Stan bitów w rejestrze DDRx odpowiada za to czy dany port jest wejściem (0) czy wyjściem(1).
Przykład:
DDRB = 0xFF ustawia wszystkie piny (PB0..PB7)  portu A jako wyjścia.
DDRB = 0x01 ustawia pin PB0 jako wyjścia, a reszta pinów (PB1..PB7) jako wejścia.

Rejestr PORTx ustawiamy stan danego pinu na wysoki(1) lub niski(0) , ale tylko w przypadku jeżeli rejestr DDRx ustawiony jest jako wyjście(1).
Przykład:
DDRB = 0xF0 ustawia piny PB4..PB7 jako wyjścia
PORTB = 0xF0 ustawian pinom PB4..PB7 stan wysoki na wyjściu

Rejestr PINx służy do odczytu stanu napięcia na danym pinie, w przypadku kiedy DDRx ustawiliśmy jako wejścia(0).

Jak widać do każdego rejestru wartości wpisujemy w systemie szesnastkowym (HEX).
Najłatwiej można to zapamiętać w taki sposób że mamy rejestr 8 bitowy, dzielimy na pół i mamy 4 starsze i 4 młodsze bity.  Literaz F szesnastkowo to binarnie 1111, cyfra 0 szesnastkowo to binarnie 0000, łącząc te dwa znaki F0 otrzymamy 11110000 czyli piny Px4..Px7 ustawimy na stan wysoki.

Jak zmieniać pojedyńcze wartości w rejestrze? Otóż musimy używać operatorów bitowych takich jak:
OR (lub) |
np. PORTB |= (1<<3) ustawi 3 bit na 1

AND (i) &
np. PORTB &= (1<<5) ustawi 5 bit na 0

Z odczytywaniem wartości na poszczególnych pinach jest podobnie.
przykład
if(PINB & 0x02)  jeżeli drugi pin (PB1) ustawiony jest na wartość 1 to wykona się instrukcja

kolejny przykład pokazuje jeżeli wartość wynosi 0
if(PIN & 0x04) jeżeli trzeci pin (PB2) ustawiony na 0 to wykona się instrukcja

Wymienione zostały najważniejsze komendy i rejestry jakie będą potrzebne na początek. Warto się ich nauczyć i przećwiczy , ponieważ znacznie ułatwią nam pisanie programów.  Polecam podłączenie paru diod LED, oraz paru przycisków i sprawdzać co się dzieje.  Można również podłączyć wyświetlacz 7 segmentowy i podłączać do każdej "nóżki" inny port mikro kontrolera, w celu testowania różnych ustawień.

Obsługa przerwań dla Attiny2313

Witam

Dzisiaj opiszę Wam obsługę przerwań przez mikro kontroler Attiny2313.

Nasz mikro kontroler posiada dwa przerwania oznaczone jako INT0 i INT1, które zostały oznaczone w czerwonej ramce na poniższym zdjęciu.
Jak widać niektóre nóżki mają podwójne a nawet potrójne zastosowania. My będziemy dzisiaj korzystać z przerwania INT0 na porcie PD2.

Co to są przerwania?

Przerwania można opisać jako zadanie które trafia do naszego procesora i zostaje wykonane prawie natychmiast. Czyli jeżeli mamy w programie w nieskończonej pętli jakiś skrypt który zapala i gasi diody LED w określonej kolejności , to możemy dopisać przerwanie które gasi wszystkie diody LED na kilka sekund. Inaczej mówiąc kontroler zapisze sobie aktualne miejsce i zatrzyma program , a tym samym rozpocznie uruchamianie funkcji przerwania, które zrealizuje określone zadania.  Jest to bardzo przydatna rzecz w naszych programach.

Kod programu w C.

#include <avr/io.h>

#include <util/delay.h>   

#include <avr/interrupt.h>

   

char liczby[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

// liczby od 0 do 9 zapisane szesnastkowo

int i=0;



SIGNAL (SIG_INTERRUPT0)  // funckaj obsługi przerwania

{

    PORTB = 0xb6;  // wyświetla pewien znak

    _delay_ms(150);  // czeka ok 2 sekund

}



int main( void )

{

    DDRB=0xff;    // ustawia porty B jak wyjścia

  

    DDRD &= ~(1<<PORTD2); // 2 pin D jako wejśćie to jest nasz przycisk

    PORTD |= (1<<PORTD2); // podciąga do niego napięcie

  

    MCUCR |= (1<<ISC00);  // ustawienie przerwania przy zmianie stanu

    GIMSK |= (1<<INT0);   // włączenie przerwania INT0

    sei(); // uruchomienie systemu przerwań

   

  while(1)

  {

  

  for(i=0;i<=9;i++) {  // pętla która wyświetla nam cyfry od 0 do 9

    PORTB = liczby[i];  // wysyła do wyświetlacza odpowiednie piny (liczbę)

    _delay_ms(60);  // czekanie

  }

    

  

   }

  return 0;

}


Schemat układu.

Korzystamy dalej z naszego wyświetlacza 7 segmentowego, który będzie odliczał od 0 do 9 a po wciśnięciu przycisku (micro-switch), na 2 sekundy pojawi się pewnie symbol na wyświetlaczu , po czym nastąpi dalsze odliczanie na wyświetlaczu.

Do każdego pinu portu B naszego Attiny2313 podpinamy wyświetlacz jak w poprzednich artykułach.  Do portu PD2 podpinamy przycisk. Do 10 portu podpinamy masę (GND), a do 20 podpinamy napięcie (VCC) ok. 3-5V.  Najlepiej całość zmontować na pajączku lub płytce stykowej.

Tak wygląda nasz układ na płytce stykowej.


piątek, 5 października 2012

Programowanie AVR'ów Attiny2313 część 1

Witam Was.

Zaczynamy zabawę z mikro kontrolerami z rodziny AVR. Na początek wybrałem Attiny2313, jako że taki mogłem dostać najszybciej za niecałe 8zł.
Kartę katalogową możemy pobrać ze strony producenta (tutaj).

Wyprowadzenia pinów dla Attiny2313


Wyprowadzenia attiny2313

Naszym pierwszym programem będzie wyświetlanie cyfr na wyświetlaczu 7 segmentowym.
Podwójny wyświetlacz 7 segmentowy

Poniżej przedstawione zostały informacje z karty katalogowej wyświetlacza


Schematy wyprowadzeń wyświetlacza

Kod programu , który będzie co określony czas wyświetlał kolejne cyferki od 0 do 9 na wyświetlaczu.

#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>       
      
int main(void)
{     
   DDRB = 0xFF;
   DDRA = 0x00;
 


   PORTA = 0x03;

     
    int czekaj = 80;
    int i;
    char liczby[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
    
    i=0;
    PORTB = liczby[i];
    i=1;
    while (1) 
    {
         
        for(i=0; i<=9; i++) {
            PORTB = liczby[i];
            _delay_ms(czekaj);
        }   
    }    
}

Całość dla przetestowania zmontowałem na płytce stykowej.  Zasilanie 3V.
U mnie wygląda to mniej więcej tak jak poniżej.
Wygląd po zmontowaniu

Na wyświetlaczu pojawiają się kolejno cyfry od 0 do 9 i tak cały czas. Jest to pierwszy artykuł w celu zapoznania się z programowaniem w C.