Wstęp

Pomimo, iż mikro-kontrolery AVR powoli odchodzą w zapomnienie na rzeczy o wiele szybszych układów ARM oraz coraz większej popularności FPGA postanowiłem pozostawić rozdział odnośnie tych mikro-klocków na swojej stronie, gdyż do prostych celów nadal możemy je śmiało wykorzystywać.

Przygotowanie do programowania

Poniżej przedstawię listę programów (dla systemu Windows) które należy zdobyć aby zacząć naukę programowania mikro-kontrolerów AVR

    Narzędzia użyte do programowania
  • Kompilator  -  AVR STUDIO wersja 4.13 z serwispakiem I
    aby zainstalować na Windows2000 wymagana jest aktualizacja Windows Instaler
  • Programator  -  zgodny z STK200
  • Program Å‚adujÄ…cy pliki HEX  -  PonyProg2000
  • Program do testowania RS232  -  (terminal) Herkules Setup Utility
  • Åšrodowisko uruchomieniowe  -  Symulator Atmega16 w AVR Studio (W rzeczywistym procku po resecie rejestry przyjmujÄ… przypadkowe wartoÅ›ci, tak samo pamięć. W symulatorze zapomniano o tym szczególe i po klikniÄ™ciu reset zerujÄ… siÄ™ wszystkie rejestry -  ZAWSZE INICJUJ UÅ»YWANE ZMIENNE)

Ważną czynnością przed rozpoczęciem pisania programu jest skonfigurowanie mikro-kontrolera do pracy z zewnętrznym rezonatorem kwarcowym. Poniższy screen przedstawia jak ustawić bity fuses za pomocą programu PonyProg2000

Założenia dla programów

    Założenia dla programu urządzenia pomiarowego
  • UrzÄ…dzenie ma być oparte na wewnÄ™trznym przetworniku A/C
  • Wyzwalanie przetwornika ma siÄ™ odbywać za pomocÄ… przerwania 16 bitowego timera
  • CzÄ™stotliwość taktowania Timera jest równa czÄ™stotliwoÅ›ci zegara podzielonej przez 1024,i wynosi 7200 Hz
  • Dla tej czÄ™stotliwoÅ›ci timer zwiÄ™kszy swojÄ… wartość o 1 co 1/7200=139 us
  • Gdy ustawimy rejestr OCR1B (z tym rejestrem timer jest ciÄ…gle porównywany) na 1 wówczas przerwanie generowane bÄ™dzie co 139us zaÅ› ustawienie maksymalnej wartoÅ›ci 65536 (szesnastkowo $ffff) da nam okres próbkowania 9s
  • Karta jest konfigurowana przez ukÅ‚ad RS232 i tak też wysyÅ‚a zebrane dane. Do konfiguracji karty można użyć terminala Herkules Setup Utility do pobrania Tutaj
  • Karta posiada bufor FIFO na 256 próbek ulokowany w pamiÄ™ci SRAM
    Założenia dla programu regulatora mocy (Prędkości obrotowej silnika prądu stałego)
  • Program ma wykorzystywać wbudowany w mikro-kontroler regulator PWM
  • Jako wartość zadana posÅ‚uży potencjometr podłączony do przetwornika AC mikro-kontrolera Atmega16
  • Przerwanie z przetwornika AC bÄ™dzie ustawiać generator PWM

Programowanie właściwe - urządzenie pomiarowe

Na początku programu napisanego w asemblerze należy zawsze umieścić wektory przerwań

Program Główny
Wektory przerwań
;-----------------------
;poczÄ…tek segmentu kodu
;-----------------------
.cseg
;---------------------------------------------
;wektory obsługi przerwań
;---------------------------------------------
jmp RESET;		skok po Reset
.org $00E
jmp TIMER1_COMPB;	skok do procedury obsługi przerwania timera
.org $016
jmp USART_RXC;		skok do procedury obsługi przerwania "znak odebrany"
.org $1c
jmp adc_cc;		skok do procedury obsługi przerwania zakończona konwersja A/C

