[bascom] Komunikacja pomiędzy kilkoma mikrokontrolerami

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!
LemuRR 11
-
Posty: 9
Rejestracja: 11 wrz 2011, 12:15
Lokalizacja: Kraków
Kontakt:

[bascom] Komunikacja pomiędzy kilkoma mikrokontrolerami

Post autor: LemuRR 11 » 11 wrz 2011, 12:59

Witam, w moim projekcie chce wykorzystać komunikację po rs232 + konwerter na rs485
Jednak zanim napiszę główny program, to poproszę o sprawdzenie przykładowego, master ma za zadanie wysyłać 2 zmienne do 2 slave`ów jedna zmienna to adres, a dróga to ta właściwa
Master

Kod: Zaznacz cały

$regfile = "attiny2313.dat" 
$crystal = 4000000 

   Config Serialin = Buffered , Size = 15 

Const A = 3 'stała adresu slave 
Const A2 = 5 ' stała adresu slave2 

Dim B As Byte 'zmienna licznika 
B = 0 
Do 'początek pętli 
B = B + 1 

 Print A ; B 'wyślij adres slave i zmienną licznika 
Waitms 100 
B = B + 1 
 Waitms 100 
Print A2 ; B `wyślij adres slave2 i zmienną 
If B = 50 Then 
B = 0 
End If 

 Loop ' koniec pętli
Slave1

Kod: Zaznacz cały

$regfile = "m16def.dat" 
$crystal = 4000000 
 $sim 
   Config Serialin = Buffered , Size = 15 
    Config Lcd = 16 * 2 
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5 

Dim Ad As Byte 'zmienna przechowująca adres 
Dim B As Byte  ' zmienna do wyświetlenia 
Ad = 0 
B = 0 

Do 


input A , B  ' odebranie zmiennej adresu i licznika
If Ad = 5 Then ' jeżeli zmienna adresowa to 5 to 
Cls ' czyść lcd 
 Lcd "odebrano" ; B ' wyświetl na lcd tą zmienną 
  End If 


  Loop
Slave2

Kod: Zaznacz cały

$regfile = "m16def.dat" 
$crystal = 4000000 
 $sim 
   Config Serialin = Buffered , Size = 15 
    Config Lcd = 16 * 2 
Config Lcdpin = Pin , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E = Portb.4 , Rs = Portb.5 

Dim Ad As Byte 'zmienna przechowująca adres 
Dim B As Byte  ' zmienna do wyświetlenia 
Ad = 0 
B = 0 

Do 


input A , B  ' odebranie zmiennej adresu i licznika
If Ad = 5 Then ' jeżeli zmienna adresowa to 5 to 
Cls ' czyść lcd 
 Lcd "odebrano" ; B ' wyświetl na lcd tą zmienną 
  End If 


  Loop

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 11 wrz 2011, 14:32

Źle to jest zrobione. Na pewno nie bezie to działać
Wszystkie trzy przykłady.
Mała wskazówka czytaj HELP i odpal ten program testowy:

Kod: Zaznacz cały

'-----------------------------------------------------------------------------------------

'name                     : rs232buffer.bas

'copyright                : (c) 1995-2005, MCS Electronics

'purpose                  : example shows the difference between normal and buffered

'                           serial INPUT

'micro                    : Mega161

'suited for demo          : yes

'commercial addon needed  : no

'-----------------------------------------------------------------------------------------

 

$regfile = "m161def.dat"                                   ' specify the used micro

$crystal = 4000000                                         ' used crystal frequency

$baud = 9600                                               ' 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 Na As String * 10

 

'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?

    Input Na     

     Print Na                                           '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

Jeśli dalej będziesz miał problemy to napisz.

LemuRR 11
-
Posty: 9
Rejestracja: 11 wrz 2011, 12:15
Lokalizacja: Kraków
Kontakt:

Post autor: LemuRR 11 » 11 wrz 2011, 16:35

