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

sebo54
-
-
Posty: 3
Rejestracja: 13 wrz 2008, o 07:11
Lokalizacja: wwy

Bascom AVR Uart

Postautor: sebo54 » 19 kwie 2009, o 17:34

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

Awatar użytkownika
j_bravo
-
-
Posty: 189
Rejestracja: 14 wrz 2005, o 16:30
Lokalizacja: Lublin
Kontaktowanie:

Postautor: j_bravo » 21 kwie 2009, o 20:18

Dim ar(53) As Byte
Inputbin ar(1) , 54

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 24 kwie 2009, o 21:21

a w jaki sposob odbierac rami o roznych dlugosciach????
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
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 ?

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 26 kwie 2009, o 10:42

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 .

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
Do testów mogę polecic terminal ze strony pololu jest idealny do wysyłania małych paczek
POLOLU
Załączniki
pololu.JPG

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 26 kwie 2009, o 11:33

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


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
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
Ostatnio zmieniony 26 kwie 2009, o 12:17 przez rdt, łącznie zmieniany 1 raz.

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 26 kwie 2009, o 12:02

wydaje mi się ze trzeba użyć If Ischarwaiting()
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
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.

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 26 kwie 2009, o 12:26

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

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 26 kwie 2009, o 12:37

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ś.
Ostatnio zmieniony 2 maja 2009, o 22:15 przez pikczu, łącznie zmieniany 1 raz.

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 26 kwie 2009, o 13:03

znam maksymalną ilość bajtów które mają byc odebrane ale nie ja wysyłam te bajty tylko urządzenie master
poniewaz slave jest kilka to paczki są różne - generalnie to modbus

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 26 kwie 2009, o 13:19

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.

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
Załączniki
SRAM.JPG
Ostatnio zmieniony 26 kwie 2009, o 18:48 przez pikczu, łącznie zmieniany 1 raz.

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 26 kwie 2009, o 18:27

ok wydaje mi się ze sobie poradziłem
posprawdzam kod i później wstawię

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 26 kwie 2009, o 18:51

Jak będziesz miał czas to wklej chętnie zobaczę

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 26 kwie 2009, o 23:00

musialem źle przepisać - jednak próbowałem i z zaremowanym on URXC
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
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

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 28 kwie 2009, o 23:15

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 :)
Ostatnio zmieniony 2 maja 2009, o 20:19 przez pikczu, łącznie zmieniany 1 raz.

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 2 maja 2009, o 20:18

Może mi ktoś wyjaśnić, pomóc zrozumieć dlaczego ten rs_head_ptr0 zawsze ma wartość 0
jeśli on się nigdy nie zmienia to poco on jest???

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 3 maja 2009, o 18:35

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

Awatar użytkownika
pikczu
-
-
Posty: 89
Rejestracja: 5 paź 2003, o 19:55
Lokalizacja: Dublin
Kontaktowanie:

Postautor: pikczu » 4 maja 2009, o 21:59

Dzięki wielkie wyraźnie widać to w tedy jak na przykład bufor ma wiele więcej miejsca niż tablica do której to zapisuje.

rdt
-
-
Posty: 87
Rejestracja: 20 sie 2003, o 18:03
Lokalizacja: 100km od Wawy

Postautor: rdt » 12 maja 2009, o 13:06

ok teraz to juz mam problem z drugiej strony mianowicie jak wbije do procka polecenie

Kod: Zaznacz cały

Printbin 5 ; 4 ; 4 ; 55 ; 22 ; 4 ; 95 ; 19 ; 22
to wszystko działa OK i delphi ładnie czyta
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
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

Wróć do „Projektowanie PCB, programy EDA, CAD, narzędziowe”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 30 gości