W instrukcji do kontrolera AVR znajduje się szczegółowy opis przerwań mikro-kontrolera. Ja tutaj umieściłem tylko te przerwania, z których będę korzystał w programie. Wektor przerwań to po prostu określony adres pamięci programu, pod który procek skacze w momencie wystąpienia przerwania. Właśnie w tym miejscu umieszczamy skok do naszej procedury obsługi przerwania. Jeżeli tego nie zrobimy a przerwanie nastąpi to zwyczajnie się procek wysypie. Do określenia, w którym miejscu umieścić skok służy nam dyrektywa .org

Konfiguracja układu transmisji szeregowej

Procedurę która odpowiada za inicjację i wykorzystanie rs232 umieściłem w oddzielnym pliku.

Oprogramowanie kliknięcia przycisku:
usart.asm
USARTINIT:				
clr r16				;Set baud rate
out UBRRH, r16
ldi r16,3			;Set baud rate	
out UBRRL, r16
ldi r16, (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);Enable receiver and transmitter, oraz włączenie przerwania dane odebrane
out UCSRB,r16
ldi r16, (1<<URSEL)|(3<<UCSZ0)	;Set frame format: 8data, 1stop bit
out UCSRC,r16;
ret

usart_send_B:			;wysyłanie przez odpytywanie
sbis UCSRA,UDRE			;jeśli usart gotowy pomin instrukcje skoku i wstaw dane do wyslania
rjmp usart_send_B
out UDR,r16			;Put data (r16) into buffer, sends the data
ret

send_msg:
lpm r16,Z+			;Pobierz bajt z pamięci programu i zwieksza o 1 indeks
tst r16				;Sprawdź czy zero
breq msg_end			;Jesli tak to koniec wysyłania
rcall usart_send_B		;Jesli bajt nie zerowy to wysli
rjmp send_msg			;I skocz do poczÄ…tku programu w celu pobrania kolejnego bajtu
msg_end:
ret

W powyższym pliku procedura USARTINIT: odpowiada za inicjację portu szeregowego.

    Rejestry mikro-kontrolera
  • UBRR - Usart Boud Rate Register - rejestr do którego zapisujemy prÄ™dkość transmisji szeregowej, aby uzyskać prÄ™dkość transmisji 115200 b/s przy kwarcu 7,3728 [MHz] do rejestru wpisujemy 3(patrz manual do Atmega16)
  • UCSRB - Usart Control Status Register B - W tym rejestrze włączamy bity odpowiedzialne za włączenie nadawania (bit TXEN) i odbioru (bit RXEN), oraz bit odpowiedzialny za generowanie przerwania gdy usart odebraÅ‚ dane (bit RXCIE).
  • UCSRC - Usart Control Status Register C - aby dokonać zapisu do tego rejestru musi być ustawiony bit URSEL, bierze siÄ™ to z stÄ…d, że dwa rejestry konfiguracyjne majÄ… ten sam adres w przestrzeni I/O mikro-kontrolera, i ten bit decyduje gdzie trafi dana (nie wiem dlaczego ale tak jest)

Procedura usart_send_B: odpowiada za wysłanie jednego bajtu. Procedura wysłania odbywa się następująco: program najpierw testuje bit UDRE (czy USART gotowy) jeśli nie to wykonuje się instrukcja skoku do początku procedury i ponowny test. Jeśli warunek testowany jest spełniony wówczas instrukcja skoku będzie pominięta i dana z R16 zostanie umieszczona w buforze UDR.

send_msg: wysyła przez port szeregowy wiadomość tekstową zakończoną zerem. I tak aby skorzystać z tej procedury należy najpierw załadować rejestr Z adresem wiadomości, wiadomość musi być zakończona zerowym bajtem.

Deklaracja wiadomości
ela:.db "JESTEM Karta ELAP",13,10,"UrzÄ…dzenie...",13,10,0
Następnie w programie:
ldi_16 2*ela,zl,zh     ;zaÅ‚adowanie z rejestru Z adresem wiadomoÅ›ci
rcall send_msg       ;wywoÅ‚anie procedury wysyÅ‚ajÄ…cej

Bufor FIFO

Bufor fifo (mojego pomysłu) jest zadeklarowany w pamięci SRAM mikro-kontrolera zarówno zapis jak i odczyt odbywają się w sposób pokazany na rysunku (wskaźniki odczytu jak i zapisu działają niezależnie). Jeżeli wskaźnik zapisu lub odczytu osiągnie wartość max to operacja zaczyna się od początku bufora Dodatkowa zmienna, którą zwiększamy o 1 przy zapisie do FIFO a zmniejszamy przy odczycie służy do kontroli zajętości Bufora



