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

USART, RS232, zaprogramowany procesor. Cały czas jest cisza.

07 Lut 2005 10:47 1407 8
  • Poziom 15  
    Stworzyłąem sobie urządznie które ma gadać z Pecetem za pośrednictewem RS 232. Napisałem prosty program, zaprogramowałem procka, ale cały czas jest cisza. Sparwdzałem połączenia, poziomy napięć na max 232 - wszytsko się zgadza. Wszystko wskazuje że musi byc coś nie tak z kodem programu.
    Jest jedna rzecz , która nie daje mi spokoju. Otóż jak symuluje sobie działanie programu w AVR STUDIO to przy konfiguracji procka , a dokładniej USART'a zachodzi dziwna rzecz. Wartość jaka wczesniej wpisuje do rejestru UCSRC jest kasowana w momencie wpisu do UBRRh. MAm procesor ATmega 162, i te dwa rejestru współdzielą ten sam adres, ale mozna je rozróżnic za pomocą nastarszego bitu - jesli jest 1 to zapsiujemy do UCSRC a jak 0 to do UBRRh. Mój kod w trakcie konfiguracji jest w zasadzie taki sam, jaki zawarty jest w aplikacji tego procka, która mówi o tym jak konfigurować USART'a. Teraz nie wiem, czy AVR Studio się myli i po prostu źle pokazuje zawartośc tych rejestrów, czy też popełniam jakiś błąd ?
    Mój kod wygląda tak:

    PORTA=0x00;
    DDRA=0x00;
    .......
    UCSR0A=0x00;
    UCSR0B=0x18;
    UCSR0C=0XB6;
    UBRR0H=0x00;
    UBRR0L=0x47;
    ..........
  • Poziom 28  
    Tak na oko wyglada ok. Mala rada tylko, do konfiguracji uzywaj takiego sposobu (asembler):
    ldi rTemp1,(1<<RXEN)|(1<<TXEN)|(1<<UCSZ2)
    out UCSRB,rTemp1
    Znacznie to ulatwia wychwytywanie bledow. Jedyne co mi przychodzi do glowy to "rozjechane" predkosci. Moze Atmega chodzi na wewnetrznym kwarcu 1MHz i dletego nici z pogaduszek z PC-tem.
    Pozdro
    Dexter
  • Poziom 10  
    ja mam taki problem że odpowiada mi śmieciami. tzn wysyłam z atmegi8 tekst Hello World. i otrzymuje na pc tekst ktory posiada za kazdym razem podobne smieci. np w miejscu gdzie powinno byc "ll" sa dwa takie same znaki podobnie jak w HW mam dwa 'o' to tez dostaje w tych miejscach takie same znaki. w dokumentacji pisze ze przy polaczeniu 9600 jest blad -7.0% nie wiem czy o to moze chodzic?. oscylator wewnetrzny 1Mhz
  • Poziom 28  
    Tak to chodzi o to. Nie bez powodu przy transmisjach asynchronicznych musi byc zgrany zegar obydwoch urzadzen. Dopuszczalny blad to 1% ale nie polecany. Ustaw bit U2X i wpisz odpowiednia wartosc do UBBRH i UBBRL wtedy blad wyniesie dopuszczalne 0,2%
    Pozdro
    Dexter
  • Poziom 10  
    Ok dzieki dziala :) Mozliwe ze program od strony pc ma byka jeszcze, ale poprawnie mi znaki przesyla i jest git :)
    Musze sprawdzic, czy nie przeoczylem czegos w dokumentacji jesli idzie o te procenty odchylen :>
  • Poziom 10  
    Heh UART zadzialal ale do czasu az wlaczylem inicjalizacje LCD.
    O co chodzi:
    Mam tak popodlaczana ATMege8:

    ; PIN NR - FUNCTION
    ; PORTB:
    ; Pin 7 - XTAL2
    ; Pin 6 - XTAL1
    ; Pin 5 - SCK
    ; Pin 4 - MISO
    ; Pin 3 - MOSI
    ; Pin 2 - LCD: RS
    ; Pin 1 - LCD: R/W
    ; Pin 0 - LCD: E
    ;
    ; PORTC:
    ; Pin 6 - RESET
    ; Pin 5 - 1-Wire
    ; Pin 4 - NC
    ; Pin 3 - NC
    ; Pin 2 - NC
    ; Pin 1 - LCD: LEDL
    ; Pin 0 - LCD: LEDR
    ;
    ; PORTD:
    ; Pin 7 - LCD: DB7
    ; Pin 6 - LCD: DB6
    ; Pin 5 - LCD: DB5
    ; Pin 4 - LCD: DB4
    ; Pin 3 - MORE (INT0)
    ; Pin 2 - LESS (INT1)
    ; Pin 1 - TXD
    ; Pin 0 - RXD

    jak widac obsluga LCD jest moze niefortunnie nieco rozdzielona na 2 porty
    ale inaczej i tak sie nie dalo jesli chcialem dac mozliwosc podlaczenia kwarcu zewnetrznego i wykorzystac UART, no chyba ze LCD R/W zwarlbym do masy...

    problem jest taki że po odkomentowaniu inicjalizacji LCD, UART nie działa, podczas gdy bz niej działa poprawnie.
    poniewaz fragment inicjalizacji moze wygladac np tak:
    in r16, LCD_DATA ; reading PORTD content (not PIND)
    andi r16, 0x0F ; masking non-data bits in r16
    ori r16, 0x30 ; "function set" command: 8 bit mode
    out LCD_DATA ; writing new data to PORTD

    czy moze taki manewr kolidowac z UARTem? gdyz TxD i RxD sa na PD0..1
  • Poziom 28  
    Dlaczego ustawiasz wyswietlacz w tryb 8bit skoro masz podlaczone tylko 4 bity ?? Co prawda nie wyjasnia to dlaczego wylacza sie UART. Gdy ustawia sie flage TXEN i RXEN UART calkowicie przejmuje kontrole nad pinami PD0 i PD1 i zadne wpisy do PORTD nie powinny zaklocac pracy UART.
    Podaj moze wieksza ilosc kodu.
    Pozdro
    Dexter
  • Poziom 10  
    juz rozwiazalem problem - nie zakłóca - błąd był w programie - przy inicjalizacji LCD (przed UARTEM) aby zrealizować timingi wykorzystywalem zegar tylko ze obie inicjalizacje zrobilem przy wyl przerwaniach wiec on wisial w pierwszym wykonywaniu DELAY

    wyświetlacz inicjalizuję zgodnie z instrukcjami w EP/dokumentacji
    czekaj_15ms
    function_set(8bit)
    czekaj_4,1ms
    function_set(8bit)
    czekaj_100us
    function_set(8bit)
    function_set(4bit)
    function_set(4bit, podac n i f)
    display_off
    clear
    entry_mode_set



    Code:

    .def AL = r16
    .def AH = r17


    ....


    .EQU LCD_E    = 0     
    .EQU LCD_RW   = 1
    .EQU LCD_RS   = 2
    .EQU LCD_DB4  = 4
    .EQU LCD_DB5  = 5
    .EQU LCD_DB6  = 6
    .EQU LCD_DB7  = 7
    .EQU LCD_CTR  = PORTB        ; LCD control register
    .EQU LCD_DATA = PORTD        ; LCD data register
    .EQU LCD_DIR  = DDRD
    .EQU LCD_PINS = PIND


    ....


    .MACRO lcd_delay
      ldi   AL, @0
      rcall DELAY_CLK64
    .ENDMACRO

    .MACRO lcd_senddata
      out   LCD_DATA, @0         ; placing data in port
      sbi   LCD_CTR, LCD_E
      nop
      nop
      nop
      cbi   LCD_CTR, LCD_E       ; writing data to LCD
    .ENDMACRO


    ....


    LCD_INIT:
      push  AL
      push  AH
      lcd_delay 255              ; waiting after power on for 255 * 64us = 16,32 ms
      cbi   LCD_CTR, LCD_E
      cbi   LCD_CTR, LCD_RW
      cbi   LCD_CTR, LCD_RS
      in    AH, LCD_DATA         ; reading PORTD content (not PIND)
      andi  AH, 0x0F             ; masking non-data bits in AH
      ori   AH, 0x30             ; "function set" command: 8 bit mode repeated 3 times
      lcd_senddata AH           
      lcd_delay 80               ; waiting for 80 * 64us = 5,12 ms
      lcd_senddata AH           
      lcd_delay 2                ; waiting for 2 * 64us = 128 us
      lcd_senddata AH           
      lcd_delay 2                ; waiting for 80 * 64us = 128 us
      andi  AH, 0x2B             ; function set: 4bits
      lcd_senddata AH           
      lcd_delay 2
      ldi   AL, 0x28             ; "function set" cmd: 4bit, 2 lines, 5x8
      rcall LCD_WRITECMD
      lcd_delay 2
      ldi   AL, 0x08             ; "display off
      rcall LCD_WRITECMD
      lcd_delay 2
      ldi   AL, 0x01             ; "clear" display on
      rcall LCD_WRITECMD
      lcd_delay 80
      ldi   AL, 0x06             ; "entry mode": inc after r/w data, do not shift
      rcall LCD_WRITECMD 
      pop   AH
      pop   AL
      ret



    ; LCD_WRITECHAR - writes char to lcd, AL contains data

    LCD_WRITECHAR: 
      ;rcall LCD_WAIT             ; wait till ready
      cbi   LCD_CTR, LCD_E
      sbi   LCD_CTR, LCD_RS      ; select character mode
      cbi   LCD_CTR, LCD_RW      ; select write mode 
      rcall LCD_WRITE
      ret




    ; LCD_WRITECMD - writes command to lcd, AL contains data

    LCD_WRITECMD:
      ;rcall LCD_WAIT             ; wait till ready]
      cbi   LCD_CTR, LCD_E
      cbi   LCD_CTR, LCD_RS      ; select instruction mode
      cbi   LCD_CTR, LCD_RW      ; select write mode 
      rcall LCD_WRITE
      ret



    ; LCD_WRITE - writes char to lcd, AL contains data/instruction

    LCD_WRITE:
      push  AL
      push  AH                   ; start   
      push  AL                   ; saving data in AL on stack (nescessary in 4b mode)
      in    AH, LCD_DATA         ; reading PORTD content
      andi  AH, 0x0F             ; masking non-data bits in AH
      andi  AL, 0xF0             ; masking more significant data bits in AL
      or    AH, AL               ; placing more significant data bits in AH
      lcd_senddata AH            ; writing more significant data bits to LCD
      pop   AL                   ; restoring data in AL from stack
      swap  AL                   ; swaping data bits halves in AL
      andi  AH, 0x0F             ; masking non-data bits in AH 
      andi  AL, 0xF0             ; masking less significant (swapped) data bits in AL
      or    AH, AL               ; placing less significant data bits in AH 
      lcd_senddata AH            ; writing less significant data bits to LCD
      pop   AH                 
      pop   AL
      ret


    nie wiem czy to jest poprawnie wlasnie jako inicjalizacja :/
    nie wkleilem tu procedury DELAY_CLK64 ale nie jest to konieczne gdyz jesli to jest poprawne to cos z wyswietlaczem by musialobyc chyba :/

    Pozdrawiam,
    paweln[/code]
  • Poziom 39  
    Witam.

    PawelNie napisał:

    ...
    display_off
    ...

    Dlaczego OFF :?:
    Code:

    ....
    LCD_INIT:
      push  AL
      push  AH
    ;  lcd_delay 255          ; waiting after power on for 255 * 64us = 16,32 ms
      cbi   LCD_CTR, LCD_E
      cbi   LCD_CTR, LCD_RW
      cbi   LCD_CTR, LCD_RS
    lcd_delay 255             ; teraz niech się rozgrzeje
      in    AH, LCD_DATA         ; reading PORTD content (not PIND)
      andi  AH, 0x0F             ; masking non-data bits in AH
      ori   AH, 0x30             ; "function set" command: 8 bit mode repeated 3 times
      lcd_senddata AH           
      lcd_delay 80               ; waiting for 80 * 64us = 5,12 ms
      lcd_senddata AH           
      lcd_delay 40                ; nie ma co się spieszyć
      lcd_senddata AH           
      lcd_delay 40   
      andi  AH, 0x2F             ; a czemu nie 0x2F  ??
      lcd_senddata AH           
      lcd_delay 40
      ldi   AL, 0x28             ; "function set" cmd: 4bit, 2 lines, 5x8
      rcall LCD_WRITECMD
      lcd_delay 3

    ; ldi   AL, 0x08             ; "display off
    ; Po co wyłączać , nie lepiej włączyć  ?

      ldi    AL,0x0C              ;display on , cursor off ,blink off
      rcall LCD_WRITECMD
      lcd_delay 3

      ;ldi   AL, 0x01             ; "clear" display on
      ;rcall LCD_WRITECMD
      ;lcd_delay 80
      ;najpierw dokończmy konfigurację  !

      ldi   AL, 0x06             ; "entry mode": inc after r/w data, do not shift
      rcall LCD_WRITECMD
      lcd_delay 2
     
      ldi   AL, 0x01             ; "clear" display on
      rcall LCD_WRITECMD
      lcd_delay 80

    ; teraz niech cuś wyświetli , łobuz jeden ;)

      ldi  AL,'O'
      LCD_WRITECHAR
      lcd_delay 3
      ldi  AL,'K'
      LCD_WRITECHAR

      pop   AH
      pop   AL
      ret

    ...



    Jak Ci "zaświeci" , to możesz pokombinować z opóźnieniami.

    Piotrek