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

[Attiny 2313][C] Sprzętowy rs232 i kamerka

mikmas 04 Lut 2009 01:47 2842 20
  • #1 04 Lut 2009 01:47
    mikmas
    Poziom 18  

    Komunikuję się z kamerką mca-25 za pomocą sprzętowego rs 232. Kwarc taktujący to 14.318180MHz. Wszystko działa dopóki nie zmienię prędkości transmisji z 19200b/s na 460800 bodów - po prostu tak jakby złą prędkość ustawiał. Nie otrzymuję odpowiedzi od kamerki. Macie może pomysł, czemu to nie trybi? Oto kod:

    Code:
    int main()
    
    {
       USART_init(baud(19200)); // #define baud(x) (F_CPU/(16UL*(x)))-1
       DDRB=GRNLED;
       DDRD=1 << PORTD2;
       PORTD=0;
       HIB(GRNLED);
       _delay_ms(500);
       
       LOB(GRNLED);
       PORTD=1 << PORTD2; //włączenie kamerki
       w84data("AT&F"); //oczekuj na komendę inicjującą od kamery
       senddata("\r\nOK\r\n");
       w84data("AT+IPR=?\r");
       senddata("+IPR: (),(460800)\r\n\r\nOK\r\n");
       w84data("800\r");
            senddata("\r\nOK\r\n"); // do tego fragmentu dochodzi jeszcze
       USART_init(1); // (141318180/(16*460800))-1 == 0.9420 == ~1
       w84data("AT+CMUX=?"); //nie otrzymuję niczego takiego
       senddata("\r\n+CMUX: (0)\r");
       senddata("\r\nOK\r\n");
       w84data("AT+CMUX=0,0,7,31");
       senddata("\r\nOK\r\n");
       return 0;
    }

    Reszta funkcji działa dobrze, także myślę, że nie ma sensu szukać w nich błędu, ale jeśli ktoś chce to proszę:
    Code:
    void USART_init(int baudrate)
    
    {
      UBRRH = (unsigned char)(baudrate>>8);
      UBRRL = (unsigned char)baudrate;
     
      UCSRB = (1 << RXEN) | (1 << TXEN);
      UCSRC = (3 << UCSZ0);
    }

    unsigned char USART_receive()
    {
      while (!(UCSRA & (1 << RXC)));
      return UDR;
    }

    void USART_transmit(unsigned char chr)
    {
       while(!(UCSRA & (1 << UDRE)));
       UDR=chr;
    }

    int strlen(const char* src)
    {
      int i;
      for (i=0;src[i];i++);
      return i;
    }

    void w84data(const char* cmpwith)
    {
      int cmppos=0;
      int cmpsize=strlen(cmpwith);
      unsigned char rcv;
     
      do
      {
        rcv=USART_receive();
        if (rcv==cmpwith[cmppos])
          cmppos++;
        else
          cmppos=0;
      }while(cmppos < cmpsize);
    }

    void senddata(const char* tosend)
    {
       int i;
       for (i=0;tosend[i];i++)
          USART_transmit(tosend[i]);
    }

    0 20
  • Napad.pl
  • #2 04 Lut 2009 08:02
    arturt134
    Poziom 26  

    Masz błąd ustawienia baud rate równy prawie 3%. Może spróbuj dopasować kwarc, tak aby błąd był mniejszy? Na przykład wstawić 14,745MHz. Wtedy, dla UBRR = 1 i U2X = 0 błąd będzie praktycznie zerowy. Kwarc możesz kupić w TME.

    0
  • Napad.pl
  • #3 04 Lut 2009 09:49
    marenc
    Poziom 24  

    Sprawdź czy webcam obsługuje taką prędkość... "do prędkości samochodu konia nie zmusisz" ;)

    0
  • #4 04 Lut 2009 16:55
    mikmas
    Poziom 18  

    Maremc! Powiem więcej! Ona wymaga takiej prędkości. Na żadnej innej nie zatrybi (wymusza tą prędkość, przez co miałem z nią problemy po podłączeniu do kompa - port com nie wyrabiał, a to "coś" pod usb<-->com nie chciałem kupować, bo szkoda kasy było :)

    Arturt! 3% to dużo? :/ Skoro tak mówisz to kupię jutro kwarc taki jak mówisz

    0
  • #5 04 Lut 2009 17:22
    marenc
    Poziom 24  

    3% to naprawdę dużo... standard RS232 nie przewiduje linii zegarowej(w swojej pierwotnej postaci, bo teraz istnieje możliwość jej stosowania). Synchronizacja zegara w nadajniku i odbiorniku następuje przy bicie startu, a błąd częstotliwości 3% przy ramce 9bitów daje blisko 27% błędu przy ostatnim bicie ... co więcej ... błąd występuje również przy bicie(bitach) stopu, a ich błędne wykrycie daje błąd ramki - skutkiem tego jest błędna transmisja danej.

    0
  • #6 22 Mar 2009 15:51
    atom1477
    Poziom 43  

    Ma być 468000 a nie 460800.

    0
  • #7 22 Mar 2009 16:01
    mikmas
    Poziom 18  

    Temat uważam za zamknięty, bo udało mi się dogadać z kamerką :).

    Atom! 460800b/s

    0
  • #8 22 Mar 2009 16:12
    atom1477
    Poziom 43  

    Racja. W innym poście znalazłem informację że to ma być 468000 i dlatego tak napisałem.

    0
  • #9 22 Mar 2009 17:59
    retner
    Poziom 10  

    mikas a możesz napisać co było przyczyną błędu ? tak na przyszlość ?

    0
  • #10 22 Mar 2009 18:37
    mikmas
    Poziom 18  

    Kod inicjacji kamerki:

    Code:
    USART_init(baud(19200));

    Funkcja USART_init:
    Code:
    void USART_init(int baudrate)
    
    {
      UBRRH = (unsigned char)(baudrate>>8);
      UBRRL = (unsigned char)baudrate;
     
      UCSRB = (1 << RXEN) | (1 << TXEN);
      UCSRC = (3 << UCSZ0) | (1 << USBS);
    }


    Problemem była za długo wykonująca się funkcja odbierająca dane. Przy małych prędkościach (19200b/s) jeszcze wytrzymywała. Jednak jak dałem na pełny bieg to każdy takt się liczy :)

    0
  • #11 10 Paź 2010 22:41
    cool_kuba
    Poziom 12  

    Czy mógł byś udostępnić swój program ponieważ mam bardzo podobny program tyle że u mnie to chyba Kamerka nie zmienia prędkości na wyższą : (

    0
  • #12 11 Paź 2010 02:27
    mikmas
    Poziom 18  

    Code:
        w84data("AT+IPR=?\r");
    
        senddata("+IPR: (),(460800)\r\n");
        ATok();
        w84data("800\r");
        ATok();
        USART_init(1);
        _delay_ms(2);
       
        w84data("AT+CMUX=?");
        senddata("\r\r\n+CMUX:\r");
        ATok();
        w84data("31");
        ATok();

    0
  • #13 11 Paź 2010 09:45
    kemot55
    Poziom 30  

    A gdzie można kupić taką kamerkę (najlepiej w okolicach Łodzi)? Przepraszam za off'a, ale trochę szukałem i najbliższa lokalizacja wyszła mi w USA :-)

    0
  • #14 12 Paź 2010 21:09
    mikmas
    Poziom 18  

    Ja wziąłem ją z SE T300 (dołączana jest, także łatwo podłączyć)

    0
  • #15 12 Paź 2010 21:43
    cool_kuba
    Poziom 12  

    @Kemot Ja swoją kupiłem na giełdzie elektronicznej w Krakowie ale ciężko było. Może masz coś takiego w Łodzi bo ja nie wiem.

    @Mikmas
    A co do programu to widzę że po prostu nie czekasz już na całe komendy tylko na ich końcówki i dodałeś funkcję ATok() która domyślam się wysyła OK? Czyli właściwie to nie wiele zmieniłeś i działa lecz u mnie taka modyfikacja nie wiele daje nadal dochodzi do momentu zmiany prędkości i dalej wysyła ale wcale kamerka nie zmienia prędkości i to jest bardzo dziwne! Może sekret tkwi w funkcji ATok():
    Czy zmieniłeś jakoś komendę OK czy jest taka sama czyli "\r\nOK\r\n"?


    I czy miałeś może kiedyś taki przypadek żeby nie zmieniała się prędkość?


    Dzięki za odpowiedź !! :D

    0
  • #16 12 Paź 2010 21:47
    mikmas
    Poziom 18  

    1. Na jakiej podstawie stwierdzasz, że nie zmienia prędkości? Nie otrzymujesz poprawnej odp?
    2. Jaki kwarc użyłeś
    3. Pokaż funkcję oczekującą na odp
    3a. Jeżeli użyłeś moich to od razu mówię - są złe, bo za wolne. Jak chcesz mogę podesłać działające

    0
  • #17 12 Paź 2010 22:00
    cool_kuba
    Poziom 12  

    mikmas napisał:
    1. Na jakiej podstawie stwierdzasz, że nie zmienia prędkości? Nie otrzymujesz poprawnej odp?
    2. Jaki kwarc użyłeś
    3. Pokaż funkcję oczekującą na odp



    1. Bo jeśli nie zmienię prędkości na uC to kurde działa dalej przynajmniej do uruchomienia tego mux bo dalej nie testowałem. tylko jest taki lag gdzie 1s lub 2s po tym ustawieniu prędkości więc dlatego obawiam się że jest coś nie tak z tym OK.
    2. używam STM32 to nie wiem czy kwarc ma takie znaczenie ale mam 12Mhz i jest ale jest przemnożony przez 6 czyli procesor działa z 72Mhz. Ale możliwe że to coś tu.
    3. A teraz funkcję oczekującą na odpowiedź mam taką jak ty. Co nie jest ciekawe
    ale wcześniej czekałem po prostu na ostatni znak.
    Cytat:
    while (1)
    {
    if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
    {
    c=USART_ReceiveData(USART1);
    GPIO_SetBits(GPIOB, GPIO_Pin_15);
    if(c=='?')
    {
    USART_PutString("\r\n+CMUX: (0)\r");
    }
    }
    }

    ale tak jak Ty też mi nie działa :D.Chociaż przyznaje że zrobiłem to bardzo topornie. ; )

    0
  • #18 12 Paź 2010 22:05
    mikmas
    Poziom 18  

    U mnie był problem z funkcją odbierającą. Była za wolna, tylko ja pracowałem na 14MHz na at2314, więc o każdy takt trza walczyć w moim przypadku. Jednak to są funkcję po modyfikacji:

    Code:
    void w84data(const char* cmpwith) 
    
    {
        const char* sptr = cmpwith;
        while(*sptr)
            if(*sptr++ != USART_receive())
                sptr = cmpwith;
    }

    void senddata(const char* tosend)
    {
        while(*tosend)
            USART_transmit(*tosend++);
    }

    PS. Używaj klawisza TAB podczas pisania programów. Inaczej się pogubisz bardzo szybko

    0
  • #19 12 Paź 2010 22:17
    cool_kuba
    Poziom 12  

    Hymm a z tym ATok(); to jak jest? Po prostu wysyłanie OK żeby się nie męczyć czy jakoś zmieniłeś może komendę dla OK??

    Bo ja jakoś tu doszukuję się błędu choć jest to mało możliwe bo wszędzie tak piszą.
    A gdzieś też znalazłem że funkcje biblioteczne dla STM32 których używam są wolne... może spróbuje zagłębić się w Rejstry.

    Z tym TAB to sama prawda ...ale jakoś nie chciało mi się heh

    0
  • #20 12 Paź 2010 22:19
    mikmas
    Poziom 18  

    Niestety nic się nie zmienia:

    Code:
    static void ATok()
    
    {
        senddata("\r\nOK\r\n");
    }

    0
  • #21 12 Paź 2010 22:41
    cool_kuba
    Poziom 12  

    dzięki za pomoc postaram się coś po próbować jak się uda to dam znać z czym był problem :D

    0