No to teraz zrozumiałem, że nic nie rozumiem
Niby wydawało by się to proste, jeden nadajnik, dwa odbiorniki
W tym rzecz że podjąłem się zrobienia zegara na dach budynku
4 matryce żarówkowe 3x5, po dwie minuty i godziny. Dwiema Cyframi sterowała by jedna Mega16. Na dole główny układ zegarowy z PCF8583, który wysyła po kablu na dach dane. Opanowałem już sterowanie i2c PCF8583, ale nie mgę wymyślić sposobu przesłania na dach Wartości godzin i minut. Myślałem nawet już o RC5 bez fotodiody i fotoodbiornika, puszczonym po kablu antenowym, potem narodził się pomysł z RS485. Ale teraz to całkowicie zwątpiłem w swoje umiejętności..

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 11 wrz 2011, 17:02

No dobra ale czego w tym nie rozumiesz?
Proste jak drut robisz tablice na 4 zmienne, Adres, godziny, minuty,CRC .
czyli :
Nadajnik

Kod: Zaznacz cały

Dim Serial_tx(4) As Byte
' w nawiasie masz ile zmiennych 
'musisz skonfigurować bufor wyjściowy 
Config Serialout = Buffered , Size = 4  
Enable Interrupts
Enable Utxc
'włączyć przerwania
' i użyć print bin zamaist print 
Printbin Serial_tx(1) ; 4  ' w nawiasie podajesz od którego byte z tablicy ma zacząć wysyłanie
' a po tym czymś zapomniałem jak się to nazywa średnik czy jakoś ";" ile byte-ów z tablicy 
' tym oto sposobem masz całe wysyłanie załatwione 

 
Część odbiorcza

Kod: Zaznacz cały

'Najpierw zmienna
Dim Serial_rx(4) As Byte 
Dim Serial_flag as bit 
' potem konfiguracja buffora 
Config Serialin = Buffered , Size = 40' miejsce na 10 transmisji 
do 
Serial_flag = Ischarwaiting()
If Serial_flag = 1 Then
   Inputbin Serial_rx(1) , 4
  End If

loop 
end 
Mniej więcej tak
wszytko ma byc na timerach i przerwaniach żadnych wait-ów
Możesz olać to CRC i zrobić tablice na 3 byte-y albo użyć ale wtedy musisz dorobić obsługę tego CRC

LemuRR 11
-
Posty: 9
Rejestracja: 11 wrz 2011, 12:15
Lokalizacja: Kraków
Kontakt:

Post autor: LemuRR 11 » 11 wrz 2011, 19:34

Dzięki za przystępne wytłumaczenie, nie wiem jak mogę się odwdzięczyć.
O ile się nie mylę Ischarwaiting() zwraca wartość 1 kiedy w buforze odbiorczym znajduje się jakikolwiek znak ?
Jeszcze takie pytanie, być może niezbyt mądre, jeżeli chcę przypisać zmiennej z tablicy wartość to piszę np. Serial_tx(1)=1 (rozumiem że pierwszy bajt wtedy przyjmie wartość "1")
albo Serial_tx(2)=6 (to wtedy bajt drugi będzie miał wartość "2") I czy to samo się ma do odczytywania liczb z tablicy ?
" CRC ", to chodziło Ci o wykrywanie błędów w transmisji ?
I jeszcze raz serdecznie dziękuję, jutro postaram się napisać już właściwy program.
Miłej nocy życzę i pozdrawiam
Adam

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 11 wrz 2011, 21:06

O ile się nie mylę Ischarwaiting() zwraca wartość 1 kiedy w buforze odbiorczym znajduje się jakikolwiek znak ?
dokładnie tak

" CRC ", to chodziło Ci o wykrywanie błędów w transmisji ?
TAK
piszę np. Serial_tx(1)=1 (rozumiem że pierwszy bajt wtedy przyjmie wartość "1")
Tak
albo Serial_tx(2)=6 (to wtedy bajt drugi będzie miał wartość "2")

Nie będzie miał wartość 6
I czy to samo się ma do odczytywania liczb z tablicy ?
TAK

