Zapisywanie danych pobranych z komputera za pomocą RS232

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Awatar użytkownika
karlos79
-
Posty: 23
Rejestracja: 14 lip 2005, 22:16
Lokalizacja: z nienacka

Zapisywanie danych pobranych z komputera za pomocą RS232

Post autor: karlos79 » 30 sty 2008, 23:23

Witam
Mam problem z zapisaniem większej ilości danych pobranych z komputera do mikrokontrolera.
Chcę, żeby mikrokontroler pobierał instrukcje i zapisywał je do pamięci.
Później ma je wykonywać w innym podprogramie.
Jak zapisać dane wysłane z komputera, do jakiejś tabeli i później się do nich dobrać?
Oczywiście próbuję to zrobić w bascomie a mikrokontroler to ATMEGA8.
Transmisja mikrokontrolera i komputera działa poprawnie.
Pozdrawiam

Awatar użytkownika
gwozdex
Użytkownik
Posty: 879
Rejestracja: 24 lut 2006, 10:04
Lokalizacja: Czechowice-Dziedzice
Kontakt:

Post autor: gwozdex » 31 sty 2008, 12:54

Jeżeli tracisz niektóre bajty to może to świadczyć o zbyt szybkim wysyłaniu danych przez komputer. Jeśli to możliwe to wprowadź opóźnienie między wysłaniem kolejnych bajtów (np. w Delphi ja użyłem polecenia Sleep(X); X- w milisekundach)

Awatar użytkownika
karlos79
-
Posty: 23
Rejestracja: 14 lip 2005, 22:16
Lokalizacja: z nienacka

Post autor: karlos79 » 31 sty 2008, 14:55

Witam
Nie tracę żadnych bajtów.
Wszystko co wyślę z komputera do kontrolera zostaje zapisane w zmiennej i zwrócone z powrotem do komputera.
Mam problem ze zgromadzeniem danych w tablicy i późniejszym ich odczytaniem.
Każda dana ma być zapisana pod innym indeksem w tabeli, który automatycznie się powinien inkrementować po zapisaniu bajtu do tablicy.
Pozdrawiam

ZbeeGin

Post autor: ZbeeGin » 31 sty 2008, 17:55

karlos79 pisze:Mam problem ze zgromadzeniem danych w tablicy i późniejszym ich odczytaniem.
Każda dana ma być zapisana pod innym indeksem w tabeli, który automatycznie się powinien inkrementować po zapisaniu bajtu do tablicy.
Przecież to bardzo proste:

Dim Tablica(10) As String*2

Utworzy tablicę 10 ciągów tekstowych o długości 2 znaki. Z tym, że ciąg znaków w BASCOM kończy się tak samo jak w C przez znak o kodzie 0, zatem możesz tam zapisać w sumie jeden znak.
Dostęp do tablicy też jest bardzo prosty. Robi się to tak samo jak dla zwykłych zmiennych, z tym, że trzeba podać indeks:

Print Tablica(2)

Wydrukuje zawartość tablicy z drugiej jej komórki.

Czytanie i drukowanie danych w pętli? Żaden problem:

Kod: Zaznacz cały

Dim i As Byte
Dim Tablica(20) As String * 3

For i = 1 To 10
   Print "Czekam na dane. 10 ciągów dwuznakowych..."  
   Input Tablica(i)
Next

Print "Pokaże co odczytałem: ";
For i = 1 To 10
  Print Tablica(i); "-";
Next
Print : Print "Koniec."
Dalsze info: czytaj helpa.

(ps. Był błąd w innym miejscu. Poprawiłem)
Ostatnio zmieniony 31 sty 2008, 23:15 przez ZbeeGin, łącznie zmieniany 2 razy.

Awatar użytkownika
karlos79
-
Posty: 23
Rejestracja: 14 lip 2005, 22:16
Lokalizacja: z nienacka

Post autor: karlos79 » 31 sty 2008, 21:26

Witam
Już przetestowałem Twoją procedurkę.
Tutaj jest łąd

Kod: Zaznacz cały

Dim Tablica(20) As String * 3
Powinno być

Kod: Zaznacz cały

Dim Tablica(10) As String * 3
Ogólnie to działa :)
Jak teraz zrobić by dane odczytane z tablicy wyświetlane były w kolejnych liniach terminala?
Jak przejść do odczytu wtedy kiedy I nie osiągnie wartości 10, czyli jak przewać pętlę for...next, wtedy kiedy przestanę zapisywać dane do tablicy nie wypełniając jej (exit for- ale jak to zastosowac?)?
Powiem jeszcze, że kombinowałem z taką tablicą, tylko index inkrementowałem poprzez

