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

[ATmega16][C]AVRStudio i symulacja USART - rejestry.

KonusiK 09 Wrz 2008 18:46 3281 9
  • #1 5520476
    KonusiK
    Poziom 12  
    Testuje sobie nowe programy na zestawie uruchomieniowym i nadszedł czas na USARTa.

    Napisałem najprostszy kod pod słońcem na wysyłanie bajtu. Oczywiście są jakieś błędy w transmisji bo NIC nie dochodzi.

    Przesymulowałem program, i to co mi wyskoczylo:
    [ATmega16][C]AVRStudio i symulacja USART - rejestry.

    Do UBRRH wpisuje same zera, okazuje sie,że mam 0x8E! Nie wiem, czy to błąd symulatora, w kazdym razie w taki sposób na pewno nie prześle niczego... Tylko co zrobić, by wpisała sie właściwa liczba?

    Wykasowałem nawet linijke zerującą UBRRH i pojawia sie to samo... Próbowałem wrzucić nawet breakpoint'a - nawet nie chce wskoczyć w inicjalizacje UARTa...

    Dobra, teraz pokombinowałem - UBRRH ustawiał sie na 0x68 po linijce:
    UCSRC |= (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);

    wiec walnąłem mu po niej UBRRH =0x00; i oczywiście wyzerował mi UBRRH i UCSRC!

    Padam przy tym... dzieks z góry za wszelką pomoc...

    Poprawiłem tytuł - regulamin p.11
    Proszę poprawić treść wiadomości - regulamin p.11
    [zumek]
  • #2 5521089
    saper_2
    Poziom 18  
    Musi ci wpisać wartość do UBRR, przeanalizuj pracę krokowo, zrób może make clean. A może zamiast wpisywać oddzielnie UBRRH/L wpisz po prostu "UBRR = 0x68" w inicjacji.... Może rzuć okiem na źródła ASM może kompilator robi ci jakiegoś trika ;)

    Ja mam taką inicjację(wygrzebana z działającego projektu):
    
    	//UBRRH = (USART_UBRR >> 8); 
    	UBRRL = USART_UBRR; // Assign UBRRL
    	UCSRB = (1 << RXEN) | (1 << TXEN); // Enable Tx & Rx
    	UCSRC = (1 << UCSZ0) | (1 << UCSZ1); // Frame 8,N,1
    


    Ps. Deklarowanie zmiennych przyjęte jest ogólnie na początku funkcji :)
  • #3 5521555
    KonusiK
    Poziom 12  
    Owszem kompilator mi psikusa zrobił... a moze to <io/avr.h>? Adresy UBRRH i UCSRC są identyczne! Normalnie oniemiałem...

    Nawet widać to na zdjęciu które zamieściłem: w prawym dolnym rogu ekranu: UBRRH 0x20 (0x40), UCSRC 0x20 (0x40). Powaga, zupełnie zgłupiałem jak to zobaczyłem..

    Czyli co, musze zmienić adres w <io/avr.h>?

    BTW. kompilator nie przyjmuje UBRR - znane mu są nazwy UBRRH/L - to dla tych, którzy czytaliby ten wątek.
  • #4 5523082
    saper_2
    Poziom 18  
    Hmmm, dziwne, nie wiem jaki kompilator C masz z avrstudio... ale ja używam winavr (avr studio używam do symulacji tylko, piszę w PN) i wiem ,że jakieś były błędy w poprzedniej wersji...

    A adresy rejestrów są w plikach ioXXX.h (gdzie XXX to skrócony symbol procesora) zaś w twoim wypadku będzie to w "iom16.h" ,a gdzie ten plik leży to nie pamiętam...
  • Pomocny post
    #5 5523210
    rrata
    Poziom 19  
    KonusiK napisał:
    Czyli co, musze zmienić adres w <io/avr.h>?
    Nie. Tak ma być. Patrz datasheet.

    Masz błąd w
    UCSRC |= (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);

    Co tam robi 3?
    powinno być:
    UCSRC |= (1<<URSEL)|(1<<USBS)|(1<<UCSZ0);


    Albo zapisz od razu cały bajt. W twoim przypadku będzie:
    UCSRC = 0b10001010;
  • #6 5524016
    KonusiK
    Poziom 12  
    Jasne, tu masz całkowitą racje
    UCSRC |= (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);

    tej 3 ma nie być - aż sam sie dziwie,że coś takiego napisałem.

    Fakt, datasheet wskazuje na te sam adres... Nie zauważyłem tego wcześniej. Dzieki wielkie za to!

    Ale tematu na wszelki wypadek jeszcze nie zamykam.

    Dodano po 32 [minuty]:

    Niestety, dalej nie bardzo chce chodzić. Datasheet wskazuje: "When doing a write access of this I/O location, the high bit of the value written, the USART Register
    Select (URSEL) bit, controls which one of the two registers that will be written. If URSEL is
    zero during a write operation, the UBRRH value will be updated. If URSEL is one, the UCSRC
    setting will be updated."

    Wiec napisałem najbardziej expclite jak tylko sie da, kiedy zamierzam coś wpisywać i gdzie, ustawiając/kasując URSEL:

    UCSRC &= ~(1<<URSEL);
    	DDRA = 0xFF;
    	UBRRH = 0;
    	UBRRL = 104;
    	/* Enable receiver and transmitter */
    	UCSRB |= (1<<RXEN)|(1<<TXEN);
    	UCSRC |= (1<<URSEL);
    	/* Set frame format: 8data, 2stop bit */
    	UCSRC |=(1<<USBS)|(1<<UCSZ0);


    I niestety, wynik jest identyczny jak poprzednio..Porażka..
  • #7 5536841
    KonusiK
    Poziom 12  
    Skopiowałem i wkleiłem to co Saper_2 wygrzebał z projektu, ale to i tak nic nie zmieniło. Modyfikując UCSRC, nawet przy URSEL = 0 modyfikuje mi UBRRH. I powstaje mi jedna wielka kupa z BAUD_RATE...

    Poważnie, nie wiem co mam z tym zrobić. Czy ktoś byłby łaskaw przesłać mi najprostszy program ECHO do odibjania danych z kompa. Tylko cały, z inicjalizacjami. Bo powoli zaczyna mnie to wkurzać, bo musze przetestować wysyłanie całej ramki danych (własny zdefiniowany protokół), ale siedze po kolana w bagnie bo nie moge przesłąć nawet jednej danej :/
  • #8 5538068
    mario06
    Poziom 15  
    KonusiK napisał:
    Skopiowałem i wkleiłem to co Saper_2 wygrzebał z projektu, ale to i tak nic nie zmieniło. Modyfikując UCSRC, nawet przy URSEL = 0 modyfikuje mi UBRRH. I powstaje mi jedna wielka kupa z BAUD_RATE...


    I tak powinno być, oba rejestry mają ten sam adres, więc zmiana jednego zmienia drugi(uC rozpozna o który rejestr chodzi dzięki URSEL). A w symulatorze zmiana zostanie zarejestrowana przez oba znaczniki.
  • #9 5539273
    ciastek4
    Poziom 14  
    Hehehe

    Też miałem problemy z symalatorem i dałem sobie spokój.

    Proponuję tak:
    1) sprawdzić fuse bity ( czy dobrze jest zegar ustawiony )
    2) poprawność połączeń ( hardware ): kabel PC<->uC, max-a( można wykonać loop back-a hardwarowego zwierając rx z tx ( sygnały TTL ) gdy da się wyjąć uC.
    3) przekopoiować kody dostępne w datasheetcie. Wszystko jak leci. Usart init ( wpisać UBRH i UBRL ręcznie z przykładów dostępnych w datasheeticie), tak samo jak UsartTx i UsartRx..
    4) zastowować terminal w którym można monitorować port COM (np. darmowy realterm)
    5) wysłać jakiś konkretny znak z ASCII np. 'A' albo cokolwiek a nie kod 0x11 ( Device control), który BTW nie wiem co robi :P
    6) wgrać do megi program :D


    Gdy wykonasz te kroki to na pewno Ci się uda, bądz zdiagnozujesz problem.

    Pozdrawiam :)
  • #10 5875863
    Jacekser
    Poziom 25  
    Z tresci HELP "AVR TOOLS USER QUIDE" AvrStudio m.in. o tym problemie:

    "Device specific issues

    Notes for ATmega16
    The USART's UBRRH and UCSRC registers share the same I/O address. Writing to one of the registers will cause both registers to contain the new value, regardless of the value of URSEL. Reading these registers do not work as described in the datasheet.
    The JTD bit in the MCUCSR register must be set to the desired value twice within four cycles to change its value. In the simulator the JTD bit can be written directly.
    The ADC noise reduction function is not supported. Setting the ADIF flag will not wake the CPU from sleep mode."
REKLAMA