Główny blok programu

Główny blok programu napisany jest w oparciu o gniazda, w którym zawsze wykonuje się jedno. Wybór gniazda dokonujemy przy pomocy zmiennej sterującej Ls. Rejestr "Z" jest załadowany adresem etykiety "skoki:", do której dodana jest wartość LS i wykonywany jest skok do instrukcji oddalonej o LS od etykiety

idea działania programu - gniazda+zmienna sterująca:
loop:
ldi_16 skoki,zl,zh	;załaduj rejestr Z adresem procedury skoki (makro)
add zl,ls		;dodaj wartość LS do rejestru Z
clr r16
adc zh,r16
ijmp			;Wykonaj skok do adresu określonego w Z
skoki:
 rjmp loop		;ls=0
 rjmp aply_		;ls=1
 rjmp odczyt		;ls=2
 rjmp wyjscie2		;ls=3
 rjmp wyjscie1		;ls=4
 rjmp who_is		;ls=5
 rjmp pressent		;ls=6
 rjmp _tyb_inf		;ls=7
 rjmp _number_sample	;ls=8
 rjmp _sampl_tim_info	;ls=9	

Konfiguracja Timera T1 oraz przetwornika AC

Karta miała działać w oparciu o przerwania Timera (Porównanie z rejestrem TCR1B). Rejestr ten jest uaktualniamy podczas konfiguracji i ma wpływ na częstotliwość próbkowania karty. Przerwanie timera to jest ustawione jako źródło wyzwalania Przetwornika AC. Po zakończeniu konwersji uaktywnione jest przerwanie przetwornika, w którego to procedurze obsługi dane z rejestrów przetwornika są przeniesione do bufora umieszczonego w pamięci SRAM mikro-kontrolera.

Konfiguracja Timera:
Timer1.asm
Timer1_init:
;inicjacja timera pierwszego 16bit
;timer ma generować przerwania dla porównania z rejestrem OCR1B
	in r16,sfior			;jeśli sie pojawi to reset preskalera	
	sbr_ r16, psr10
	out sfior,r16;
	ldi r16, (1<<WGM12)|(1<<cs10)|(1<<cs12)
; ustawienie maxymalnej wartości jako OCR1A bit WGM12 - timer wyłączony
	out TCCR1B, r16;
	;ldi r16, (1<<OCF1B)
	;out tifr,r16
	ldi r16, (1<<OCIE1B)	; włączenie przerwania od porównania z rejestrem OCR1B
	out TIMSK,r16
ret
    Aby skonfigurować Timer należy:
  • Ustawić bit psr10 w rejestrze SFIOR - reset preskalera(nie bardzo konieczne)
  • W rejestrze TCCR1B ustawić bity WGM12 (ustawienie maksymalnej wartoÅ›ci jako OCR1A), cs10 i cs12 te dwa bity odpowiadajÄ… za czÄ™stotliwość taktowania Timera
  • W rejestrze TIMSK ustawić bit OCIE1B (włączenie przerwania od porównania z rejestrem OCR1B).
Konfiguracja przetwornika ACDC :
adc.asm
; do przetwornika ADC
ADC_init:
	PUSH R16
	CLR R16
	out Admux, r16
	ldi r16, (1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)
	;ADEN - włączony przetwornik A/C
	;ADIE - włączenie generowania przerwania kiedy konwersja zakoñczona
	;ADSC - start przetwarzania A/C - bit wymagany równierz w trybie autowyzwalania	
	;ADATE - włączenie autowyzwalania - źródło wyzwalania zdefiniowane w rejestrze SFIOR 
	;ADPS2,ADPS1 - wybór częstotliwości taktowania przetwornika u nas = częstotliwość zegara/64
	out ADCSRA,R16
	;teraz ustawimy źródło wyzwalania przetwornika jako przerwanie timera1-porównanie;
	;ADST2-1, ADST1-0' ADST0-1 Timer/Counter1 Compare Match B
	in r16,SFIOR
	ldi tmp2, (1<<ADTS0)|(1<<ADTS2)
	or r16,tmp2
	out SFIOR,r16
	POP r16
