♬ ☘ Moja muzyka do majstrowania ♬ ♬ ♬ ☘
♫ ♩ ♪ Avantasia ☘ Another Angel Down ♪ ♩ ♫
https://youtu.be/tPhGvWURgIAgaweł pisze:Jestem pewien, że w przypadku jakichkolwiek problemów, możesz poprosić o pomoc i zostanie ci ona udzielona. W końcu te forum to prawie rodzina
Z proszeniem o pomoc to u mnie jest dość słabo, ale oczywiście bardzo dziękuje za chęci. Słowo rodzina traktuję dość szczególne i fora internetowe jednak się w to pojęcie nie wpasowują.
Marcin pisze:PICe u nas mało znane, te starsze wersje ubogie i dla konstruktora amatora szczególnej przewagi nad konkurencją nie prezentują.
I w tym dla mnie cały ich urok, tak na przekór. Zakładam, że po pewnym czasie wyrobię sobie własne zdanie o ich możliwościach, nie tylko w kategoriach sprzętu ale i komfortu programowania, przyjazności narzędzi, etc. I wtedy może pokuszę się na ocenę, a póki co jest radocha z odkrywania koła po raz n-ty.
piotrek pisze: (...) a tutaj od razu od asemblera. Cud, miód i orzeszki
Ano właśnie od assemblera...więc oprócz słodyczy jest też sporo pieprzu (w ramach możliwości polskiej gramatyki i słowotwórstwa), ale dzięki temu jest w sumie ciekawie. Język C też pomaga, ale jest na drugim planie, w rezerwie, wydłubanie programiku w C nie jest dla PIC jakimś wielkim wyzwaniem, takie mam wrażenie...mpasm daje do wiwatu...
Myślę, że powyższe może zakończyć cześć dialogową, kolejny odcinek grafomanii będzie traktował o komunikacji szeregowej z wykorzystaniem pokładowego UART-a. Napisano o tym w sieci wiele, ja akurat zerkałam na te stronki:
http://www.oz1bxm.dk/PIC/628uart.htm https://www.teachmemicro.com/serial-usart-pic16f877a/ https://www.exploreembedded.com/wiki/Se ... PIC16F877A https://github.com/magkopian/pic-assemb ... ith%20uartNo i oczywiście jednym okiem w dokumentację '876 oraz lista rozkazów plebejskiej klasy średniej
http://ww1.microchip.com/downloads/en/d ... 31029a.pdf wprawdzie korzystam z cudzego, no ale niech będzie, że świadomie. Aby nie robić wioski dołączam schemat ideowy piaskownicy jak i fotki. Ledy tym razem są trzy, ponieważ celem ćwiczenia jest spreparowanie programiku, który oprócz realizacji prostego echa (znaczkowej papugi) będzie identyfikował czy ma do czynienia z cyfrą czy literą (zarówno dużą jak i małą) i pokaże to na żółtej lub zielonej lampce. W przypadku odebrania znaczka innego niż wymienione - pozostaje mu lampka czerwona.
pic-1.jpg
Oczywiście nie wszystko na raz, najpierw powstał prosty progamik realizujący znakowe echo:
/asm-echo-rxtx-simple-1.X/main.asm pisze:Kod: Zaznacz cały
processor 16f876
include <p16f876.inc>
; https://www.tme.eu/Document/c3972e2483251b2e1f702409912d1888/pic16f87x.pdf
; ustawienia procesora
__config _FOSC_HS & _WDT_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF
radix dec ; (!)
XTAL_REQ equ 8000000
BAUD_9600 equ XTAL_REQ/(16*9600)-1 ; 51
; blok danych w bank 0, wolne mamy od 0x20
cblock 0x020
tempByte : 1 ; znaczek tymczasowy
delCntr1 : 1 ; programowy licznik
delCntr2 : 1 ; i kolejny
endc
reset_vector: code 0x0000
goto main
;-------------------------------------------
application: code
main:
call initUart
mainLoop:
call getChar
; movwf tempByte
; xorlw 0x0D ; czy == CR?
; btfsc STATUS, Z
; call sendExtraLF ; wtedy dodaj LF-a
; movfw tempByte
call putChar
goto mainLoop
;-------------------------------------------
; dosłanie LF-a na terminal
sendExtraLF:
movlw 0x0A
call putChar
return
;-------------------------------------------
; blokujące wysłanie znaczka z W
putChar:
bcf STATUS,RP0 ; bank 0
movwf TXREG
bsf STATUS,RP0 ; bank 1
putChar_wait:
btfss TXSTA, TRMT ; while ( TXSTA.TRMT != 1 )
goto putChar_wait
bcf STATUS,RP0 ; bank 0
return
;-------------------------------------------
; blokujące odbieranie znaczka do W
getChar:
bcf STATUS,RP0 ; bank 0
getChar_wait:
btfss PIR1,RCIF ; while ( PIR1.RCIF != 1)
goto getChar_wait
movf RCREG,W ; save received data in W
return
;-------------------------------------------
; setup portu szeregowego
initUart:
bsf STATUS, RP0 ; bank 1
movlw BAUD_9600 ; szybkość transmisji
movwf SPBRG
; włącz nadajnik generator, na highspeed, reszta bitów 0 co daje
; transmisje 8bit, asynchroniczną
movlw (1<<TXEN)|(1<<BRGH)
movwf TXSTA
bcf STATUS, RP0 ; bank 0
movlw (1<<SPEN)|(1<<CREN); włącz UART
movwf RCSTA
; to do zastanowienia czy z sensem
call delay
; ślepe odczyty zaległości z fifo
movf RCREG,W
movf RCREG,W
movf RCREG,W
return
;-------------------------------------------
delay:
movlw 0xFF
movwf delCntr1
delay_1:; petelka zewnetrzna (dekrementuje cntr1)
movlw 0xFF
movwf delCntr2
delay_2:; petelka wewnetrzna (dec na cntr2)
nop
decfsz delCntr2,f ; delCntr2--
goto delay_2 ; while (delCntr2 != 0)
decfsz delCntr1,f ; delCntr1--
goto delay_1 ; while (delCntr1 != 0)
return
end
Powyższe jest w pewnym sensie średnią z detali dostępnych na wskazanych stronkach, pogrupowałam całość w trzy główne procedurki:
initUart,
getChar,
putChar, delay już znamy. No i tu
mpasm pokazał pazury, a w pewnym momencie cztery litery. Wyliczanie stałej dla szybkości transmisji to był zonk. Proszę, niby proste (pomijając literówkę - miało być FREQ, oczywiście, sorki):
Kod: Zaznacz cały
XTAL_REQ equ 8000000
BAUD_9600 equ XTAL_REQ/(16*9600)-1
Sztuczka polega na tym, że gdy zerkniemy na ustawienia IDE:
Project Properties -> Conf -> mpasm to znajdziemy tam:
Default radix : HEX, co oznacza, że wszelkie stałe numeryczne pozbawione prefiksu (czy 0x, D', B') są traktowane jako szesnastkowe. Łatwo zgadnąć, że w takim wypadku powyższe wyliczenia dadzą wartości z koziej trąbki, co nie zmieni faktu, że program się skompiluje, załaduje, tylko nie zadziała. Oj nagoniłam się chwilę zanim oko me nie zawisło na dyrektywie assemblera
radix, która mówi jak narzędzie ma domyślnie potraktować liczby bez żadnych ozdobników.
Następna rzecz, której nie jestem do końca jeszcze pewna to końcówka inicjalizacji uarta, a mianowicie delay i potem kilka pustych odczytów, aby wysycić fifo, PIC-owy Uart posiada FIFO (dwa znaczki) więc jakiś sens to ma, ale pewnie zalety objawią się, gdy urządzenie nadawcze będzie już coś wysyłało, podczas gdy systemik z PIC-em dopiero się ogarnia.
No i z ewidentnie słabych stron, to zabrakło mi oprogramowania błędów odbierania, overrun i framig error, no tak. Programik testowałam w warunkach cieplarnianych, strona nadawcza (mój PC)
raczej-*** nie wycinała numerów. Filmik z działania tej wersji mamy poniżej.
https://youtu.be/pT85Ae5V_zMI tu taka ciekawostka - GTK Term na skutek ENTER wysyła tylko znaczek CR. No i linijki się nie łamały w okienku. Rozwiązanie proste - dorobić wysyłanie ekstra znaczka LF gdy przyjdzie CR, wtedy jest dobrze. Wiem, że jest w opcjach `auto cr-lf`, ale wtedy nie było by tej odrobiny prostej algorytmiki. Ten fragment kodu mamy w pętli głównej chwilowo objęty komentarzem, na filmie są oba.
Z całego tego programiku najciekawsze jest ciągłe żaglowanie bankami, normalnie masakra aby się nie pomylić, ale autentycznie zaczyna się pamiętać, w którym co siedzi, choć dlaczego akurat tak rozsypali SFR-y po przestrzeni adresowej - to jest ciągle dla mnie zagadka.
Cały projekt dla MPLAB-X
https://github.com/bienata/picnawode/tr ... simple-1.X*** kluczowe jest słowo - raczej
No więc właśnie, po wczorajszych śwatełkowych zbytkach, prosto z trasy i mocno po północy - myślę sobie: a coś jeszcze podłubię, nie szło klecenie więc w bety. Od rana do komputera i brzdęk! Coś co wcześniej - dam sobie głowę uciąć - działało, rano szaleje. UART zachowywał się idiotycznie, w sensie nie reagował w ogólne na nadchodzące znaki lub po odebraniu jednego - przestawał reagować i tylko jego zwracał, masakra z elementami paniki. Faktem jest, że płytka stykowa została pod prądem (i z podłączonymi próbnikami logicznymi), nie porozłączałam USB od PICKIT-a, a system zahibernowałam zamiast zamknąć, możliwe że to wprowadziło całość w jakiś dziwny stan i nawet clean+build i przeprogramowanie kostki nie dawało rezultatu. I tu powstało zagadnienie - nie mam pewnego, mega-prostego kawałka softu, którym mogę niezależnie zweryfikować czy cześć sprzętowa jest ok. No i łatwo zgadnąć - tu przydało się C, na kolanie sklecony ratunkowy program wygląda tak:
/c-echo-rxtx-simple-1.X/main.c pisze:Kod: Zaznacz cały
#define _XTAL_FREQ 8000000
#include <xc.h>
#include <pic16f876.h>
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
void putch( char data ){
TXREG = data;
while( TRMT == 0 );
}
unsigned char getch( void ){
while( RCIF == 0 );
return RCREG;
}
void main( void ) {
unsigned char c;
TRISB = 0; // port out
PORTB = 0; // ledy off
SPBRG = 51; //9600 @ 8MHz
TXEN=1; // nadajnik on
BRGH=1; // baudy na high
SPEN=1; // serial on
CREN=1; // cont.rec. on
while( 1 ) {
c = getch();
PORTB = c & 0x07; // pokaż, że żyjesz
putch ( c );
}
}
Program robi echo i mruga lampkami, to taki test czy chiński PICKIT3 oraz biedny mały PIC w ogóle jeszcze żyją, filmik pamiątkowy:
https://youtu.be/Xmt0VMwk6qEI kolejny projekt dla MPLAB-X
https://github.com/bienata/picnawode/tr ... simple-1.XTotalny restart całego mojego majdanu na szczęście pomógł, dalsza zabawa to zgodnie ze wstępem - rozróżniaczka do cyferek i literek. Zaczęłam coś tam szkicować w assemblerze i powstało zagadnienie porównywania wartości numerycznych, a do obsłużenia są trzy zakresy wartości kodów ASCII - "0"..."9", "a"..."z" oraz "A"..."Z" no i to co pomiędzy nimi. I tak goglując wpadłam na bardzo ciekawe opisy różnych implementacyjnych przydasiów, proszę:
http://picprojects.org.uk/projects/pictips.htm A to spodobało mi się najbardziej: mpasm posiada garść pseudo instrukcji (12-Bit/14-Bit Instruction Width Pseudo-Instructions)
http://picprojects.org.uk/projects/pseudoins.htm to mega ułatwienie moim zdaniem. BTW, chwila poszukiwań wykazała, że takie instrukcje są dostępne w burżuazyjnych kostkach 18F, małe bidy mają to udawane na poziomie translatora. Finalnie wyszedł mi niezbyt skomplikowany programik, ale pokręceń nieco tam jest, pętla główna:
/asm-echo-rxtx-sel-led-1.X/main.asm pisze:Kod: Zaznacz cały
mainLoop:
call getChar
movwf tempByte ; na bok
; zgas poprzednie stany ledów
movlw 0x00
movwf PORTB
; badamy kolejno - czy cyfry
movlw "0"
movwf asciiMin
movlw "9"
movwf asciiMax
call isCharInRange ; sprawdzenie <min,max>
bz indicateDigit
; jak nie, to czy dolne literki
movlw "a"
movwf asciiMin
movlw "z"
movwf asciiMax
call isCharInRange ; sprawdzenie <min,max>
bz indicateAlpha
; a duże litery?
movlw "A"
movwf asciiMin
movlw "Z"
movwf asciiMax
call isCharInRange ; sprawdzenie <min,max>
bz indicateAlpha
; no to nie wiem, czerwony OTHER led
bsf PORTB, OTHER_LED
main_sendBack:
; odeslij znaczek
movfw tempByte
call putChar
goto mainLoop ; while ( 1 )
; a tu zaczyna się spagetti
indicateDigit:
bsf PORTB, DIGIT_LED
goto main_sendBack
indicateAlpha:
bsf PORTB, ALPHA_LED
goto main_sendBack
No i procedurka rozpoznająca znaki i jej zmienne robocze:
/asm-echo-rxtx-sel-led-1.X/main.asm pisze:Kod: Zaznacz cały
cblock 0x020
tempByte : 1 ; znaczek tymczasowy
asciiMin : 1 ; zmienne procedurek badających zakres
asciiMax : 1 ; wejściowego kodu ASCII
endc
/asm-echo-rxtx-sel-led-1.X/main.asm pisze:Kod: Zaznacz cały
isCharInRange:
movfw asciiMin
subwf tempByte,W
bc isCharInRange_gteq_min
; skasuj Z, znaczek poniżej zakresu
clrz
return
isCharInRange_gteq_min:
; to teraz czy < max+1
movfw asciiMax
addlw 1 ; +1 aby domknąć przedział
subwf tempByte,W
bnc isCharInRange_lt_max
; skasuj Z, znaczek powyżej zakresu max
clrz
return
isCharInRange_lt_max:
setz ; znaczek w domknietym przedziale
return ; wychodzimy z Z := 1
Procedurki putChar, getChar i reszta jak w poprzednim programie, a tak wygląda całość na żywo:
https://youtu.be/f-CDrOTsqfYW podsumowaniu odcinka -
na chwilę obecną moje zdanie jest takie, że mpasm jest całkiem sprytnym narzędziem, a mnemoniki typu
btfss można nawet polubić. W końcu `ipmdbk butelka,2` rozwinięte do `idź po mleko do Biedry, kup 2 butelki` nie budzi wątpliwości...
Do trzech razy sztuka, ostatni dziś zatem projekt dla MPLAB-X
https://github.com/bienata/picnawode/tr ... el-led-1.XDobranoc.
#slowanawiatr
#picnawode
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.