Strona 1 z 1

Regulator PI Atmega asembler

: 11 maja 2007, 19:45
autor: as124
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?

: 11 maja 2007, 21:22
autor: jarekk
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

: 11 maja 2007, 21:42
autor: as124
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.

: 12 maja 2007, 16:32
autor: jarekk
To może lepiej obejrzeć kod źródłowy bibliotek napisanych w assemblerze zawartych w WinAvr ? Będzie tam wszystko co kolega potrzebuje.

: 13 maja 2007, 09:14
autor: as124
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ę.

: 13 maja 2007, 20:35
autor: jarekk
Proponuję odwiedzić www.avrfreaks.com