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

[Atmega32][c][BTM222][USART]

mijadzi 05 Lis 2011 16:00 3946 9
  • #1 10104359
    mijadzi
    Poziom 10  
    Witam!

    Mam problem. Podłączyłem atmege32 z BTM222 i na komputerze używał programu Realterm do obsługi portu szeregowego.

    Komputer się ładnie podłączył do BTM-a, to znaczy nawiązał połaczenie wpisałem kod 1234 i w programie Realterm jest napisane że się połączył. Chyba jest problem dalej, to znacyz z USART-em. Gdy wysyłam coś z komputera to uC tego nie odbiera i na odwrót, Ale nie wiem co jest źle:(
    Ustawiłem, Usarta tak jak jest w dokumentacji BTM-a:
    Baud rate: 19200 bps
    z Data bit: 8
    z Parity: none
    z Stop bit: 1
    Tu przedstawiam mój program:
    #include <avr/io.h>
    #include <util/delay.h>
    
    #define BAUD 19200
    #define MYUBRR F_CPU/16/BAUD-1
    
    /* Usypianie */
    void delay_ms(int ms)
    {
    	volatile long unsigned int i;
    	for(i=0;i<ms;i++)
    		_delay_ms(1);
    }
    
    /* Inicjalizacja bloku USART */
    void USART_Init( unsigned int ubrr)
    {
    	UBRRH = (unsigned char)(ubrr>>8);	// Ustawienie predkosci
    	UBRRL = (unsigned char)ubrr;
    	UCSRB = (1<<RXEN)|(1<<TXEN);		// Wlaczenie nadajnika i odbiornika
    	UCSRC = (1<<URSEL)|(3<<UCSZ0);		// Ustawienie ramki 8bit, 1bit stopu, brak bitu parzytosciu
    }
    
    /* Transmisja przez bluetooth */
    void USART_Transmit( uint8_t data )
    {
    	while ( !( UCSRA & (1<<UDRE)) )		// Czekanie na wolny bufor zapisu
    		;
    	UDR = data;							// Przeslanie danych
    }
    
    /* Odczyt przez bluetooth */
    uint8_t USART_Receive( void )
    {
    	while ( !(UCSRA & (1<<RXC)) )		// Czekanie na dane do odczytu
    		;
    	return UDR;							// Zwrot odczytanych danych
    }
    
    /* Inicjalizacja BTM-222 przez komendy AT */
    void BTM_Init()
    {
    	USART_Transmit('A');				// Przywrocenie wartosci domyslnych
    	delay_ms(25);
    	USART_Transmit('T');
    	delay_ms(25);
    	USART_Transmit('P');
    	delay_ms(25);
    	USART_Transmit('0');
    	delay_ms(25);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    
    	USART_Transmit('A');				// Wylaczenie echa
    	delay_ms(25);
    	USART_Transmit('T');
    	delay_ms(25);
    	USART_Transmit('E');
    	delay_ms(25);
    	USART_Transmit('0');
    	delay_ms(25);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    	
    	USART_Transmit('A');				// Wylaczenie kontroli przeplywu
    	delay_ms(5);
    	USART_Transmit('T');
    	delay_ms(5);
    	USART_Transmit('C');
    	delay_ms(5);
    	USART_Transmit('0');
    	delay_ms(5);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    	
    	USART_Transmit('A');				// Wylaczenie kodow wynikowych
    	delay_ms(5);
    	USART_Transmit('T');
    	delay_ms(5);
    	USART_Transmit('Q');
    	delay_ms(5);
    	USART_Transmit('1');
    	delay_ms(5);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    }
    
    int main(void)
    {
    	USART_Init(MYUBRR);					// Inicjalizacja USART
    	BTM_Init();							// Inicjalizacja BTM
    	DDRB|=_BV(PB2);						//wyjście dioda zielona
    	DDRB|=_BV(PB1);						//wyjście dioda żółta
    	PORTB |= _BV(PORTB1);				//zgaszenie diody żółtej
    	PORTB &= ~_BV(PORTB2);				//zapalenie diody zielonej
    	DDRC &= ~_BV(PC0);					//wejście przycisk S3
    	PORTC|=_BV(PC0);					//podciągnięcie wejścia do góry
    	while(1)
        {
    		//PORTB |= _BV(PORTB1);			//zgaszenie diody żółtej
    		if(USART_Receive() == 'B') {	
    			PORTB &= ~_BV(PORTB1);		//zapalenie diody żółtej
    		}			
    		
    		//USART_Transmit('B');
    		delay_ms(25);
            //TODO:: Please write your application code 
        }
    }

    Dodałem do portu PIO(6) (w BTM-ie) diode (zobaczyłem ją w jakimś schemacie na necie, nie wiem co ona dokładnie oznacza:() i ona cały czas świeci, aż program Realterm się z nią nie połączy potem gaśnie. Nie wiem czy ma to coś wspólnego z problemem, ale mówię o takim fakcie.

    Proszę o w miarę szybką pomoc. Przede wszystkim chciałbym znaleźć jakiś sposób by się dowiedzieć czy dobrze ustawiłem połączenie USART.

    Z góry dziękuję za pomoc!!!
  • #2 10104839
    mirekk36
    Poziom 42  
    Pierwszym i najgorszym babolem jaki robisz jest jakieś tam wymyślone inicjalizowanie BTM'a. Toż to szaleństwo ;) .... czy nie czytałeś o tym, że za każdym startem procka (a na pewno jest ich trochę, wciąż przeprogramowujesz dane w pamięci EEPROM modułu BTM ??? To się robi TYLKO RAZ i najlepiej z poziomu terminala na PC. Tzn raz sobie konfigurujesz BTM'a i to wszystko - potem zapominasz o tym.

    Masz na samej elektrodzie kilka długich tematów o modułach BTM-222. Masz tam wszystko opisane a także pokazane dokładne schematy - a ty coś gdzieś tam jakąś diodę w ciemno podłączasz i nawet nie wiesz po co i do czego.

    Reasumując - wywal tą swoją funkcję BTM_Init() i nigdy jej nie wywołuj z poziomu procka bo to w ogóle bez sensu jest niestety :(

    Czy zasilasz to wszystko z 3,3V ?

    No i jak chcesz szybciej przetestować to lepiej sobie z procka na początek ustaw wysyłanie jakiegoś znaku - np co sekundę do termianala - żeby zobaczyć czy w końcu ruszyło.

    Oczywiście ruszy - gdy połączenie zainicjujesz właśnie terminalem

    no i najważniejsze - nawet nie napisałeś - jaką częstotliwością taktujesz procka ???

    A poza wszystkim - to weź ty sobie odłącz na razie BTM'a i w zamian za to podłącz się kablem RS232 do kompa. Sprawdź czy działa ci komunikacja tak jak chcesz - a jeśli ruszy to wtedy zamiast sznurka włączysz BTM (i bez żadnej inicjalizacji w procku) wszystko ci ruszy od razu ;)
  • #3 10111503
    mijadzi
    Poziom 10  
    kompletnie nie mam pojęcia co się dzieje. Próbowałem na wszystkie sposoby otrzymać cokolwiek od BTM-a i nic. Na uC wylaczylem BTM_init i funkcje inicjalizującą napisałem taką:
    #include <avr/io.h>
    #define F_CPU 4000000
    #include <util/delay.h>
    
    
       static void
       uart_19200(void)
       {
       #define BAUD 19200
       #include <util/setbaud.h>
       UBRRH = UBRRH_VALUE;
       UBRRL = UBRRL_VALUE;
       #if USE_2X
       UCSRA |= (1 << U2X);
       #else
       UCSRA &= ~(1 << U2X);
       #endif
       }
    
    /* Inicjalizacja bloku USART */
    void USART_Init() //unsigned int ubrr)
    {
    	uart_19200();
    	UCSRC = (1<<URSEL)|(1<<UCSZ0);		// Ustawienie ramki 7bit, 1bit stopu
    	UCSRB = (1<<RXEN)|(1<<TXEN);		// Wlaczenie nadajnika i odbiornika,  brak bitu parzytosciu
    	//UCSRB = (1<<RXEN)|(1<<TXEN);		// Wlaczenie nadajnika i odbiornika,  brak bitu parzytosciu
    }

    ustawiałem ramki na 7 i na 8 bitów i w żaden sposób nie mogłem nic otrzymać od BTM-a. Z pozycji komputera to samo wysyłałem mu komendy typu ATF? by zwrócił swą nazwę, na inne komendy też nie reagował. Sprawdziłem napięcia zasilające wszystkie są na 3,3 V, tam gdzie ma być 0 jest 0. Do połączenia uC do kompa przez rs232 potrzebuje jeszcze przetwornika, którego nie mam. uC taktuje zegarem 4MHz. BTM raczej nie jest zepsuty, niedawno go kupiłem. Nie wiem co jest nie tak. Proszę o jakąkolwiek pomoc.
  • #4 10111508
    kiziu13
    Poziom 17  
    Zacznij od kodu, który używasz, całego, nie kawałka oraz od schematu połączeń.
  • #5 10111692
    mirekk36
    Poziom 42  
    mijadzi napisał:
    kompletnie nie mam pojęcia co się dzieje. .


    No nie dziwię się, bo po opisie problemu i podejściu jawi się totalny chaos. Przede wszystkim np sprawdzanie wszystkiego czyli ramek składających się z 7 bitów ;) Szok! jakie pomysły ludzie mają?

    Proponuję usiąść na spokojnie, otrząsnąć się z tego co było i przeczytać najpierw PDF od BTM'a z którego jasno wynika jaki musi być format ramki przy domyślnych ustawieniach z fabryki: 19200, 8, n, 1.

    Potem zgodnie z notą PDF procka - napisać inicjalizację UART - masz pan tam gotowy fragment kodu, a następnie w pętli głównej wysyłaj jakiś znak np "A" na terminal co sekundę. Wtedy podłącz się terminalem do virtualnego portu COM stworzonego przez twoją przejściówkę USB/BT i zaczniesz widzieć nadlatujący znak "A". Pamiętaj żeby terminal ustawić tak samo. I nie wymyślaj żadnych innych ustawień bo to bez sensu.

    Jeśli ci to nie zadziała to:

    1. masz skopane połączenia - więc pokaż schemat jak to zrobiłeś
    2. masz problem ze swoją przejściówką USB/BT (najpewniej z jej prawidłową instalacją)
  • #6 10112145
    mijadzi
    Poziom 10  
    Rzeczywiście znalazłem błąd w schemacie, ale teraz sobie sam pogrzebałem. Ponieważ wyłączyłem kod autoryzacji poleceniem ATP0 i się zaczęły problemy:( ponieważ nie mogę się połączyć z komputera do BTM-a:( podczas instalacji urządzenia wybieram opcje(opcja bez parowania), ale gdy włączam Realterm-a to jest wymagane parowanie, a kod 1234 już nie działa:(
    Próbowałem z powrotem przywrócić stary kod takimi poleceniami:
    USART_Transmit('A');
    delay_ms(25);
    USART_Transmit('T');
    delay_ms(25);
    USART_Transmit('P');
    delay_ms(25);;
    USART_Transmit('=');
    delay_ms(25);
    USART_Transmit('1');
    delay_ms(25);
    USART_Transmit('2');
    delay_ms(25);
    USART_Transmit('3');
    delay_ms(25);
    USART_Transmit('4');
    delay_ms(25);
    Ale to już nie działa. Możliwe że coś źle jest ustawione z połączeniem uC z BTM, bo może one się komunikują ale BTM może nie odbiera dokładnie to co mu wysyłam. Dlatego przedstawiam kod:
    /*
     * bodyguard.c
     *
     * Created: 2011-11-05 12:18:52
     *  Author: wojtek
     */ 
    
    #include <avr/io.h>
    #define F_CPU 4000000
    #include <util/delay.h>
    
    
       static void
       uart_19200(void)
       {
       #define BAUD 19200
       #include <util/setbaud.h>
       UBRRH = UBRRH_VALUE;
       UBRRL = UBRRL_VALUE;
       #if USE_2X
       UCSRA |= (1 << U2X);
       #else
       UCSRA &= ~(1 << U2X);
       #endif
       }
       
    
    /* Usypianie */
    void delay_ms(int ms)
    {
    	volatile long unsigned int i;
    	for(i=0;i<ms;i++)
    		_delay_ms(1);
    }
    
    /* Inicjalizacja bloku USART */
    void USART_Init() //unsigned int ubrr)
    {
    	uart_19200();
    	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);		// Ustawienie ramki 8bit, 1bit stopu
    	UCSRB = (1<<RXEN)|(1<<TXEN);		// Wlaczenie nadajnika i odbiornika,  brak bitu parzytosciu
    }
    
    /* Transmisja przez bluetooth */
    void USART_Transmit( uint8_t data )
    {
    	while ( !( UCSRA & (1<<UDRE)) )		// Czekanie na wolny bufor zapisu
    		;
    	UDR = data;							// Przeslanie danych
    }
    
    /* Odczyt przez bluetooth */
    uint8_t USART_Receive( void )
    {
    	while ( !(UCSRA & (1<<RXC)) )		// Czekanie na dane do odczytu
    		;
    	return UDR;							// Zwrot odczytanych danych
    }
    
    /* Inicjalizacja BTM-222 przez komendy AT */
    void BTM_Init()
    {
    	USART_Transmit('A');				
    	delay_ms(25);
    	USART_Transmit('T');
    	delay_ms(25);
    	USART_Transmit('P');
    	delay_ms(25);
    	USART_Transmit('0');
    	delay_ms(25);
    	/*USART_Transmit('=');
    	delay_ms(25);
    	USART_Transmit('1');
    	delay_ms(25);
    	USART_Transmit('2');
    	delay_ms(25);
    	USART_Transmit('3');
    	delay_ms(25);
    	USART_Transmit('4');
    	delay_ms(25);*/
    	USART_Transmit(0x0D);
    	delay_ms(25);
    
    	USART_Transmit('A');				// Wylaczenie echa
    	delay_ms(25);
    	USART_Transmit('T');
    	delay_ms(25);
    	USART_Transmit('E');
    	delay_ms(25);
    	USART_Transmit('0');
    	delay_ms(25);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    	
    	USART_Transmit('A');				// Wylaczenie kontroli przeplywu
    	delay_ms(5);
    	USART_Transmit('T');
    	delay_ms(5);
    	USART_Transmit('C');
    	delay_ms(5);
    	USART_Transmit('0');
    	delay_ms(5);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    	
    	USART_Transmit('A');				// Wylaczenie kodow wynikowych
    	delay_ms(5);
    	USART_Transmit('T');
    	delay_ms(5);
    	USART_Transmit('Q');
    	delay_ms(5);
    	USART_Transmit('1');
    	delay_ms(5);
    	USART_Transmit(0x0D);
    	delay_ms(25);
    }
    
    void SPI_master_init() 
    { 
    	DDRB|=(1<<DDB5)|(1<<DDB7);						// Ustawienie MOSI i SCK jako wyjscia a MISO jako wejscie
    	SPCR =(1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR1);	// Wlaczenie SPI, ustawienie master, zegar /64
    	SPCR &= ~_BV(CPOL);								//CPHA=1,CPOL=0
    	PORTB|=_BV(PB4);								//wlaczenie lini ss na stan wysoki
    } 
    
    char SPI_Transmit_Receive(char cData)
    {
    	PORTB &= ~_BV(PB4);								//wlaczenie lini ss na stan niski
    	delay_ms(20);
    	SPDR = cData;									// start transmisji 
    	while(!(SPSR & (1<<SPIF)));						//czekanie na odbiór 
    	delay_ms(20);
    	PORTB|=_BV(PB4);								//wlaczenie lini ss na stan wysoki
    	return SPDR;
    }
    
    void SONAR_Init()
    {
    	char a;
    	delay_ms(120);
    	SPI_Transmit_Receive(0xF0);
    	SPI_Transmit_Receive(0xF0);
    	SPI_Transmit_Receive(0xF0);
    	a = SPI_Transmit_Receive(0xF0);
    	if(a==10){
    		PORTB &= ~_BV(PORTB1);						//zapalenie diody żółtej
    	}
    	else{
    		PORTB &= ~_BV(PORTB3);						//zapalenie diody czerwonej
    	}
    }
    
    
    
    int main(void)
    {
    	//USART_Init(MYUBRR);					// Inicjalizacja USART
    	USART_Init();						// Inicjalizacja USART
    	BTM_Init();							// Inicjalizacja BTM
    	DDRB|=_BV(PB3);						//wyjście dioda czerwonej
    	DDRB|=_BV(PB1);						//wyjście dioda żółta
    	DDRB|=_BV(PB2);						//wyjście dioda zielona
    	PORTB |= _BV(PORTB3);				//zgaszenie diody czerwonej	
    	PORTB |= _BV(PORTB1);				//zgaszenie diody żółtej
    	PORTB &= ~_BV(PORTB2);				//zapalenie diody zielonej
    	DDRC &= ~_BV(PC0);					//wejście przycisk S3
    	PORTC|=_BV(PC0);					//podciągnięcie wejścia do góry
    	
    	//SONAR_Init();						// Inicjalizacja sonaru
    	while(1)
        {
    		//PORTB |= _BV(PORTB1);			//zgaszenie diody żółtej
    		//if(USART_Receive() == 'B') {	
    			//PORTB &= ~_BV(PORTB1);		//zapalenie diody żółtej
    		//}			
    		
    		USART_Transmit('A');
    		/*if(USART_Receive() == 'A') {	
    			PORTB &= ~_BV(PORTB1);		//zapalenie diody żółtej
    		}*/
    		delay_ms(100);
    		
            //TODO:: Please write your application code 
        }
    }

    Przesyłam również schemat bo może tam się kryje błąd:
    [Atmega32][c][BTM222][USART]
    Proszę o dalszą pomoc.

    ps. Wiem że miałem wyłączyć funkcje BTM_init, ale coś mnie podkusiło, a teraz to jedyna droga dostania się do BTM-a:(
  • #7 10152746
    Sparrowhawk
    Poziom 22  
    Rozumiem, że masz dwa moduły BTM-222? Jeden przez RS232 podłączony do PC, a drugi do USART ATMEGI? Czy też jeden moduł BTM, a w komputerze jakiś moduł bluetooth?

    Jeśli chcesz sprawdzić działanie USART, to połącz w ATMEGA nóżki RXD i TXD. A funkcja, która będzie odbierać dane, niech wyrzuca je na PORT.
  • #8 10152932
    mirekk36
    Poziom 42  
    mijadzi --> czy ty czytasz to co się do ciebie pisze, czy tylko piszesz sam i nic nie czytasz ?


    Przecież masz w moim poście wyżej opisane babole jakie robisz - cały ten twój BTM_init() jest do wyrzucenia z kodu programu (co do jednej linijki - bo BTM nie wymaga ŻADNEJ inicjalizacji). Po co ty w ogóle to robisz ? problemy na własne życzenie.
  • #9 10155823
    mijadzi
    Poziom 10  
    Mam jeden BTM-222 a na komputerze mam bluetooth. Używam teraz BTM_init bo przez komputer nie mogę się połączyć przez BTM. Jest jakiś sposób by przywrócić ustawienia fabryczne na BTM-ie?
  • #10 10155853
    mirekk36
    Poziom 42  
    Chłopie - jak byś poczytał kilka tematów o BTM-222 na elektrodzie to szybko byś się dowiedział że od strony kompa przez BT NIGDY W ŻYCIU nie będziesz w stanie wydawać poleceń AT.

    To jest możliwe tylko poprzez podłączenie BTM-222 do komputera za pomocą jakiejś przejściówki np USB/RS232 TTL - gdzie do kompa podłączasz fizyczne nogi Rx oraz TX modułu i dopiero wtedy można z terminala wydawać polecenia AT u ustawić raz a porządnie moduł a nie niszczyć go tymi twoimi INIT'ami.
REKLAMA