Dodatkowo zapamiętaj że odbiór ma wyglądać tak Inputbin Serial_rx(XX) , XXX
XX-numer byte-u od którego zaczynasz
XXX- ilość byte-ów
Co ważne w inputbin po nawiasie musi być przecinek

Nadawanie
ma wyglądać tak Printbin Serial_tx(XX) ; XXX
Printbin po nawiasie musi być myślnik czy jak to się tam nazywa
Przy wysyłaniu tablic możesz sprecyzować od którego byte-u zaczynasz wysyłanie,
i ile byte-ów chcesz wysłać
XX-to byte od którego chcesz wysyłać
XXX- to ile byteów chcesz wysłać

rezasurmar
Użytkownik
Posty: 626
Rejestracja: 19 kwie 2009, 15:59
Lokalizacja: Tychy
Kontakt:

Post autor: rezasurmar » 12 wrz 2011, 20:56

Panowie, za kolejne posty nie na temat, polecą ostrzeżenia.

keruseykaryu

Post autor: keruseykaryu » 12 wrz 2011, 20:57

LemuRR 11 pisze:PS. Zamiast Mega16 kupiłem AT89s52, porównując układy nie zauważyłem znaczących różnic, a cena megi16 to 23zł a AT89s52 4,50 zł. Nie jestem w stanie pojąć dlaczego jest taka ogromniasta różnica w cenie..
No niestety cofnąłeś się tym w czasie o ładnych parę lat. 89s52 to rodzina 8051 a mega16 to Avr. Nie zdziwiłbym się jakbyś w Bascom 8051 nie znalazł CONFIG SERIALIN i SERIALOUT, które by ci ułatwiły. Dajmy na to poprzez Bytematch...

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 12 wrz 2011, 21:25

Może by tak przykleić takie gotowce- wprowadzenia do najużyteczniejszych zagadnień jak np ta transmisja po rs232.
Mogę to jakoś bardziej rozpisać opisać. Żeby więcej nie powielać tematu na forum.
Co wy na to ?

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 12 wrz 2011, 21:36

Pikczu pisze:Mogę to jakoś bardziej rozpisać opisać. Żeby więcej nie powielać tematu na forum.
Co wy na to ?
Oooo. Pikczu, masz rację.

LemuRR 11
-
Posty: 9
Rejestracja: 11 wrz 2011, 12:15
Lokalizacja: Kraków
Kontakt:

Post autor: LemuRR 11 » 13 wrz 2011, 19:53

No i napisałem program :)
teraz proszę o sprawdzenie
P.S program (symulator) wyświetlał różne dziwne rzeczy na lcd

Kod: Zaznacz cały

$regfile = "m8def.dat"
$crystal = 4000000
$sim
Enable Interrupts
Enable Utxc
Config Serialout = Buffered , Size = 4
Config Sda = Portd.6
Config Scl = Portd.5
Config Lcd = 16 * 1
Config Lcdpin = Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
Config Pinb.0 = Input
Config Pinb.1 = Input
Config Pinb.2 = Input
Config Pind.7 = Input

Pinb.0 = 1
Pinb.1 = 1
Pinb.2 = 1
Pind.7 = 1