RET 
    Aby skonfigurować przetwornik A/C:
  • Wyzerować rejestr ADMUX (wybieramy pierwszy pin portu PA jako wejÅ›cie do przetwornika AC)
  • W rejestrze ADCSRA ustawić bity: ADEN (włączony przetwornik A/C), ADIE (włączenie generowania przerwania kiedy konwersja zakoÅ„czona), ADSC(start przetwarzania A/C - bit wymagany również w trybie auto wyzwalania), ADATE (włączenie auto wyzwalania - źródÅ‚o wyzwalania zdefiniowane w rejestrze SFIOR), ADPS2,ADPS1(wybór czÄ™stotliwoÅ›ci taktowania przetwornika u nas = czÄ™stotliwość zegara/64)
  • W rejestrze SFIOR ustawić bity ADTS0 i ADTS2 (jako źródÅ‚o wyzwalania okreÅ›lamy przerwanie timera TIMER1_COMPB).

Uwagi końcowe - urządzenie pomiarowe

Więcej informacji o programie można dostać czytając komentarze w plikach źródłowych

    Kartę można skonfigurować przy pomocy terminala i tak
  • "a" Start zbierania danych
  • "c" WejÅ›cie do trybu konfiguracji
    • "t" Ustawienie trybu pracy karty
    • "T" Ustawienie okresu próbkowania jako wielokrotność 140 us
    • "n" Ustawienie iloÅ›ci zebranych próbek
  • "b" WyjÅ›cie z trybu konfiguracji
  • "?" Przedstawienie siÄ™ karty
  • "e" koniec zbierania danych

Programowanie właściwe - regulator mocy PWM

To będzie bardzo prosty programik mający na celu zmierzyć napięcie na potencjometrze i ta tej podstawie wygenerować przebieg PWM o odpowiednim współczynniku wypełnienia. Program składa się z procedury inicjującej przetwornik AC - przetwornik pracuje w trybie wolnego zbierania danych

Konfiguracja przetwornika ACDC :
adc.asm
ADC_init:
	PUSH R16
	 ;przesunięcie danych w rejestrach przetwornika - zmniejszam rozdzielczość pomiaru do 8 bitów
	ldi R16, (1<<ADLAR) 
	out Admux, r16
	ldi r16, (1<<ADEN)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADSC)
	;ADEN - włączony przetwornik A/C
	;ADIE - włączenie generowania przerwania kiedy konwersja zakończona
	;ADSC - start przetwarzania A/C - bit wymagany równierz w trybie autowyzwalania	
	;ADATE - włączenie autowyzwalania - źródło wyzwalania zdefiniowane w rejestrze SFIOR 
	;ADPS2,ADPS1 - wybór częstotliwości taktowania przetwornika u nas = częstotliwość zegara/64
	;źródło wyzwalania fre-rouning mode ADTS 0 0 0
	out ADCSRA,R16
	POP r16
RET 

Procedury inicjujÄ…cej Timer - timer pracuje w trybie PWM

Konfiguracja Timera1 -PWM:
Timer1.asm
Timer0_init:
;ustawienie mocy na zero
	ldi r16, $f0;
	out OCR0, r16;
;reset preskalera
	in r16,sfior
	sbr_ r16, psr10
	out sfior,r16;
;konnfiguracja timera jako PWM
	ldi r16, (1<<WGM00)|(1<<CS02)|(1<<COM01)
; podział czestotliwości na 1024 bity CS oraz ustawienie timera w tryb PWM bit WGM00
	out TCCR0, r16;
ret

ustawienie rejestru pwm odbywa się podczas obsługi przerwania przetwornika AC (konwersja zakończona) są to tylko 2 instrukcje asemblera.

Ustawienie współczynnika wypełnienia rejestr OCR0:
in r16,ADCH
out OCR0, r16

Podsumowanie

Tutaj przedstawię zdjęcie obrazujące jak nasze urządzenie pomiarowe współpracuje z programem w Labwiev

Do pobrania

UrzÄ…dzenie Pomiarowe - program mikro-kontrolera
UrzÄ…dzenie Pomiarowe - program PC (DELPHI)
UrzÄ…dzenie Pomiarowe - program PC (LABview)
Regulator mocy (obrotów silnika prądu stałego) - program mikro-kontrolera
Projekt elektroniczny regulatora (nie wykonany nie testowany)