Kod: Zaznacz cały

incr index
Cała procedura była umieszczona w pętli Do...Loop.
Ograniczenie inkrementacji indeksu było zrobione za pomocą instrukcji warunkowej if..then
Jednak to po prostu nie działało.
Jeszcze raz dziękuję bardzo za pomoc i za poświęcony czas
Pozdrawiam

ZbeeGin

Post autor: ZbeeGin » 31 sty 2008, 22:54

Uwaga! Nastąpiła zmiana treści posta.
karlos79 pisze:Tutaj jest łąd
Nie koniecznie. Nikt nie wymaga byś wykorzystywał całą tablicę. Program miał pobrać tylko 10 elementów, a potem je wyświetlić. Co zresztą przecież robi.
karlos79 pisze:Jak teraz zrobić by dane odczytane z tablicy wyświetlane były w kolejnych liniach terminala?
Po prostu instrukcję PRINT nie zakańczasz żadnym ze znaków specjalnych:
";" - nie wysyłaj znaku przejścia do następnej linii przed następnym parametrem/na końcu danych
"," - wysyłaj znak tabulatora przed następnym parametrem/na końcu danych
Zatem samo PRINT "ALA" wydrukuje słowo ALA, a kursor przejdzie do następnej linii. Stąd w programie konstrukcja:

Kod: Zaznacz cały

Print : Print "Koniec."
karlos79 pisze:Jak przejść do odczytu wtedy kiedy I nie osiągnie wartości 10, czyli jak przewać pętlę for...next, wtedy kiedy przestanę zapisywać dane do tablicy nie wypełniając jej (exit for- ale jak to zastosowac?)?
Zanczy się, chcesz przerwań pętlę, gdzie występuje instrukcja INPUT? Jeśli tak to trzeba skorzystać z dyrektywy $TIMEOUT która ustala "czas" po jakim INPUT zostanie warunkowo zakończony bez dalszego czekania na znak CR (ASCII 13 - ENTER). Wtedy musisz w jakiś sposób kontrolować poprawność otrzymanych danych i wyjść z pętli przez EXIT FOR (dla FOR..NEXT), EXIT DO (DO...LOOP), itd; jeśli ciąg był pusty lub niepełny.
Na przykład rozkazy tekstowe są zawsze wysyłane w jednym formacie: #AT_R (reset), #AT_S (set), #AT_T (start). Jeśli nie wpiszesz nic to INPUT zwróci pusty ciąg "" zatem wystarczy porównać przez IF czy ciąg jest pusty i EXIT.
Ale może się zdarzyć, że wpiszesz #A a potem zrezygnujesz, zatem program powinien wychwycić, że: komenda jest niepełna bo nie zgadza się ze wzorcem #AT_<kod>; albo że: ciąg jest zbyt krótki by był poprawny - funkcja LEN() zwraca mniej niż 4 (długość ciągu w znakach). I znów prosty IF i EXIT.

Awatar użytkownika
karlos79
-
Posty: 23
Rejestracja: 14 lip 2005, 22:16
Lokalizacja: z nienacka

Post autor: karlos79 » 02 lut 2008, 18:23

Witam
Dziękuję bardzo za pomoc :)
Procedurę już prawie napisałem i działa coraz lepiej.
Tematu jeszcze nie zamykam, bo pewnie pojawia się jakieś problemy.
Pozdrawiam

Awatar użytkownika
olatao
-
Posty: 29
Rejestracja: 20 lip 2006, 16:28
Lokalizacja: Bielsko-Biała

Post autor: olatao » 16 maja 2008, 16:52

Testuje RS232 dla przesyłania danych, które są umieszczane w buforze. Program działa na M8 jednak dla M16 już nie... Czy należy odblokować jeszcze dodatkowe jakieś przerwanie w M16? Dla M16 podczas symulacji zmienna ZNAK wypełnia się samymi "yyyyyyyyyyyy"

Kod: Zaznacz cały

$sim
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 9600

Config Serialin = Buffered , Size = 50
Dim Znak As String * 1
Dim Poz As Byte
Enable Interrupts

Cls
Poz = 1

Do

Znak = Inkey()
If Asc(znak) > 31 Then
   If Poz = 17 Then
      Cls
      Poz = 1
   End If
   Lcd Znak
   Incr Poz
End If

Wait 1

Loop
End

ODPOWIEDZ