Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[8051] [Keil] - odbiór danych z rs232 i ich użycie [Proteus]

Erisen 25 Sie 2014 21:48 1836 7
  • #1 25 Sie 2014 21:48
    Erisen
    Poziom 5  

    Witam Państwa,
    Projektuję układ do sterowania silniczkiem w Proteusie. Wcześniej udało mi się sterować nim przez klawiaturę podłączoną do układu. Teraz natomiast chciałbym odbierać sygnał przez port rs232. Program do nadawania jest napisany w C# i działa prawidłowo, jednak na terminalu w Proteusie np. przy wysłaniu E7 dostaję znak "ç", Przy wysłaniu 61 na terminalu pojawia się "a", 62 = "b" itd.
    Komunikacja jest, ale widnieje problem z jej prawidłowym odbiorem. Z góry przepraszam za podstawowe błędy, ale jestem bardzo początkującym programistą.

    Kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    #include <REGX52.H>
    #include <stdio.h>

    volatile unsigned int UP;
    volatile unsigned char data Kod;
    volatile unsigned int data index;
    volatile unsigned int data index2;

    void Read_Serial (void) interrupt 4 //procedura obsługi przerwań portu szeregowego
    {
    while (RI != 1) {;}
    Kod = SBUF;
    RI = 0;
    }

    void Timer1_IRQ(void) interrupt 3 //obsługa silniczka
    {
    index++;
    if (index %4 == 0) {index2++;}
    if (index2 == UP) {EN1 = 1; P0_1 = 0; P0_2 = 0; index2 = 0; index = 0;}
    if (index == 254) {index = 0;}
    }

    void main (void)
    {
    EN1 = 1;
    //Konfiguracja seriala
    SCON = 0x50; // mode 1, 8-bit uart, enable receiver
    TMOD = 0x20; // timer 1, mode 2, 8-bit reload
    TH1 = 0XFD; // 9600 baud rate
    TL1 = 0XE6;
    TR1 = 1;
    SBUF = 0;
    UP = 0; //odpowiada za czas kręcenia silnika

    while (1)
    {
    if (Kod == 0xE7) {P0_1 = 1; P0_2 = 0; UP = 254;} //kręci silnikiem w lewo
    if (Kod == 0xEB) {P0_1 = 0; P0_2 = 1; UP = 254;} //kręci silnikiem w prawo
    if (Kod == 0xED) {P0_1 = 1; P0_2 = 1;} //zatrzymanie silnika
    if (Kod == "a") {P0_1 = 1; P0_2 = 0; UP = 100;} //kręci silnikiem w lewo
    if (Kod == 'a') {P0_1 = 0; P0_2 = 1; UP = 100;} //kręci silnikiem w prawo
    }
    }
    [/syntax]

    Schemat:

    [8051] [Keil] - odbiór danych z rs232 i ich użycie [Proteus] [8051] [Keil] - odbiór danych z rs232 i ich użycie [Proteus]

    Coś robię nie tak. Zapewne jest to problem z wykorzystaniem rejestru SBUF. Może ktoś z Państwa potrafi dostrzec błąd. Keil nic nie dostrzega.

    0 7
  • Pomocny post
    #2 26 Sie 2014 11:48
    BlueDraco
    Specjalista - Mikrokontrolery

    W kodzie jest mnóstwo błędów, ale to, co Ty uważasz za błąd akurat błędem nie jest.

    Zacznijmy od tego, że prawdopodobnie masz ciągle zgłoszone i nieobsługiwane przerwanie nadajnika, bo zupełnie nie wiadomo po co kazałeś UARTowi wysłać 0.

    Timer generujący szybkość transmisji jest źle zaprogramowany - pierwszy okres będzie inny, niż następne, a te następne mają długość zapisaną w TH1.

    Instrukcja
    if (Kod == "a")
    oznacza "jeśli wartość 8-bitowej zmiennej Kod jest równa mniej znaczącemu bajtowi łańcucha tekstowego".

    Kod szesnastkowy 0x61 odpowiada literze a, a 0x62 - b. Prawdopodobnie to właśnie obserwujesz i wydaja Ci się, że coś jest nie w porządku.

    Zamiast sekwencji if() użyj instrukcji switch().

    0
  • #3 26 Sie 2014 18:30
    Erisen
    Poziom 5  

    Dziękuję za odpowiedź.

    Cytat:
    Zacznijmy od tego, że prawdopodobnie masz ciągle zgłoszone i nieobsługiwane przerwanie nadajnika, bo zupełnie nie wiadomo po co kazałeś UARTowi wysłać 0.

    Chodzi o przypisanie wartości 0 do SBUF'a?

    Cytat:
    Timer generujący szybkość transmisji jest źle zaprogramowany - pierwszy okres będzie inny, niż następne, a te następne mają długość zapisaną w TH1.

    Jak poprawnie zaprogramować timer?
    Aby uzyskać 9600 baud rate z oscylatorem 11.0592MHz, dzielone przez 12 i 16 wychodzi 57600. 57600/9600 = 6
    TH1 będzie 0xFA?

    Cytat:
    Instrukcja
    if (Kod == "a")
    oznacza "jeśli wartość 8-bitowej zmiennej Kod jest równa mniej znaczącemu bajtowi łańcucha tekstowego".

    Czyli zrobić to po kodzie szesnastkowym z użyciem switch'a:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #4 26 Sie 2014 19:33
    BlueDraco
    Specjalista - Mikrokontrolery

    Kompilatorowi wszystko jedno, czy napiszesz case 0x61:, czy case 'a':, za to człowiekowi nie jest wszystko jedno, kiedy czyta taki program, więc pisz case 'a':, case 'b':.

    TH1 i TL1 powinny mieć tę samą wartość początkową: 256 - FCLK / 12 / 16 / BAUD.

    0
  • #5 27 Sie 2014 11:06
    Erisen
    Poziom 5  

    Dziękuję za odpowiedź.

    Więc na dzień dzisiejszy kod wygląda następująco:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kompilator nie wykrywa żadnych błędów.
    Mikrokontroler nadal nie obsługuje poleceń z portu szeregowego.
    Czy RxD z COMPIM nie powinien iść do TxD mikrokontrolera?
    Zaznaczam, że komunikuje ze sobą programy wirtualnym portem szeregowym na standardowych ustawieniach (bez krosowania).

    Bardzo dziękuję za jakiekolwiek odpowiedzi.

    0
  • #6 27 Sie 2014 13:45
    BlueDraco
    Specjalista - Mikrokontrolery

    Czy masz konwerter poziomów, np. MAX232? Na porcie RS232 masz napięcia rzędu 9 V - mikrokontroler nie steruje bezpośrednio RS232 - po drodze potrzebny jest transceiver.
    No i oczywiście łączymy linie RXD transceivera z TXD interfejsu w komputerze i odpowiednio TXD z RXD.

    0
  • #7 27 Sie 2014 17:04
    Erisen
    Poziom 5  

    Dziękuję za odpowiedź.

    Cytat:
    Czy masz konwerter poziomów, np. MAX232? Na porcie RS232 masz napięcia rzędu 9 V - mikrokontroler nie steruje bezpośrednio RS232 - po drodze potrzebny jest transceiver.

    Może ktoś mnie wprowadził w błąd, ale podobno MAX232 w Proteusie w symulacji jest zbędny.
    Mimo wszystko dołączyłem go.
    [8051] [Keil] - odbiór danych z rs232 i ich użycie [Proteus]

    Mikrokontroler nadal nie odpowiada. Na virtual terminal 'a' dostaje tym razem po wysłaniu 3D, nie 61.

    0
  • #8 28 Sie 2014 19:10
    Erisen
    Poziom 5  

    Rozwiązałem sprawę. Temat można zamknąć. Dzięki BlueDraco za wszelkie podpowiedzi. Pozdrawiam

    0