Programowanie mikrokontrolerów AVR z rodziny ATmega.

Transkrypt

Programowanie mikrokontrolerów AVR z rodziny ATmega.
Programowanie mikrokontrolerów AVR
z rodziny ATmega.
Materiały pomocnicze
Wszelkie prawa zastrzeżone. Kopiowanie w całości lub w częściach bez zgody i wiedzy autora surowo
zabronione.
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
Strona
1
Jakub Malewicz
[email protected]
•
Enkodery
Enkoder – czujnik mierzący położenie liniowe lub kątowe. W celu określenia położenia najczęściej
stosuje się metodę optyczną lub magnetyczną.
o Podział enkoderów
Enkoder inkrementalny (przyrostowy, względny) – wskazuje zmianę położenia o określoną wartość
(kątową lub liniową w zależności od typu) w postaci impulsu. Układ pomiarowy, zliczając impulsy,
jest w stanie określić wielkość przesunięcia / obrotu.
Enkoder absolutny (bezwzględny) – wskazuje konkretne położenie obiektu, jest ono zawsze znane.
Układ pomiarowy jest nieczuły na wyłączenie zasilania, gdyż po jego przywróceniu położenie można
odczytać z enkodera. Kolejne pozycje / stany najczęściej są zapisywane w kodzie Gray’a ze względu
na jego własności. Na rysunku 1 przedstawiono przykładową tarczę, która umożliwia rozróżnienie 16
pozycji.
Rys 1. Tarcza enkodera absolutnego (źródło: http://asimo.pl)
o Rozdzielczość
Jest to najważniejszy parametr enkodera, na podstawie którego możemy określić najmniejszą zmianę
położenia liniowego lub kątowego, jaką jest w stanie rozróżnić enkoder. Im większa rozdzielczość tym
enkoder precyzyjniejszy. Obecnie najczęściej stosuje się czujniki o rozdzielczości od 6 do 12 bitów.
PRZYKŁAD
rozdzielczość: 10 bitów
typ: obrotowy
Strona
2
Powyższe parametry oznaczają, że enkoder mierzy położenie kątowe i jest w stanie rozróżnić 210
różnych położeń na każde 360°. Wynika z tego, że układ pomiarowy jest w stanie określić położenie z
dokładnością do około 0,3°.
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
o Typy sygnałów wyjściowych w enkoderach
−
−
słowo bitowe – pozycja przedstawiona na n-bitach, gdzie n to rozdzielczość czujnika
impulsowe – przesunięciu/obrotowi o określoną jednostkę towarzyszy impuls (rysunek 2)
Rys 2. Enkoder impulsowy
−
kwadraturowe – dwa przebiegi prostokątne, przesunięte w fazie o 90°, dla podniesienia
precyzji stosuje się trzeci sygnał, tzw. indeksujący, na którym raz na odcinek / obrót pojawia
się impuls, co pozwala układowi pomiarowemu uzyskać dodatkowy punkt odniesienia i
umożliwia korektę; na rysunku 3 przedstawiono przykładowy przebieg sygnału
Rys 3. Przykładowy przebieg czujnika z wyjściem kwadraturowym
−
−
−
PWM – szerokość impulsu jest proporcjonalna to przesunięcia / obrotu
SPI – szeregowa magistrala danych
inne
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
Strona
Jest to enkoder inkrementalny i absolutny zarazem. Posiada wyjścia kwadraturowe wraz
z indeksującym, PWM oraz magistralę SPI. Można go również skonfigurować do pracy z silnikami
bezszczotkowymi (BLDC). Pomiar przy pomocy czujnika opiera się o badanie zmian pola
3
o AS5040
magnetycznego, dzięki czemu pomiar jest bezkontaktowy. Na rysunku 4 przedstawiono ideę działania
AS5040.
Rys. 4 Idea działania czujnika magnetycznego (źródło: dokumentacja techniczna AS5040)
•
Przerwania
o System przerwań
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
Strona
- sygnał reset
- zmiana stanu na wybranych wyprowadzeniach mikrokontrolera
- zdarzenia związane ze stanami liczników / timerów
- magistrala SPI
- magistrala USART
- przetwornik analogowo-cyfrowy
- pamięć wewnętrzna
- komparator
- magistrala TWI
- wewnętrzny mechanizm zapisu do pamięci
4
Mechanizm obsługi specjalnych zdarzeń, które z punktu widzenia mikrokontrolera występują
w sposób asynchroniczny, a w niektórych przypadkach wręcz losowy. Mikrokontroler może obsłużyć
wiele zdarzeń specjalnych, które w większości związane są z jego układami peryferyjnymi.
W przypadku wystąpienia takiego zdarzenia mikrokontroler przerywa główną pętlę programu
i przechodzi do wykonania procedury obsługującej dane zdarzenie, po czym wraca do miejsca,
w którym przerwał. Źródłami przerwań mogą być:
o Elementy programu niezbędne do korzystania z przerwań
Aby móc korzystać z systemu przerwań należy dołączyć bibliotekę interrupt.h:
#include <avr/interrupt.h>
Powyższa biblioteka pozwala korzystać z funkcji obsługujących przerwania:
ISR(wektor)
{
}
gdzie wektor to informacja dla kompilatora, o tym jakie przerwanie będzie obsługiwane (co będzie
źródłem przerwania).
PRZYKŁAD
ISR(USART_RXC_vect)
{
UDR;
UART_SEND_string("To ja, Twoj kontroler :)\n\r");
}
Wektor może być podany jako liczba lub w postaci tekstowej, co jest bardziej wygodne, gdyż od razu
widać, co będzie wywoływało przerwania. Nazwy wektorów są jasno określone i można je odnaleźć
w dokumentacji kompilatora oraz w dokumentacji technicznej ATmegi (tabela Reset and Interrupt
Vectors). W tym drugim przypadku należy tekst z kolumny Source (źródło) odpowiednio
zmodyfikować, zamieniając wszystkie znaki białe oraz interpunkcyjne na pojedyncze znaki
podkreślenia ”_” i dodając na końcu ”_vect”.
PRZYKŁAD
TIMER0 COMP -> TIMER0_COMP_vect
USART, RXC -> USART_RXC_vect
Aby włączyć system przerwań należy w funkcji main() przed pętlą główną wywołać jedną z poniższych
instrukcji:
sei();
SREG |= (1<<SREG_I);
SREG &=(~ (1<<SREG_I));
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
Strona
cli();
5
Ponadto należy odpowiednio skonfigurować układ peryferyjny, który ma być źródłem przerwania
poprzez ustawienie odpowiednich bitów w jego rejestrach. Jeżeli natomiast chcemy z jakiegoś
względu wyłączyć system przerwań należy wywołać jedną z poniższych linii:
o Przerwania zewnętrzne
Przerwanie mogą wywołać również zmiany stanu na niektórych pinach mikrokontrolera oznaczonych
jako INTx, gdzie x jest cyfrą. Aby skorzystać z tych źródeł należy odpowiednio ustawić bity
w rejestrach:
GICR – włączenie odpowiedniego źródła
MCUCR – konfiguracja warunku wystąpienia przerwania (stan niski, zmiana stanu na pinie, zbocze
opadające, zbocze narastające)
PRZYKŁAD
#define F_CPU
1000000ul
#define UART_CONST
(F_CPU/(16ul*UART_BAUD)-1)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
void delay_ms(int ms)
{
volatile long unsigned int i;
for(i=0;i<ms;i++)
_delay_ms(1);
}
ISR(INT0_vect)
{
PORTA=0x00;
delay_ms(1000);
}
int main(void)
{
//konfiguracja i inicjalizacja portów
DDRD = 0x00;
PORTD = 0xff;
DDRA = 0xff;
PORTA = 0xff;
//INT0
MCUCR |= (0<<ISC01) | (0<<ISC00);
GICR |= ((1<<INT1) | (1<<INT0));
return 0;
}
Projekt jest współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego
Strona
while(1)
{
PORTA = 0xff;
}
6
//wlaczenie przerwan
SREG=(1<<SREG_I);