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

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

mikmas 04 Lut 2009 01:47 3067 20
  • #1 6099851
    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:
    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ę:
    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]);
    }
  • #2 6100008
    arturt134
    Poziom 27  
    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.
  • #3 6100266
    marenc
    Poziom 24  
    Sprawdź czy webcam obsługuje taką prędkość... "do prędkości samochodu konia nie zmusisz" ;)
  • #4 6101930
    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
  • #5 6102058
    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.
  • #6 6316657
    Konto nie istnieje
    Poziom 1  
  • #7 6316712
    mikmas
    Poziom 18  
    Temat uważam za zamknięty, bo udało mi się dogadać z kamerką :).

    Atom! 460800b/s
  • #8 6316755
    Konto nie istnieje
    Poziom 1  
  • #9 6317238
    retner
    Poziom 11  
    mikas a możesz napisać co było przyczyną błędu ? tak na przyszlość ?
  • #10 6317437
    mikmas
    Poziom 18  
    Kod inicjacji kamerki:
    USART_init(baud(19200));

    Funkcja USART_init:
    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 :)
  • #11 8605645
    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ą : (
  • #12 8606029
    mikmas
    Poziom 18  
        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();
  • #13 8606296
    kemot55
    Poziom 31  
    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 :-)
  • #14 8612484
    mikmas
    Poziom 18  
    Ja wziąłem ją z SE T300 (dołączana jest, także łatwo podłączyć)
  • #15 8612665
    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
  • #16 8612692
    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
  • #17 8612789
    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. ; )
  • #18 8612812
    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:
    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
  • #19 8612879
    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
  • #21 8613015
    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
REKLAMA