Plus Alias Pinb.1
Minus Alias Pinb.0
Ok Alias Pinb.2
Ustaw Alias Pind.7
Deflcdchar [1] , 32 , 14 , 19 , 21 , 21 , 14 , 32 , 21
Dim Czas(3) As Byte
Dim S As Byte
 Dim M As Byte
 Dim H As Byte
 Dim S1 As Byte
 Dim M1 As Byte
 Dim H1 As Byte
 S = 0
 M = 0
 H = 0
 S1 = 0
 M1 = 0
 H1 = 0
 Czas(1) = 0
 Czas(2) = 0
 Czas(3) = 0


 Display On

 Do

      If Ustaw = 0 Then
      Gosub Ustawianie
      End If

      I2cstart
      I2crbyte 162
      I2crbyte 2
      I2cstart
        I2crbyte 163
        I2crbyte Czas(1) , Ack
        I2crbyte Czas(2) , Ack
        I2crbyte Czas(3) , Nack
        I2cstop
        Gosub Zamien
        Gosub Wyswietl
         If Czas(1) = 0 Then
          Gosub Wyslijrtc
                        End If
                        Loop
          Ustawianie:
           S = 0
           M = 0
           H = 0
          Cls
                   Do
           If Plus = 0 Then
          H = H + 1
          Waitms 200
          Elseif Minus = 0 Then
          H = H - 1
          Waitms 200
          Elseif H > 24 Then
          H = 0
          Elseif Ok = 0 Then
          Exit Do
          End If
          Cls
           Lcd "ustaw godzine" " - " ; H
          Loop
          Do

          If Plus = 0 Then
          M = M + 1
          Waitms 200
          Elseif Minus = 0 Then
          M = M - 1
          Waitms 200
          Elseif M > 59 Then
          M = 0
          Elseif Ok = 0 Then
          Exit Do

          End If
          Cls
             Lcd "ustaw minuty" " - " ; M
             Loop
                         Do

          If Plus = 0 Then
          S = S + 1
          Waitms 200
          Elseif Minus = 0 Then
          S = S - 1
          Waitms 200
          Elseif S > 59 Then
          S = 0
          Elseif Ok = 0 Then
          Exit Do
          End If
          Cls
          Lcd "sekundy" " - " ; S


         Loop
          Return
          Wyswietl:
          Cls
          Lcd Chr(1) ; "  :" ; Czas(3) " : " ; Czas(2) ; " : " ; Czas(1)
          Return
          Zamien:
          Czas(1) = Makedec(czas(1))
          Czas(2) = Makedec(czas(2))
          Czas(3) = Makedec(czas(3))
          Return
          Wyslij:


Printbin Czas(1) ; 4

Return
                Wyslijrtc:
                H1 = Makebcd(h)
                M1 = Makebcd(m)
                S1 = Makebcd(s)
                I2cstart
                I2crbyte 162
                I2crbyte 2
                I2crbyte S1
                I2crbyte M1
                I2crbyte H1
                I2cstop
                Return

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 13 wrz 2011, 20:01

A czemu masz tam printbinczas(1);4 jak zmienna masz zdeklarowana tylko na 3 byte-owa tablice Dim Czas(3) As Byte??
Nie mam jak tego przetestować ale już patrząc wygląda źle. Te petle do loop nie mozesz tego zrobić w jednej petli zaraz stos się przeładuje i procek se zrestartuje.
:lol: Słowa otuchy :lol:
Ostatnio zmieniony 13 wrz 2011, 20:10 przez Pikczu, łącznie zmieniany 1 raz.

Awatar użytkownika
matrix
Użytkownik
Posty: 1796
Rejestracja: 15 mar 2006, 5:21
Lokalizacja: Sochaczew
Kontakt:

Post autor: matrix » 13 wrz 2011, 20:09

Czemu masz napisane:

Kod: Zaznacz cały

Config Lcdpin = Config Lcdpin = Pin
Ja zawsze piszę tak:

Kod: Zaznacz cały

Config Lcdpin = Pin

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 13 wrz 2011, 20:52

Tak mysle nad tym softem bo przetestować nie mam jak jak już tak bardzo chcesz zatrzymać te pętle do loop do daj chociaż loop untill i warunek spełniający.
Ale nie wiem jak wtedy ze stosem może niech się ktoś bardziej doświadczony wypowie bo moja wiedza o stosie jest mała.
Wiem ze na niektórych palili czarownice :lol:

LemuRR 11
-
Posty: 9
Rejestracja: 11 wrz 2011, 12:15
Lokalizacja: Kraków
Kontakt:

Post autor: LemuRR 11 » 14 wrz 2011, 5:08

Z tym błędem w lcd to już się uporałem, w procedurze wysyłania literówka.
Ale nie rozumiem dokładnie czego mógłbym użyć zamiast pętli do loop (chodzi tutaj o pętle w ustawianiu ?) Co miało by spowodować że mikrokontroler się zresetuje ? Przecież to nie jest wszystko w jednej pętli.

ODPOWIEDZ