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

rs232 +at90s2313 +siemens c45

zulek87 05 Cze 2009 01:10 2837 6
  • #1 6617761
    zulek87
    Poziom 10  
    Witam!

    Mam taki oto problem. Gdy chcę za pomocą uC skomunikować się z c45, to nie zawsze przyjmie on komendę AT, ponadto nigdy mi nie odpowiada:( dla przykładu:
    na komendę UART_sendstring("ATD+48886160558\n\r"); telefon odpowiada, próbuje zestawić połączenie, ale tego nie robi, bo nie jest to tryb voice.
    na komendę UART_sendstring("ATD+48886160558;\n\r"); już nie odpowiada :(
    tak samo przyjmie komendę AT^SDLD kasując ostatnio wybrany numer, ale na zwykłą komendę ATE0 nie odpowie...

    pisząc program wzorowałem się na Link

    Podaję kod:

    // Sterownie diodą LED podłączoną do dowolnej linii mikrokontrolera
    // za pomocą dowolnego znaku odebranego z portu szeregowego 
    // mikrokontrolera i wysyłanie jej stanu na port szeregowy
    
    #include <avr/io.h>                // dostęp do rejestrów
    #include <string.h>
    #include <util/delay.h>
    
    
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 
    
    // Zmieniając poniższe definicje można dostosować program do potrzeb
    
    #define F_CPU                4000000ul         // częstotliwość zegara w Hz
    #define UART_BAUD        19200ul                // prędkość transmisji bit/s
    
    #define LED_PORT        PORTD                // port diody LED
    #define LED_BIT                4                // bit diody LED
    
    #define DDR(x) _SFR_IO8(_SFR_IO_ADDR(x)-1) // adr. rej. kier. PORTx
    #define PIN(x) _SFR_IO8(_SFR_IO_ADDR(x)-2) // adr. rej. wej. PORTx
    
    #define LED_PORT_O        LED_PORT             // rejestr wyjściowy
    #define LED_PORT_D        DDR(LED_PORT)   // rejestr kierunkowy
    #define LED_PORT_I        PIN(LED_PORT)   // rejestr wejściowy
    
    #define UART_CONST        (F_CPU/(16ul*UART_BAUD)-1)
    
    // _UCR_
    
    #ifdef        UCR
    #define _UCR_        UCR
    #endif
    
    #ifdef        UCSRB
    #define _UCR_        UCSRB
    #endif
    
    #ifdef        UCSR0B
    #define _UCR_        UCSR0B
    #endif
    
    // _USR_
    
    #ifdef        USR
    #define _USR_        USR
    #endif
    
    #ifdef        UCSRA
    #define _USR_        UCSRA
    #endif
    
    #ifdef        UCSR0A
    #define _USR_        UCSR0A
    #endif
    
    #define MAX_ODP_AT 15
    char at_temp[MAX_ODP_AT];
    
    // Definicje funkcji
    
    // inicjalizacja portu szeregowego
    void UART_init(void) 
    {
    	UBRR = (unsigned char)UART_CONST;         // ustaw prędkość transmisji 
    	_UCR_ = _BV(RXEN)|_BV(TXEN);                // załącz tx, rx
    }
    
    // wysyła znak podany jako parametr na port szeregowy
    void UART_putchar (char c)
    {
    	UDR = c;                                // wpisz c do rejestru UDR
    	loop_until_bit_is_set(_USR_,TXC);        // czekaj na zakończenie transmisji
    	sbi(_USR_,TXC);                                // ustaw bit TXC w rej. USR
    	
    }		
    
    // odbiera znak z portu szeregowego i zwraca go jako wartość funkcji
    char UART_getchar (void)
    {
    	
    	loop_until_bit_is_set(_USR_,RXC);        // czekaj na zakończenie odbioru
    	cbi(_USR_,RXC);                                // skasuj bit RXC w rej. USR
    	return UDR;                                // zwróć zawartość rejestru UDR
    }
    
    
    void UART_sendstring(char *string)
    {
    	int dlugosc;
    	dlugosc = strlen(string);
    		
    	for ( int i=0 ; i<dlugosc ; i++)	
    		UART_putchar(*(string+i));
    }
    
    
    int main(void)                        // program główny
    {
    	UART_init();                        // inicjalizacja portu szeregowego
    
    	sbi(LED_PORT_D,LED_BIT);        // użyj linii jako wyjścia
    
    	cbi(LED_PORT_O,LED_BIT);        // zgaś diodę LED
    	
    	char znak;	
    	int i =0;
    
    	while(1)
    	{
    
    	UART_sendstring("ATD48886150669\n\r");
    	
    	znak = UART_getchar();
    	i =0;
    	
    	while(1)
    
    	{
    		
    		if (i == MAX_ODP_AT) break;		
    
    		if (znak != 13)
    			at_temp[i++] = znak;
    		else 
    		{
    				at_temp[i] = '\0';
    				break;
    		}
    		
    		znak = UART_getchar();
    	}
    	
    	UART_sendstring(at_temp);
    
    	}
    
    }


    Połączenie pc-uC na rsie jest bezproblemowe... w terminalu wszystko działa. Program jest napisany na poczekaniu, tzn własne funkcje (aż 2). Połączenie telefon - pc działa bez problemu, na każdą komendę w terminalu telefon odpowiada. Dodatkowo podczas połączenia uC - c45 komenda UART_sendstring("ATD48886150669\n\r"); wykonuje się tylko raz.... zatem tak jakby telefon nie odpowiedział komendą zakończoną '\n' :(
  • #2 6622045
    zulek87
    Poziom 10  
    Piszę posta pod postem, żeby odświeżyć temat....

    Czy przyczyną może być to, że podczas połączenia c45 - uC nie mam w torze RXD ani TXD konwertera napięć? W książce odnośnie modułów GSM znalazłem, że na telefonie powinno być ok 2,5 V a jak ja mierzyłem, to miałem ok 4V, może dlatego sygnały nie są jednoznaczne i niektóre komendy potrafi odczytać a niektórych nie?
  • #4 6630788
    zulek87
    Poziom 10  
    you made my day...

    Mam kolejne pytanie.

    Dlaczego jak sprawdzam mój program pomiędzy uC a PC to on działa (w terminalu piszę sobie komendy i program je czyta oraz je wyświetla), a pomiędzy uC a c45 już nie? Mam na myśli to, że nie umiem odczytać tego, co telefon odpowie na zadaną komendę. Nawet najprostszy program nie chce działać, czyli jak chcę odczytać jeden znak wysłany przez telefon. Program stoi w miejscu i nie chce przejść dalej...

    int main(void)                        // program główny
    {
    	UART_init();                        // inicjalizacja portu szeregowego
    
    	sbi(LED_PORT_D,LED_BIT);        // użyj linii jako wyjścia
    
    	cbi(LED_PORT_O,LED_BIT);        // zgaś diodę LED
    	
    	char znak;	
    
    	UART_sendstring("ATE0\x0D"); 
    
    	while(1)
    	{
    
    	sbi(LED_PORT_O,LED_BIT);          // zapal diodę LED
    
    	UART_putchar(0x0D);
    	wait(5);
    
    	UART_sendstring("ATx0D"); 
    	
    	znak = UART_getchar();
    	
    	wait(3);
    
    	i =0;
    
    	if (znak != 0x0D)
    		cbi(LED_PORT_O,LED_BIT);        // zgaś diodę LED
    		
    			
            wait(10);
    
    	}
    
    }


    Program wchodzi do funkcji UART_getchar(); i koniec.
    Funkcja ta jest zdefiniowana w pierwszym poście ;]
  • #5 6634883
    zulek87
    Poziom 10  
    tak jak wcześniej, odświeżam, widzę po liczniku odsłon, że nikt nie zagląda :(


    EDIT:

    Zmieniłem zasilanie z USB na stabilizowane z zasilacza i zasiliłem płytkę napięciem 7,5 V, po czym program zaczął działać.
    Nie wchodzi mi do pętli i nie zostaje w niej na cały czas. Jak długo po wysłaniu komendy at powinienem czekać na odpowiedź telefonu? Jakie dać opóźnienia?


    Dziękuję za pomoc ;-)
  • Pomocny post
    #6 6654948
    shootky
    Poziom 15  
    Witam
    Mi modem na AT odpowiada natychmiast.
    Czy pamiętałeś aby wyłączyć echo? Modem na komendę AT<13><10> bez wyłączonego echa powinien odpowiedzieć znakami:
    A - 61
    T - 74
        0D znaki powrotu karetki i nowej lini
        0A
        0D znaki powrotu karetki i nowej lini
        0A
    O  4F
    K  4B
        0D znaki powrotu karetki i nowej lini
        0A
    


    A gdy wyłączysz echo ATE0 to

    0D
        0A
    O   4F
    K   4B
       0D
       0A
    


    To drugie znacznie łatwiejsze do analizy, prawda?
  • #7 6768727
    zulek87
    Poziom 10  
    Po dłuższej przerwie wróciłem do tego.

    Dzięki @shootky, gdyby nie to, ze podałeś mi jak odpowiada Twój modem to bym tego nie zrobił... moja funkcja kończyła się warunkiem na wystąpienie znaku <CR> czyli odpadała na samym początku... zrobiłem funkcję, która na sztywno czyta mi 6 znaków i ładnie śmiga... na zadaną komendę AT odpowiada OK. Ponadto trzeba czytać wszystko co telefon odpowiada, jak się tego nie zrobi, to są śmieci w buforze.

    Jeszcze raz dziękuję :)
REKLAMA