Regulator PI Atmega asembler

Na tym forum rozmawiamy o elektronice nie związanej bezpośrednio z tematem CNC

Autor tematu
as124
Nowy użytkownik, używaj wyszukiwarki
Nowy użytkownik, używaj wyszukiwarki
Posty w temacie: 3
Posty: 3
Rejestracja: 10 maja 2007, 22:15
Lokalizacja: wroclaw

Regulator PI Atmega asembler

#1

Post napisał: as124 » 11 maja 2007, 19:45

Witam.
Co prawda mam wątpliwości co do działu w którym umieścić swój post ale chyba jednak ten jest najsłuszniejszy.
Buduję napęd silnika prądu stałego oparty na Atmedze8. I moim problemem jest implementacja algorytmu kaskadowego do sterowania silnikiem, a dokładniej regulatorów PI. (przepraszam za takie "mądre" określenie problemu, ale w ten sposób najłatwiej mi to opisać. Tak czy owak potrzebuje stworzyć program w asemblerze na Atmege który wykona zadanie regulatora PI.
Przechodząc do sedna sprawy muszę wykonać nastpujące operacje:

1. Obliczyć błąd uchybu e=Y0-Y (gdzie: Y0 to wartość zadana (8bitów) Y wartość zmierzona, aktualne (też 8bitów)
2. X1 = e pomnożone razy stałą wartość K1 (8 bitów).
3. In = I(n-1) + X1 (I(n-1) to wartość In z poprzedniej pętli algorytmu)
4. X2= e pomonożone razy druga stała K2 (8 bitów)
5 U=K1*e+I(n-1)

No i problem dla mnie stanowi rozwiązanie kwestii przepełnień przy dodawaniu i określenia znaku przy czym wartości Y0, Y, U są zapisane w zwykłym kodzie dwójkowym. Ktoś spotkał się z takim zadaniem?



Tagi:


jarekk
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1701
Rejestracja: 17 mar 2006, 08:57
Lokalizacja: Gdańsk

#2

Post napisał: jarekk » 11 maja 2007, 21:22

Sa to dość standardowe problemy arytmetyczne. Proponuję przestudiować teorię liczb zapisanych w kodzie U2 oraz używanie flag arytmetycznych procesora ( bity znaku, przepełnienia, zera etc.). Potrzebne też będzie "podówjna precyzja" - operacje na liczbach 16 bitowych


Autor tematu
as124
Nowy użytkownik, używaj wyszukiwarki
Nowy użytkownik, używaj wyszukiwarki
Posty w temacie: 3
Posty: 3
Rejestracja: 10 maja 2007, 22:15
Lokalizacja: wroclaw

#3

Post napisał: as124 » 11 maja 2007, 21:42

Po pierwsze przyznaję, że moja wiedza w temacie jest dość skąpa a rozwiązania problemu potrzebuje bardzo szybko, na tyle szybko, że sam nie dam rady tego wszystkiego opanować w tak krótkim czasie - dlatego prośba o pomoc na forum.

A odnośnie problemu zdaję sobie sprawę z konieczności wykorzystania wspominanych znaczników i zwiększania precyzji liczb. Problem w tym, że rozwiązania które przychodzą mi do głowy powodują straszne rozbudowanie kodu i mam przeczucie, że zadania takie rozwiązuje się dużo prościej niż metodami które jestem w stanie wymyślić.
Nie oczekuję też gotowego rozwiązania. Poprostu potrzebuje popchnięcia w prawidłowym kierunku na starcie.

Mam przeczucie, że w momencie mnożenia najlepiej będzie operować na liczbach zapisanych w kodzie z przecinkiem (1N7Q) dlatego moje pytanie w jaki sposób przenieść liczby zapisane "normalnie" (od 0 do 255) do formatu 1N7Q z zachowaniem jakichś proporcji między nimi.

Odnośnie 1 punktu algorytmu mam taki pomysł (proszę o ocenę czy słuszny i jeśli nie to wskazówkę jak zrobić to lepiej), by przejść do zapisu w kodzie uzupełnień do 2. Czyli przesuwam Y0 i Y w prawo o jeden bit. Zdaję sobie sprawę, że tracę na rozdzielczości obliczeń ale sądzę że zyskam w ten sposób uproszczenie algorytmu zyskując jednocześnie informację o znaku po wykonaniu odejmowania.

(Pracuję nad kodem który mi to umożliwi gdy skończę umieszczę go tutaj.)

Narazie mam coś takiego:

ldi R16, 100 ; przykladowe wartosci dodawane
ldi R17, 130

cp R16, R17 ; porównanie odjemnej i odjemnika
brlo e_ujemne
sub R16, R17 ; jesli wynik jest dodatni
mov R18, R16

e_ujemne:
sub R17, R16 ; jesli wynik jest ujemny
mov R18, R17

; ostateczny wynik w R18

[ Dodano: 2007-05-12, 03:27 ]
Innym rozwiązaniem dodawania jest:

ldi R16, -100 ;przykladowe wartosci dodawane
ldi R17, -30
add R16, R17

brvs wynik_niepoprawny ; skocz jesli wystapilo przepelnienie (V w SREG =1)
jmp koniec_dodawania ; jesli nie to wynik jest prawidlowy

wynik_niepoprawny:
brlt max_ujemny ; skocz jesli wynik jest ujemny z przepelnieniem
ldi R16, 0b01111111 ; jesli bylo przepelnienie ale wynik dodatni to ustaw 127
jmp koniec_dodawania

max_ujemny: ; jesli wynik jest ujemny i mniejszy od -128 to
ldi R16,0b10000000 ; ustaw wynik na -128

koniec_dodawania: ; ostateczny wynik w R16
jmp Main

Tutaj zastosowałem (sądzę że okaże się to uproszczeniem) "histerezowe" (8bitowe) ograniczenia wyniku. Jeśli ktoś doświadczony w pisaniu takich aplikacji mógłby mi doradzić którego rozwiązania się trzymać oraz (jeśli) co zmienić będę bardzo wdzięczny.


jarekk
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1701
Rejestracja: 17 mar 2006, 08:57
Lokalizacja: Gdańsk

#4

Post napisał: jarekk » 12 maja 2007, 16:32

To może lepiej obejrzeć kod źródłowy bibliotek napisanych w assemblerze zawartych w WinAvr ? Będzie tam wszystko co kolega potrzebuje.


Autor tematu
as124
Nowy użytkownik, używaj wyszukiwarki
Nowy użytkownik, używaj wyszukiwarki
Posty w temacie: 3
Posty: 3
Rejestracja: 10 maja 2007, 22:15
Lokalizacja: wroclaw

#5

Post napisał: as124 » 13 maja 2007, 09:14

Normalnie używam AVRSudio, o winavr słyszałem ale właściwie go nie widziałem i nie wiedziałem nic na ten temat, że ma jakieś biblioteki asemblera jak tak to poszukam go na sieci i popatrzę.


jarekk
ELITA FORUM (min. 1000)
ELITA FORUM (min. 1000)
Posty w temacie: 3
Posty: 1701
Rejestracja: 17 mar 2006, 08:57
Lokalizacja: Gdańsk

#6

Post napisał: jarekk » 13 maja 2007, 20:35

Proponuję odwiedzić www.avrfreaks.com

ODPOWIEDZ Poprzedni tematNastępny temat

Wróć do „Elektronika ogólna”