Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięBascom AVR Uart
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
Witam
Potrzebuję odebrać dane w formacie HEX przez uart 64 bajty z czego 10 pierwszych bajtów chciałbym sie pozbyć i 54 bajty przesłać dalej uartem
programowym. Jaką użyć instrukcje INPUTHEX czy INPUTBIN i do jakiego typu zapisać te zmienne.jestem początkującym bascomowcem
Potrzebuję odebrać dane w formacie HEX przez uart 64 bajty z czego 10 pierwszych bajtów chciałbym sie pozbyć i 54 bajty przesłać dalej uartem
programowym. Jaką użyć instrukcje INPUTHEX czy INPUTBIN i do jakiego typu zapisać te zmienne.jestem początkującym bascomowcem
a w jaki sposob odbierac rami o roznych dlugosciach????
probowałem czegoś takiego
ale niestety do bani
i druga sprawa - jeżeli zostaje wysłane więcej niż zadeklarowana w tablicy liczba znaków to procek sie zawiesza - procek to atmega 8
Jakies pomysły ktoś ma ?
probowałem czegoś takiego
Kod: Zaznacz cały
dim dane_in(25) as byte
dim index as byte
dim zmienna_pomocnicza as byte
baud=9600
enable Interrupts 'zezwolenie globalne
Enable Urxc 'zezwolenie na przerwanie
On Urxc Odbior
odbior:
disable URXC
do
zmienna_pomocnicza=ischarwaiting()
if zmienna pomocnicza = 1 then
inputbin dane_in(index)
index= index+1
if index=255 then exit do
loop
end if
Enable Urxc
RETURN
i druga sprawa - jeżeli zostaje wysłane więcej niż zadeklarowana w tablicy liczba znaków to procek sie zawiesza - procek to atmega 8
Jakies pomysły ktoś ma ?
Musicie ustawić bufor dla seriala jeśli tego nie zrobicie jakie kolwiek opóźnienie spowoduje nieodebranie znaku i co za tym idzie dane będą poszatkowane.
W sumie siedzę nad tym samym ale moje paczki są dużo krótsze bo tylko 6 byte-ów.
A i ja odbieram i wysyłam binarnie ale to nie powinno mieć znaczenia .
Do testów mogę polecic terminal ze strony pololu jest idealny do wysyłania małych paczek
POLOLU
W sumie siedzę nad tym samym ale moje paczki są dużo krótsze bo tylko 6 byte-ów.
A i ja odbieram i wysyłam binarnie ale to nie powinno mieć znaczenia .
Kod: Zaznacz cały
$sim
$regfile = "M128def.dat"
$crystal = 16000000 'Kwarc
$baud = 9600
'-----------konfiguracjia portu B i C jako wyjscie -----------
Config Portb = Output
Config Portc = Output
'-------------deklaracia zmiennych---------------------------
Dim Osy As Byte
Dim Osx As Byte
Dim Channel As Byte
Dim Serial_flag As Byte
Dim Serial_rx(6) As Byte
'-----------------konfiguracjia seriala----------------------
Config Serialin = Buffered , Size = 6
'-----------------konfiguracjia serv-------------------------
Config Servos = 2 , Servo1 = Portb.7 , Servo2 = Portb.6 , Reload = 10
Enable Interrupts
Echo On
Servo(1) = 40 'tak dla zabawy sprawdzam czy servo dziala
Servo(2) = 40 'jak wyżej
Print "start"
Cls
Do
Serial_flag = Ischarwaiting() 'jesli znak czeka to ustaw flage
Portb.0 = Serial_flag ' tylko do testów w symulacji programowej
If Serial_flag = 1 Then ' jelsi flaga =1
Inputbin Serial_rx(1) ; 1 'przypisz dane z bufora do tablicy startujac od pierwszego byte-u
Osy = Serial_rx(1) ; 1 'teraz do serva
Osx = Serial_rx(2) ; 1 ' i do drugiego serva
Print " servo1=" ; Osy 'dla testów wydruk serva 1
Print "servo2=" ; Osx 'dla testów wydruk serva 2
Clear Serialin 'to niewiem jak działa właśnie testuje
End If
Loop
End
POLOLU
serialin próbowałem ale niestety uważam tą funkcje za kiepsko opisaną
pomocne by było mieć jakiś przykład korzystający ze zmiennych _RS_HEAD_PTR0
_RS_TAIL_PTR0 _RS232INBUF0
rozumiem ze samo serialin korzysta z przerwania URXC i nie robię tutaj nic - jak jednak robić coś innego w głównej pętli a w przypadku przerwania od UART przejść do buforowania znaków?
użycie etykiety Serial0ByteReceived jakoś u mnie nie zadziałało (procek u mnie nie zaczął wykonywać instrukcji zawartych w tym podprogramie
Poza tym to rozumiem ze u Ciebie zostanie wpisana cała tablica 6 bajtów i że za każdym razem masz w ramce po 6 bajtów
w moim przypadku ilość bajtów jest różna i tutaj właśnie by się przydała zmienna _RS_TAIL_PTR0
- w raporcie kompilacji tez nie jest pokazanme zeby była - no chyba ze muszę te zmienne sam zadeklarowac a bascom będzie tylko samoczynnie modyfiukował ich zawartość
myślę ze instrukcja clear serialin zeruje również poza samym buforem i te zmienne wlasnie
tak to wygląda i nie działa - nie do końca rozumiem jeszcze polecenie Inputbin Zmienna_byte(1) ; 1 które "ściągnąłem z Twojego kodu ale rozumiem ze to jest od bajtu pierwszego z krokiem 1
powyzszy progam najzwyczajniej w swiecie tak jakb nie wykrywał przerwania
pomocne by było mieć jakiś przykład korzystający ze zmiennych _RS_HEAD_PTR0
_RS_TAIL_PTR0 _RS232INBUF0
rozumiem ze samo serialin korzysta z przerwania URXC i nie robię tutaj nic - jak jednak robić coś innego w głównej pętli a w przypadku przerwania od UART przejść do buforowania znaków?
użycie etykiety Serial0ByteReceived jakoś u mnie nie zadziałało (procek u mnie nie zaczął wykonywać instrukcji zawartych w tym podprogramie
Poza tym to rozumiem ze u Ciebie zostanie wpisana cała tablica 6 bajtów i że za każdym razem masz w ramce po 6 bajtów
w moim przypadku ilość bajtów jest różna i tutaj właśnie by się przydała zmienna _RS_TAIL_PTR0
- w raporcie kompilacji tez nie jest pokazanme zeby była - no chyba ze muszę te zmienne sam zadeklarowac a bascom będzie tylko samoczynnie modyfiukował ich zawartość
myślę ze instrukcja clear serialin zeruje również poza samym buforem i te zmienne wlasnie
Kod: Zaznacz cały
$regfile = "m8def.dat"
$crystal = 8000000
$regfile = "m8def.dat"
Baud = 9600 'ustawienie predkosci
Echo Off ' wylacz echo
config serialin =buffered ,size= 255
Dim Zmienna_byte(255) As Byte
Dim Index As Byte
Dim Index1 As Byte
Dim Zmienna_pomocnicza1 As Byte
Dim Jest_znak As Byte
Config Portb.0 = Output
Portb.0 = 1 'dioda zgaszona- tak mam podlaczone
Enable Interrupts 'zezwolenie globalne
Enable Urxc 'zezwolenie na przerwanie
'On Urxc Serial0ByteReceived 'okreslenie podprogramu przy przerwaniu od 'przychodzacego znaku- na razie jako komentarz bo przy serialin nie mozna tak określić 'podprogramu
'PETLA GŁÓWNA to petla glownego nic nie robienia
Do
Waitms 300
Portb.0 = Not Portb.0 ' tak sobie dioda miga
If Zmienna_pomocnicza1 = 1 Then
Gosub Wyswietlanie
End If
'KONIEC PETLI GŁÓWNEJ
Loop
Wyswietlanie:
Do'na razie kręci się w kółko cały czas potem sie to rzecz jasna zmieni
Zmienna_pomocnicza1 = 0
Portb.0 = 0
Do
Print "zmienna " ; Index1 ; "jest równa " ; Zmienna_byte(index1)
Index1 = Index1 + 1
If Index1 = 255 Then Exit Do
Loop
Loop
Enable Urxc
Zmienna_pomocnicza1 = 0
Portb.0 = 1
Return
Serial0ByteReceived:
Disable Urxc
Portb.0 = 1
Jest_znak = Ischarwaiting()
if jest_znak=1 then
Inputbin Zmienna_byte(1) ; 1
Zmienna_pomocnicza1 = 1
end if
jest_znak=0
Return
powyzszy progam najzwyczajniej w swiecie tak jakb nie wykrywał przerwania
Ostatnio zmieniony 26 kwie 2009, o 12:17 przez rdt, łącznie zmieniany 1 raz.
wydaje mi się ze trzeba użyć If Ischarwaiting()
zobacz na przykład opisany w samplach w bascomie :
Wiec wydaje mi sie ze program może sobie robić swoje a jak coś wpadnie do bufora to
If Ischarwaiting() musi to odebrać
Ja się dopiero tego uczę więc prowadził slepy kulawego ale może wspólnymi siłami damy rade.
Mam pomysł jeśli znasz maksymalna liczbę bajtów odbieranych.
To możesz paczkę wysyłaną zacząć od wysłania pierwszego bajtu który będzie mówił ile bajtów będziesz wysyłał i teraz _RS_BUFCOUNTR0 jeśli będzie równe pierwszemu bajtowi z tablicy będziesz mógł określić czy odebrałeś wszystko z tej paczki i wyczyścić bufor.
zobacz na przykład opisany w samplach w bascomie :
Kod: Zaznacz cały
$regfile = "m48def.dat" ' specify the used micro
$crystal = 8000000 ' used crystal frequency
$baud = 19200 ' use baud rate
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
'first compile and run this program with the line below remarked
Config Serialin = Buffered , Size = 20
Dim Nm As String * 1
'the enabling of interrupts is not needed for the normal serial mode
'So the line below must be remarked to for the first test
Enable Interrupts
Print "Start"
Do
'get a char from the UART
If Ischarwaiting() = 1 Then 'was there a char?
Nm = Waitkey()
Print Nm 'print it
End If
Wait 1 'wait 1 second
Loop
'You will see that when you slowly enter characters in the terminal emulator
'they will be received/displayed.
'When you enter them fast you will see that you loose some chars
'NOW remove the remarks from line 11 and 18
'and compile and program and run again
'This time the chars are received by an interrupt routine and are
'stored in a buffer. This way you will not loose characters providing that
'you empty the buffer
'So when you fast type abcdefg, they will be printed after each other with the
'1 second delay
'Using the CONFIG SERIAL=BUFFERED, SIZE = 10 for example will
'use some SRAM memory
'The following internal variables will be generated :
'_Rs_head_ptr0 BYTE , a pointer to the location of the start of the buffer
'_Rs_tail_ptr0 BYTE , a pointer to the location of tail of the buffer
'_RS232INBUF0 BYTE ARRAY , the actual buffer with the size of SIZE
If Ischarwaiting() musi to odebrać
Ja się dopiero tego uczę więc prowadził slepy kulawego ale może wspólnymi siłami damy rade.
Mam pomysł jeśli znasz maksymalna liczbę bajtów odbieranych.
To możesz paczkę wysyłaną zacząć od wysłania pierwszego bajtu który będzie mówił ile bajtów będziesz wysyłał i teraz _RS_BUFCOUNTR0 jeśli będzie równe pierwszemu bajtowi z tablicy będziesz mógł określić czy odebrałeś wszystko z tej paczki i wyczyścić bufor.
uzywam ischarwaiting
po 1 waitkey czeka az bedzie znak w buforze i zwraca kod ASCII (maly proble i latwo sie go da rowiązac poprzez asc()
po 2 odbieranie danych u mnie nie występuje cały czas - głównie program ma inne zadanie robić a w przypadku przerwania odebrać dane
po 3 w moim wcześniejszym kodzie program nie wykrywa przerwania - kod był pisany na podstawie sampla
OOO i jeszcze to
The following internal variables will be generated :
'_Rs_head_ptr0 BYTE , a pointer to the location of the start of the buffer
'_Rs_tail_ptr0 BYTE , a pointer to the location of tail of the buffer
'_RS232INBUF0 BYTE ARRAY , the actual buffer with the size of SIZE
nic takiego u mnie bascom nie wygenerował
a w raporcie kompilacji jest użyta tak wujowa czcionka ze ręce opadają - zmiana czcionki w opcjach nic nie daje
chyba sie zirytuje i przeinstaluje bascoma
po 1 waitkey czeka az bedzie znak w buforze i zwraca kod ASCII (maly proble i latwo sie go da rowiązac poprzez asc()
po 2 odbieranie danych u mnie nie występuje cały czas - głównie program ma inne zadanie robić a w przypadku przerwania odebrać dane
po 3 w moim wcześniejszym kodzie program nie wykrywa przerwania - kod był pisany na podstawie sampla
OOO i jeszcze to
The following internal variables will be generated :
'_Rs_head_ptr0 BYTE , a pointer to the location of the start of the buffer
'_Rs_tail_ptr0 BYTE , a pointer to the location of tail of the buffer
'_RS232INBUF0 BYTE ARRAY , the actual buffer with the size of SIZE
nic takiego u mnie bascom nie wygenerował
a w raporcie kompilacji jest użyta tak wujowa czcionka ze ręce opadają - zmiana czcionki w opcjach nic nie daje
chyba sie zirytuje i przeinstaluje bascoma
Zrobił się mix jak ja edytowłaem swojego posta to ty wysyłałeś swojego wiec to co ja napisałem jest bez sensu.
Daj mi chwile na test tego co posłałeś.
Daj mi chwile na test tego co posłałeś.
Ostatnio zmieniony 2 maja 2009, o 22:15 przez pikczu, łącznie zmieniany 1 raz.
Włącz symulację programowa włącz podgląd sramu i zobaczysz że te
'_Rs_head_ptr0 BYTE , a pointer to the location of the start of the buffer
'_Rs_tail_ptr0 BYTE , a pointer to the location of tail of the buffer
'_RS232INBUF0 BYTE ARRAY , the actual buffer with the size of SIZE
są za rezerwowane w pamięci
zobacz na screen shota twój program nie opuszcza tej pierwszej pętli.
Posiedzę nad tym później.
Bo moja małżonka dostaje wścieklicy macicy teraz muszę lecieć
-----------------------------18:00-----------------------------------------------
troszkę powalczyłem z tym twoim kodem
wiec tak jak używasz przerwania od Urxc to nie używasz config serial z buforem
bo wyskakują błędy że to już jest zrobione
wiec za REM-uj te configi i od REM-uj to przerwanie od Urxc
wtedy bedzie działać ale i tak kreci się jak szalone w tej pętli do 255 i wypełnia tablice tylko pierwszym w sumie jedynym znakiem jaki się odebrał.
Moim zdaniem musisz to wszytko zrobić od nowa.
Nie trybiłem tego ale jak wygrzebałem z helpa przykład otwarło mi oczy.
'_Rs_head_ptr0 BYTE , a pointer to the location of the start of the buffer
'_Rs_tail_ptr0 BYTE , a pointer to the location of tail of the buffer
'_RS232INBUF0 BYTE ARRAY , the actual buffer with the size of SIZE
są za rezerwowane w pamięci
zobacz na screen shota twój program nie opuszcza tej pierwszej pętli.
Posiedzę nad tym później.
Bo moja małżonka dostaje wścieklicy macicy teraz muszę lecieć
-----------------------------18:00-----------------------------------------------
troszkę powalczyłem z tym twoim kodem
wiec tak jak używasz przerwania od Urxc to nie używasz config serial z buforem
bo wyskakują błędy że to już jest zrobione
wiec za REM-uj te configi i od REM-uj to przerwanie od Urxc
wtedy bedzie działać ale i tak kreci się jak szalone w tej pętli do 255 i wypełnia tablice tylko pierwszym w sumie jedynym znakiem jaki się odebrał.
Moim zdaniem musisz to wszytko zrobić od nowa.
Nie trybiłem tego ale jak wygrzebałem z helpa przykład otwarło mi oczy.
Kod: Zaznacz cały
'--------------------------------------------------------------------
' SERINT.BAS
' (c) 1999-2005 MCS Electronics
' serial interrupt example for AVR
' also look at CONFIG SERIALIN for buffered input routines
'--------------------------------------------------------------------
$regfile = "m88def.dat"
$baud = 19200
$crystal = 8000000
Const Cmaxchar = 20 'number of characters
Dim B As Bit 'a flag for signalling a received character
Dim Bc As Byte 'byte counter
Dim Buf As String * Cmaxchar 'serial buffer
Dim D As Byte
'Buf = Space(20)
'unremark line above for the MID() function in the ISR
'we need to fill the buffer with spaces otherwise it will contain garbage
Bc = 0
Print "Start"
On Urxc Rec_isr 'define serial receive ISR
Enable Urxc 'enable receive isr
Enable Interrupts 'enable interrupts to occur
Do
If B = 1 Then 'we received something
Disable Serial
Print "{" ; Buf ; "}" 'print buffer
Print "BC:" ; Bc 'print character counter
'now check for buffer full
If Bc = Cmaxchar Then 'buffer full
Buf = "" 'clear
Bc = 0 'rest character counter
End If
Reset B 'reset receive flag
Enable Serial
End If
Loop
Rec_isr:
D = Udr 'read UDR only once
Print "*" ' show that we got here
If Bc < Cmaxchar Then 'does it fit into the buffer?
Incr Bc 'increase buffer counter
If D = 13 Then 'return?
Buf = Buf + Chr(0)
Bc = Cmaxchar 'at the end
Else
Buf = Buf + Chr(d) 'add to buffer
End If
' Mid(buf , Bc , 1) = Udr
'unremark line above and remark the line with Chr() to place
'the character into a certain position
'B = 1 'set flag
End If
B = 1 'set flag
Return
Ostatnio zmieniony 26 kwie 2009, o 18:48 przez pikczu, łącznie zmieniany 1 raz.
musialem źle przepisać - jednak próbowałem i z zaremowanym on URXC
a oto moje rozwiazanie
i tym oto prostym sposobem mam w zmiennej Zmienna_byte(255) zapisane bajty od 1 do ostatniego - wskaźnikiem ostatniego jest zmienna index
poniewaz czyszcze bufor serialin to zmienna _rs_head_ptr0 jest zawsze taka sama
a oto moje rozwiazanie
Kod: Zaznacz cały
$regfile = "m8def.dat"
$crystal = 8000000
$regfile = "m8def.dat"
Baud = 9600 'ustawienie predkosci
Echo Off ' wylacz echo
Config Serialin = Buffered , Size = 255
Dim Zmienna_byte(255) As Byte
Dim Index As Byte
Dim Zmienna_pomocnicza1 As Byte
Config Portb.0 = Output
Portb.0 = 1 'dioda zgaszona- tak mam podlaczone
Enable Interrupts 'zezwolenie globalne
'PETLA GŁÓWNA to petla glownego nic nie robienia
Do
Waitms 300
Portb.0 = Not Portb.0
'ten warunek mi wykrywa przychodzącą ramkę
If _rs_head_ptr0 < _rs_tail_ptr0 Then Gosub Odbior
loop
Odbior:
' ta petla sprawdza czy skonczylo nadawac
do
tu bedzie jakies przerwanie od UDRE chyba
loop
' jesli skonczylo nadawac to musze sobie przerzucić bufor 'SERIALIN do swojego bufora
disable interrupts
Index = 1 'bo tablice w bascomie nie mają indexu zero
Do
Zmienna_byte(index) = _rs232inbuf0(index)
Index = Index + 1
Loop Until Index > _rs_tail_ptr0
'gdyby było Index = _rs_tail_ptr0 to zgubiłoby ostatni bajt i wpisałoby 0
'przed wyczysczeniem bufora serialin i zmiennych '_rs_tail_ptr0, i rs_head_ptr0 chce zapamietac ile bylo bajtow wiec zapisuje do index
Index = _rs_tail_ptr0
Zmienna_pomocnicza1 = 1 'taka sobie zmienna uzywana gdzie indziej
Clear Serialin 'tutaj czyszcze bufor i zmienne
'enable interrupts 'włączam przerwania i czekam na nastepna ramke
'wyremowalem bo jeszcze trzeba bedzie przetworzyc ramke przed zezwoleniem na przerwania
Return
poniewaz czyszcze bufor serialin to zmienna _rs_head_ptr0 jest zawsze taka sama
No i kaplica teraz to już mogę ten soft tylko w symulacji programowej sprawdzić
Uwaliłem dwa at mega 128.
Fusy mi się przestawiły przypadkiem i nie wiem jakie.
--------------2.05.09----------------------
fusy odblokowane
Uwaliłem dwa at mega 128.
Fusy mi się przestawiły przypadkiem i nie wiem jakie.
--------------2.05.09----------------------
fusy odblokowane
Ostatnio zmieniony 2 maja 2009, o 20:19 przez pikczu, łącznie zmieniany 1 raz.
ok zrób tak - bufor na serialin weź np 50
wprowadź po UART np 20 znaków
przepisz te 20 znaków do jakiejś zmiennej (ale tylko te 20 nie całą tablicę )
NIE CZYŚĆ BUFORA serialin
wprowadź po uart kolejne znaki
teraz sprawdź jaką wartość ma rs_head_ptr0
Je czyszczę bufor po przepisaniu wszystkiego - nieważne czy tam są zera czy jakaś wartość całość przepisuje sobie do innej zmiennej - dlatego mam zawsze zero
wprowadź po UART np 20 znaków
przepisz te 20 znaków do jakiejś zmiennej (ale tylko te 20 nie całą tablicę )
NIE CZYŚĆ BUFORA serialin
wprowadź po uart kolejne znaki
teraz sprawdź jaką wartość ma rs_head_ptr0
Je czyszczę bufor po przepisaniu wszystkiego - nieważne czy tam są zera czy jakaś wartość całość przepisuje sobie do innej zmiennej - dlatego mam zawsze zero
ok teraz to juz mam problem z drugiej strony mianowicie jak wbije do procka polecenie
to wszystko działa OK i delphi ładnie czyta
jak zrobię tak
to kupa - i źle odczytuje
O dziwo inne programy odbierają poprawnie (inne nie pisane przeze mnie)
ok sprawa załatwiona
nie jest to jasno napisane w helpie ale sprawa jest taka -
polecenie printbin zmienna_tablicowa(index) drukuje od konkretnego indexu do skonczenia tabeli
Można sie zorientować po przykładzie w helpie - jakby komuś było potrzebne to będzie wiedział o co chodzi
Kod: Zaznacz cały
Printbin 5 ; 4 ; 4 ; 55 ; 22 ; 4 ; 95 ; 19 ; 22
jak zrobię tak
Kod: Zaznacz cały
Dane_out(1) = 5
Dane_out(2) = 4
Dane_out(3) = 4
Dane_out(4) = 55
Dane_out(5) = 22
Dane_out(6) = 4
Dane_out(7) = 95
Dane_out(8) = 0
Dane_out(9) = 0
printbin dane_out(1) ;dane_out(2) ;dane_out(3);dane_out(4); ....itd
O dziwo inne programy odbierają poprawnie (inne nie pisane przeze mnie)
ok sprawa załatwiona
nie jest to jasno napisane w helpie ale sprawa jest taka -
polecenie printbin zmienna_tablicowa(index) drukuje od konkretnego indexu do skonczenia tabeli
Można sie zorientować po przykładzie w helpie - jakby komuś było potrzebne to będzie wiedział o co chodzi
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 46 gości