logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

UART/BASCOM - pierwszy program

arktik1 14 Lut 2011 13:29 8184 36
REKLAMA
  • #1 9150010
    arktik1
    Poziom 27  
    Witam.
    Chciał bym zacząć od tego, że nigdy nie stosowałem UARTa w żadnym swoim projekcie.
    No i przyszedł moment że trzeba by połączyć ze sobą 2 Uc które mogły by ze sobą "rozmawiać".
    Z założenia komunikacja miała być bardzo krótka(zajmować mało miejsca), ponieważ występują ograniczenia spowodowane pojemnością FLASCH.
    "Stworzyłem" 2 programy, wysyłanie:
    
    $regfile = "m8def.dat"
    
    $crystal = 2000000
    $baud = 115200
    
    Config Portb = Input
            Portb = &B11111111
    
    
    Do
    If Pinb.0 = 0 Then Print "1"
    If Pinb.1 = 0 Then Print "2"
    If Pinb.2 = 0 Then Print "3"
     If Pinb.3 = 0 Then Print "4"
    If Pinb.4 = 0 Then Print "X"
    
    Loop
    
    

    i Odbieranie"
    
    $regfile = "m16def.dat"
    $crystal = 2000000
    $baud = 115200
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
    Dim Uart As Word
    
    Cls
    Do
    
      Uart = Inkey()
    
     If Uart > 0 Then
    
    If Chr(uart) = "1" Then
    Locate 2 , 1
    Lcd "Bieg 1"
     End If
     If Chr(uart) = "2" Then
    Locate 2 , 1
    Lcd "Bieg 2"
     End If
     If Chr(uart) = "3" Then
    Locate 2 , 1
    Lcd "Bieg 3"
     End If
    End If
    
    Loop
    End
    

    Programy, jeśli tak to można nazwać działają w symulatorze, ale tylko wtedy, gdy ich prędkość jest identyczna.
    Chciał bym, by można było ustawić różne prędkości oscylatorów i nie kolidowało by to z przesyłaniem danych.
    Nie wspomnę już ,że super by było przesyłać całe ciągi znaków a nie tylko jeden.
  • REKLAMA
  • #2 9150056
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #3 9150070
    mirekk36
    Poziom 42  
    Nie rozumiem za bardzo co masz na myśli żeby programy działały przy różnej prędkości ;) ? ..... toż ideą działania RS232 jest to że dawa urządzenia, które ze sobą "gadają" po RS232 MUSZĄ !!! mieć ustawioną taką samą prędkość ;) - nie ma że boli - tego nie przeskoczysz.

    Przy różnym taktowaniu za to możesz spokojnie ustawiać różne prędkości ale tylko takie przy których procent błędów transmisji jest mniejszy niż 2%. W tym celu przejrzyj sobie tabelki na ostatniej stronie rozdziału USART dowolnego procka AVR to sam zobaczysz o co chodzi i jak się dobiera prędkości do danej częstotliwości taktowania procka. Zauważ że np kwarce: 11,0592MHz, czy np 18,432MHz i jeszcze kilka innych określane są mianem "przyjaznych dla RS232" bo dla każdej prędkości RS232 dają 0% błędów ;)

    Co do procedur nadawczo odbiorczych i żeby przesyłać i odbierać ciągi znaków - no to już temat rzeczka jeśli nie rzeka. To trzeba powoli poćwiczyć i popatrzeć na różne rozwiązania. Ale przede wszystkim w Bascomie zainteresuj się poleceniem:

    Config Serialin oraz Bytematch

    i poczytaj sobie o tym tu i tam w necie. Albo przejdź na język C ;) będzie wtedy o wiele łatwiej ;)

    Co nie znaczy że i w bascomie nie da rady tego zrobić, chodzi mi tylko, że jak już się dużo nowych rzeczy uczyć to może warto w końcu w nowym języczku ;) .... a akurat te zagadnienia/podstawy masz bardzo dobrze omówione w pewnej książce.
  • #4 9150315
    arktik1
    Poziom 27  
    Rozumiem.
    1.Konieczna równa prędkość oscylatorów.
    Chciał bym teraz odebrać coś więcej niż:


    Np:
    
    Print "ciekaweczydziala"
    

    I po odebraniu, wpisaniu warunku:
    
    If Chr(uart) = "ciekaweczydziala" Then 
    ....
    .....
    endif
    

    Żeby działało.
  • #5 9150358
    Konto nie istnieje
    Poziom 1  
  • #6 9150538
    arktik1
    Poziom 27  
    Napisałem coś takiego:
    
    $regfile = "m16def.dat"
    Config Portb = Output
    Portb = &B00000000
    $crystal = 16000000
    $baud = 9600
    
    Config Serialin = Buffered , Size = 20
    
    Dim Uart As String * 10
    
    Enable Interrupts
    
    Do
    
       Uart = Inkey()
    
       If Err = 0 Then
       If Uart = "12345" Then
       Portb.0 = 1
       End If
       If Uart = "1" Then
       Portb.0 = 0
        End If
    End If
    
    
    Loop
    

    Ale nadal nie działa na ciąg znaków.
    Jedno się poprawiło, przynajmniej ich nie gubi :D
  • #8 9151746
    Fredy
    Poziom 27  
    Jeśli piszesz tak:

    Uart = Inkey()

    to odbierasz jeden znak z UARTA.

    Nie możesz potem porównywać ten jeden znak z ciągiem kilku znaków typu "12345"


    Musisz odbierać znaki pojedyńczo i dodawać je , dopiero jak odbierzesz np 5 znaków to wtedy porównywać ale już nie znaki lecz stringi.

    Zadeklaruj sobie zmienną typu String np 10 elementową.

    A potem wyzeruj ją .

    Następnie robisz tak : String=string +UART

    Dopiero po tym możesz porównać ten string np z "12345".
  • #9 9152195
    arktik1
    Poziom 27  
    Wygląda na to że zaczyna działać:
    
    $regfile = "m16def.dat"
    $crystal = 8000000
    $baud = 115200
    
    Config Serialin = Buffered , Size = 10
    
    Dim Uart As String * 10 , Napis As String * 10
    Enable Interrupts
    Cls
    Do
    
       Uart = Inkey()
    
       If Err = 0 Then
         Napis = Napis + Uart
           End If
    
    If Napis = "123" Then
    Cls
    Locate 1 , 1
    Lcd "123"
    End If
    
    If Napis = "12" Then
    Cls
    Locate 1 , 1
    Lcd "12"
    End If
    
    
    
    Loop
    

    Tylko jak teraz wyzerować NAPIS by po każdym ciągu znaków zaczynał od początku a nie dodawał dalej.
  • #11 9152449
    arktik1
    Poziom 27  
    Nie mam pojęcia gdzie to dopisać
  • REKLAMA
  • #14 9154285
    arktik1
    Poziom 27  
    Zmodyfikowałem trochę kod ,dodając zmienną kasującą NAPIS gdy zostanie wysłany ciąg znaków nieodpowiadający któremuś z warunków.
    
    Dim Uart As String * 10 , Napis As String * 10 , Kas As Integer
    Enable Interrupts
    Cls
    Do
    
       Uart = Inkey()
    
       If Err = 0 Then
        Napis = Napis + Uart
        Print Napis
        Incr Kas
          If Kas = 100 Then
        Napis = ""
        Kas = 0
        End If
          End If
    
    If Napis = "1234" Then
    Cls
    Locate 1 , 1
    Lcd Napis
    Napis = ""
    End If
    Loop
    

    Czy ma to szansę działania?
  • #15 9178180
    arktik1
    Poziom 27  
    Mam jeszcze jedno pytanie.
    Dlaczego powyższe programy nie działają na realnym LCD.
    W symulatorach działają a jeśli przyjdzie do wyświetlenia znaków na "żywym" LCD, to nic nie ma lub są jakieś krzaki?
  • #17 9179466
    arktik1
    Poziom 27  
    Jest taki sobie programik:
    
    
    $regfile = "m16def.dat"
    $crystal = 16000000
    $baud = 9600
    
    Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0
    Config Lcd = 20 * 4
    
    Config Serialin = Buffered , Size = 10
    
    Enable Interrupts
    
    Declare Sub Kas_bufor
    
    Dim Uart As String * 1
    Dim Buf As Word
    Dim Dane As String * 10
    
    
    Cls
    Locate 1 , 1
    Lcd "Test"
    
    Dane = ""
    
    Do
    
      Buf = Ischarwaiting()
      If Buf = 1 Then
       Waitms 10
       Gosub Odczyt_uart
       'Print "123"
       Cls
       Locate 1 , 1
       Lcd Dane
    
       Gosub Kas_bufor
       End If
    
    Loop
    
    
    
    
    Odczyt_uart:
    
    Dane = ""
    
    Do
     Uart = Inkey()
     Dane = Dane + Chr(uart)
    Buf = Ischarwaiting()
    Loop Until Buf = 0 Or Uart = "13"
    Return
    
    
    Kas_bufor:
    Do
       Uart = Inkey()
       Buf = Ischarwaiting()
    Loop Until Buf = 0
    Return
    

    Po wysłaniu czegokolwiek z terminala na LCD pojawiają się jakieś znaki, nigdy to co wysyłam.
  • REKLAMA
  • #18 9180338
    xury
    Specjalista automatyka domowa
    Przykład odbioru z sms.bas
    b - zmienna typu Byte

    Sub Getline(s As String)
      S = ""
      Do
        B = Inkey()
        Select Case B
           Case 0                                               'zamiast ischarwaiting
           Case 13                                              'filtracja znaku CR
           Case 10 : If S <> "" Then Exit Do                    'filtracja LF i zakończenie
           Case Else
             S = S + Chr(b)                                     'budowanie ciagu
        End Select
      Loop
    End Sub

    Chociaż osobiście używam odczytu w przerwaniu. Przy pomocy buforowania z bytematch. Info w helpie.
  • #19 9181577
    arktik1
    Poziom 27  
    Gdzie mogę znaleźć dane o:
    baudrate, bity parzystości kontrola przepływu?
  • #21 9181976
    arktik1
    Poziom 27  
    W programie jest tak:
    
    $regfile = "m16def.dat"
    $crystal = 16000000
    $baud = 9600
    

    w terminalu tak:
    UART/BASCOM - pierwszy program
    w BASCOM tak:
    UART/BASCOM - pierwszy program
    .
    Jeśli w przejściówce połączę TXDz RXD wszystkie znaki wracają.
    Jeśli podłącze to do Uc to są "krzaki" na LCD i w terminalu.
    Nie wiem o co chodzi.
  • #23 9182568
    arktik1
    Poziom 27  
    oto fusy:
    UART/BASCOM - pierwszy program
    UART/BASCOM - pierwszy program
    Mam tam BOOTLOADER i normalnie działa.
    Problem jest z wysyłaniem znaków.

    Dodano po 3 [godziny] 21 [minuty]:

    Chyba zaczyna mnie to wkurzać, 3 komputery( laptopXP/LaptopW7/ PC XP)
    Prawidłowe konfiguracje i NADAL NIE DZIAŁA.
    Instalowane różne terminale, cały czas odbiera nie to co powinien.
    Może trzeba "wymusić" jakiś port COM np 2,3,4 a nie 44?
    Może to wina Przejściówki, a może to BASCOM nie nadaje się do takich rzeczy?
    A może ma ktoś jakiś prosty programik w C, który wyświetli mi dane na LCD?
  • #25 9184850
    arktik1
    Poziom 27  
    Na pewno nic się nie znajdzie?:D
  • #27 9186274
    arktik1
    Poziom 27  
    Próba:
    Atmega 16, Atmega8, wewnętrzne i zewnętrzne rezonatory-Nie działa.
    Dziwne jest to że mogę załadować program przez BOOTLOADER i działa.
    Pokombinuje jeszcze z ustawieniami terminala, zobaczymy co będzie.
    Na obydwu Uc, przy tych samych prędkościach pojawiają się identyczne znaczki.
    Jeśli chcę wysłać z terminala sam CR to na LCD widać XF.
    Jeśli jakąś literę lub cyfrę to "krzaki" i XF.
    Zmienia się to tylko wtedy gdy przestawię oscylator, wtedy na końcu nie widać np XF tylko "kszak" h.
    Tak samo jest gdy znaki są zwracane do terminala.
  • #28 9187688
    maximus22_kr
    Poziom 18  
    u mnie również działa ten kod
    
    Odczyt_rs:
      E = ""
    
      Do
        F = Inkey()
        Select Case F
           Case 0                                               'nic
           Case 13 : If E <> "" Then Exit Do                    ' jeśli coś odebrane
           Case Else
            E = E + Chr(f)                                      ' utwórz ciąg
        End Select
    
      Loop
    
    Return 
    


    po wpisaniu stringu pasującego do jednego z określonych wcześniej warunków następuję działanie.

    Problem jest tylko jeśli warunek jest częściowo zmienny, np.
    pow1:100
    pow1:125
    pow1:180

    Zgodnie z sugestia Kolegi Xury testuję funkcje Val i Str,

    wpisanie stringu na "sztywno" wykonuje poprawnie funkcje
    
    Dim D1 As String * 8
    Dim D2 As String * 8
    Dim G as Byte
    
    D1 = "pwm1:050"
    D2 = Mid(d1 , 6 , 3)       ' wyciągnięcie liczby 050
    
    G = Val(d2)                  ' usunięcie 0 
    


    Gorzej z współpracą z ciągiem otrzymywanym z terminala, wstawiłem sobie wyświetlanie zmiennych na LCD i zawsze jest 0.
    Link
  • #29 9188304
    arktik1
    Poziom 27  
    Napisałeś:
    "Gorzej z współpracą z ciągiem otrzymywanym z terminala"
    U mnie nawet nie odbiera pojedyńczego znaku, a co dopiero ciąg znaków.
  • #30 9188817
    maximus22_kr
    Poziom 18  
    taki objaw, jak piszesz, że dochodzą inne znaki, a nie te co wysłałeś świadczy o niedopasowaniu prędkości, miałem tak, gdy w uC ustawiłem 9600, a w komputerze np. 19200 lub 4800. Przychodziły jakieś śmieci, dopiero ustawienie identycznych prędkości spowodowało, że komputer odbierał to co trzeba
REKLAMA