Muszę przesyłać do Atmegi przez UART daną 4 bajtową w formie ASCII.
Trzeci i czwarty bajt może przy niektórych ramkach być z przedziału 1..255 jako liczba Byte.
A w pętli głównej Input'em. Problem jest jednak z tym bajtem liczbowym.
W przypadku nadawania np. czwartej liczby=8 która jest w ASCII Backspacem, wcześniejsza trzecia litera zostaje skasowana tak jakby działał na nią "Backspace", jeśli odbieram ją Input'em.
Tworzysz zmienną czterobajtową (Dim zmienna(4) as byte), czytasz cztery kolejne bajty odebrane przez port szeregowy z automatu, instrukcją INPUTBIN zmienna(1) , 4
Instrukcja ta odczyta cztery bajty z bufora portu szeregowego (w formie surowych bajtów), i zapisze je w zmiennej wielobajtowej "zmienna" począwszy od bajtu (pozycji) 1.
A poszczególne bajty ze zmiennej wielobajtowej czytasz po pozycji - zmienna(1) oznacza pierwszy bajt, lub "od pierwszego bajtu". Nie jestem teraz 100% pewien (i nie mam możliwości sprawdzenia, piszę z pamięci) ale wydaje mi się że żeby wczytać dwa pierwsze bajty zmiennej wielobajtowej do zmiennej typu n.p. word wystarczy polecenie:
Napisałeś że musisz przesłać / odebrać 4 bajty, więc pomyślałem że INPUTBIN będzie dobre.
Czy wysyłasz znak początku ramki?
Jak wykryć znak końca ramki? Ja bym to zrobił w przerwaniu URXC, sprawdzając co przyszło do bufora UDR, jeśli nie jest to znak końca ramki to dopisywałbym to do wielobajtowej zmiennej, jeśli natomiast byłby to znak końca ramki to nie dopisywałbym nic, ale ustawiłbym dodatkowy bit "dana_gotowa" tak, aby podprogram który będzie obrabiał te dane wiedział że ma do czynienia z kompletnym źródłem.
Możesz też zabezpieczyć się przed błędami i założyć maksymalną długość ramki, jeśli dana przychodząca "przeleci" poza zakres to możnaby ustawić bit "blad_RX" na 1, po czym dalej czytać UDR w przerwaniu czekając na znak początku ramki.
EDIT: z tym że musisz to robić na porcie sprzętowym, tylko wtedy będziesz miał dostęp do rejestru UDR. Obsługa przerwania możliwie krótka (może wstawka w ASM?) aby nie gubiło danych, ewentualnie zmodyfikować program na PC tak, aby przed wysłaniem kolejnego bajtu danych czekał on na potwierdzenie odbioru poprzedniego.
W pętli głównej czekam na event, i tu można byłoby przepisać bezpośrednio z bufora UARTa do tablicy. Tylko gdzie jest ten bufor i czy można bezpośrednio przepisać ramkę ?
W ten sposób pozbyłbym się problemów z INPUTami.
Manual BASCOM-a, w opisie instrukcji SERIALIN mówi że bufor danych wejściowych przechowywany jest w wewnętrznej tablicy bajtów _RS232INBUF0 . Oprócz tego są dwa wskaźniki, na początek tych danych oraz na ich rozmiar.
'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
Niestety nie jest podany adres tej tablicy (pewnie jest zmienny).
Może spróbuj odwołać się do tej wewnętrznej zmiennej?
Jest też polecenie INKEY, które odczytuje dane z tego bufora, w manualu jest (dla mnie niejasna) wzmianka o czytaniu danych nie będących znakami:
'When you need to receive binary data and the bibary value 0 ,
'you can use the IScharwaiting() function.
'This will return 1 when there is a char waiting and 0 if there is no char waiting.
'You can get the char with inkey or waitkey then.
Pozdrawiam,
TD
EDIT: Jeszcze jedno, sprawdź pole "bytematch" przy konfiguracji UART-u instrukcją SERIALIN. Musisz użyć specjalnych nazw podprogramów aby to polecenie prawidłowo interpretowało zdarzenia.
" The ASCII value of the byte that will result in calling a user label.
When you specify ALL, the user label will be called for every byte that is received. You must include the label yourself in your code and end it with a return. The following label names must be used when you check for a specific byte value:
• Serial0CharMatch (for SERIALIN or the first UART/UART0)
• Serial1CharMatch (for SERIALIN1 or the second UART/UART1)
• Serial2CharMatch (for SERIALIN2 or the third UART/UART2)
• Serial3CharMatch (for SERIALIN3 or the fourth UART/UART3)
The following label names must be used when you check for any value:
• Serial0ByteReceived (for SERIALIN or the first UART/UART0)
• Serial1ByteReceived (for SERIALIN1 or the second UART/UART1)
• Serial2ByteReceived (for SERIALIN2 or the third UART/UART2)
• Serial3ByteReceived (for SERIALIN3 or the fourth UART/UART3)
When you specify NONE, it is the same as not specifying this optional parameter."
EDIT2: ok, widzę że u Ciebie procedura, którą obsługuje SERIALIN jest nazwana poprawnie.
EDIT3: (bo najlepsze pomysły przychodzą kiedy jest się w wannie)
Bascom obsługuje bufor portu szeregowego programowo, każda przychodząca dana jest porównywana z "bytematch" oraz, jeśli nie jest zgodna to jest dodawana do wielobajtowej zmiennej będącej buforem. W przeciwnym wypadku wywoływany jest odpowiedni podprogram itp.
Skoro BACOM "ma czas" aby wykonać wszystkie te czynności, to dlaczego nie zrobić tego samemu? Zrezygnować z bufora wejściowego, czytać rejestr UDR po wystąpieniu przerwania URXC, porównać go ze wzorcem początku / końca ramki i jeśli nie jest zgodny to dodać do naszej wielobajtowej zmiennej. Wydaje się to prostszym i pewniejszym rozwiązaniem, bo będzie "szyte na miarę" dla naszych potrzeb.