logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.
  • #1 7329454
    revolt
    Poziom 34  
    Mimo najszczerszych chęci ten pakiet mnie zaczyna wkurzać powoli. Ostatnio podczas pisania program, który działał godzinę temu przestaje, ale przed chwilą to już przesadziło.
    Taki kawałek (odbieram ramkę z GPSa i wyrzucam na terminal czas sobie):

    void pokaz()
    {

    int zimowy;
    zimowy=asd[9]+1;
    US_TRA(asd[8]);
    US_TRA(zimowy);
    US_TRA(':');
    (....)

    Działało po południu. Teraz włączam i zamiast 21:14:00 pokazuje mi 2::14:00. Jako, że nie pierwszy raz PRZEPISAŁEM to na nowo - kompilacja i działa OK. Jeszcze przeżyłbym, ale już raz przepisywałem 3/4 kodu :/
    PS> tablica asd jest deklarowana z volatile.
  • #2 7329781
    arrevalk
    Poziom 25  
    Jak chcesz żeby ktoś pomógł to pokaż cały kod albo chociaż wyjaśnij co zawiera tablica asd bo z tego skąpego fragmentu programu niewiele można wywnioskować.

    No i wstaw kod ze swojego posta w znaczniki code.
  • #3 7330041
    mirekk36
    Poziom 42  
    No na pewno wina nie leży niestety po stronie WinAvr - tylko po stronie samego programisty - taka jest prawda czasu i ekranu.

    Samo przepisywanie tegoż kawałka kodu nic nie da i nic nie zmieni - problemy możesz mieć ze swoimi funkcjami do nadawania albo odbioru przez UART. Bo równie dobrze może być być to błąd przy nadawaniu do terminala a równie dobrze może to być błąd przy odbieraniu ramki z GPSa - albo jeszcze gdzie indziej w kodzie.
  • #4 7330186
    Freddie Chopin
    Specjalista - Mikrokontrolery
    revolt napisał:
    Mimo najszczerszych chęci ten pakiet mnie zaczyna wkurzać powoli. Ostatnio podczas pisania program, który działał godzinę temu przestaje, ale przed chwilą to już przesadziło.

    Otwórz konsole i wpisz format c: - problemu nie będzie. Przecież nikt nie każe Ci używać tego pakietu, prawda?

    4\/3!!
  • #5 7330424
    revolt
    Poziom 34  
    U widzę bojowe nastawienie co niektórych :)

    A więc kod:

    #include "stdio.h"
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #define FOSC 12000000// Clock Speed
    #define BAUD 9600
    #define MYUBRR FOSC/16/BAUD-1
    
    
    
    volatile int coun;
    
    volatile int asd[69];
    
    
    void USART_Init( unsigned int ubrr)
    {
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }
    
    
    void US_TRA(unsigned char data)
    {
    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
    }
    
    void pokaz()
    {
    
    int zimowy;
    	zimowy=asd[9]+1;
    	
    	US_TRA(asd[8]);
    	US_TRA(zimowy);
    	US_TRA(':');
    	
    	US_TRA(asd[10]);
    	US_TRA(asd[11]);
    	US_TRA(':');
    	
    	US_TRA(asd[12]);
    	US_TRA(asd[13]);
    
    	US_TRA(13);
    
    }
    
    SIGNAL(SIG_UART_RECV)
    {
    
    if (UDR==0x24) {coun=0; } //szuka początku danych z GPSa ($......)
    
    asd[coun]=UDR; //zapisuje od początku ramki
    
    
    if (UDR==0x2A)  //jezeli * czyli koniec pojedynczej ramki
    {
    
    if (asd[5]==0x4D && asd[6]==0x43) //wyszukuje konkretną ramkę
    
    	{
    		pokaz();
    	
    	}
    }
    
     coun++;
      
    }
    
    int main(void) 
    { 
      
      USART_Init ( MYUBRR );
      sei();
      
        // EEPROM_write(201, k);
    	
          while(1) 
         { 
         } 
    }
    


    Nie oto chodzi, że napisałem sobie i nie działa - ten sam program (bez żadnych zmian) potrafi się inaczej zachowywać po kompilacji.
  • #6 7330691
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Cytat z datasheeta atmegi16 (akurat ten mam pod ręką):

    Cytat:
    Therefore the UDR must only be read once for each incoming data!


    Zrozum też różnicę między int (twoja tablica) a char (dane odbierane przez UART).

    Ciekawe czy zauważyłeś też, że podczas odsyłania danych (skoro robisz to wewnątrz przerwania odbioru - genialne!) gubisz inne napływające dane.

    A teraz najlepsza ciekawostka dla ciebie! (SUPER HIT!) Zgadnij po znaku jakiej cyfry jest dwukropek w tablicy ASCII? Tak, właśnie tak - po 9, więc teraz zastanów się, co się stanie jak twoja super-h4x0rska korekcja czasu zimowego zostanie zaaplikowana na godzinę kończącą się cyfrą 9...

    Jak już to wszystko przemyślisz to szukaj dalej błędu w kompilatorze i nie zapomnij zgłosić go twórcom!

    Jak to możliwe, że o 18tej działało, a o 19 już nie? Co za zj$%^$% kompilator!

    4\/3!!
  • #7 7330952
    mirekk36
    Poziom 42  
    Freddie Chopin napisał:
    .... Co za zj$%^$% kompilator!


    Freddie - nie przeklinaj ;) hyhyhyhy albo może inaczej nie cytuj tak brzydkich myśli autora ;)

    No a zgodnie z tym co ja pisałem spełniły się wszystkie najgorsze koszmary w każdym miejscu praktycznie tegoż kodu, które kolega powyżej super przedstawił - nic dodać nic ująć.

    Ja bym tylko powiedział, że niestety pokutuje najczęściej błąd przy podejściu do przerwań tak w ogóle. A przy takich przerwaniach jak do pracy z RS232 to mści się najszybciej.

    Pętla główna u ciebie pusta - a cały program piszesz w przerwaniach więc już z tego punktu nie dziwota, że będziesz miał zawsze jakąś degrengoladę.

    Już prędzej by ci wyszło coś gdybyś w trybie poolingu za pomocą fragmentów na żywca kodu do obsługi odbioru czy wysyłania zrobił to w main

    Natomiast jeśli chcesz używać przerwań to proponuję poczytać i zrobić sobie to raz a dobrze - przyda się na pewno na później. Poczytaj o sprzętowym buforze cyklicznym przy obsłudze przerwań UART - a zobaczysz że wiele ci się wyjaśni w tym temacie.

    A dopiero później zajmuj się pozostałymi częściami kodu tzn doprowadzeniem tego do porządku - a na pewno - po kolei ładnie ci wszystko wyjdzie.

    Powodzenia
REKLAMA