Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8][C][SE T630] odbiór danych

tptak 07 Jun 2008 17:45 1690 5
  • #1
    tptak
    Level 2  
    Witam
    Robię projekt z Techniki mikroprocesorowej. Docelowo ma to być, jak to my nazwaliśmy: smsos, który ma odebrać smsa, przeanalizować treść i odesłać odpowiedź.
    Jest to układ z Atmegą8, kwarcem 11059200Hz.
    Pin trzeci(Tx) jest połączony bezpośrednio z komórką i przez max 232 (jeśli zewrę) z wyjściem coma, tak że mogę odpierać na kompie przez minicoma to, co jest wysłane do komórki. Mogę wysłać bez problemu smsa, mogę puścić dzwonka (wykorzystuję AT Commands i SMS text mode czy jak mu tam).
    Mam problem z odbiorem - pin drugi(Rx) był do wczoraj połączony bezpośrednio z komórką, ale odbierałem tylko AT gdy wysłałem AT, OK gdy wysłałem OK, przy większych poleceniach nic nie było zwracane.
    Wczoraj prowadzący zasugerował, że to może być wina tego, że 3,3V to zbyt małe napięcie żeby doszło do skutecznej komunikacji i zaproponował mi kilka rozwiązań, w tym wykorzystanie właśnie max3232 i wolnych pinów na max 232 (najpierw skaluję z 0-3,3V do napięć dla rs, potem z nich do 0-5V). Wygląda na to, że echo działa poprawnie (nakazałem odczytywanie po każdym wysłanym znaku pierwszego znaku z wejścia), bo wypisuje wszystkie komendy z powrotem i każdy znak na wyjściu pojawia się tylko jeden raz, ale ciągle brak odpowiedzi na nie - kompletnie niczego nie dostaję.
    Zauważyłem też, że przy wysyłaniu smsa nie mogę kontrolować wysyłanej treści, inaczej sms nie zostaje wysłany.
    Czy ktoś miał już podobne problemy? Poniżej prezentuję kod:
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <string.h>
    #include <stdlib.h>
    #include <inttypes.h>
    
    #define FOSC 11059200
    #define BAUD 9600
    #define MYUBRR 71
    
    
    
    //funkcje do obslugi komorki
    void mobile_init();
    void mobile_ring(char* number);
    void mobile_send(char* number, char* text);
    
    
    void USART_Init( unsigned int ubrr);
    unsigned char USART_Receive( void ); //odbior znaku
    void USART_Transmit( unsigned char data ); // wyslanie znaku
    void USART_println(unsigned char* string); //wyslanie linii zakonczonej przez \r\n z kontrolą przesłania
    void USART_print(unsigned char* string); //wyslanie stringa z kontrolą przesłania
    void USART_printlnnc(unsigned char* string); //wyslanie linii zakonczonej przez \r\n bez kontroli przesłania
    void USART_printnc(unsigned char* string);//wyslanie linii  bez kontroli przesłania
    
    char* USART_read( void ); //zczytanie z wejścia linii
    void USART_Flush( void ); //opróżnienie bufora wejścia
    unsigned char *strunsign(char *str); //konwersja stringa z char do unsigned char
    
    //funkcje do obslugi diodki na PB1
    void LED_Init();
    void toggle_led();
    void blink_led(int times);
    void delay_ms(uint16_t ms);
    
    int main( void ) {
    
    	char* line; //zmienna do wykomentowanych odczytow
    	LED_Init();
    	
    	USART_Init ( MYUBRR );
    	mobile_init();
    	USART_Flush();
    //	sei();
    	
    //	blink_led(2);
    	//wywoluje polaczenie z moim telefonem
    	//mobile_ring("XXXXXXXXX");
    
    	//wysyla smsa
    ///	mobile_send("+48XXXXXXXXX", "test");
    	USART_Flush();
    
    //	tu chcialem wczytac wejscie po napisaniu AT, przed kontrola wyslania znakow pierwsza proba zczytywala AT a pozostale tylko dawaly znak nowej linii po kontroli zadna nic nie zwracala
    
    	USART_println(strunsign("AT"));
    	delay_ms(500);
    //	USART_println(strunsign(USART_read()));
    //	delay_ms(500);
    //	USART_println(strunsign(USART_read()));
    //	delay_ms(500);
    //	USART_println(strunsign(USART_read()));
    //	delay_ms(500);
    	
    	while(1) {
    	}
    }
    
    void mobile_init() {
    	USART_println(strunsign("AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0"));
    	delay_ms(200);
    	USART_println(strunsign("at+cnmi=2,1,0,0,0"));
    	delay_ms(200);
    	
    	USART_println(strunsign("at+cpms=\"ME\",\"ME\",\"ME\""));
    	delay_ms(200);
    	USART_println(strunsign("at+cmgf=1"));
    	delay_ms(200);
    }
    
    void mobile_ring(char* number) {
    	char tmp[20];
    	char i;
    	strcpy(tmp,"ATD");
    	i=3;
    	while(*number) {
    		tmp[i]=*number;
    		number++;
    		i++;
    	}
    
    	tmp[i]=';';
    	tmp[i+1]='\0';
    	delay_ms(150);
    	USART_println(strunsign(tmp));
    	delay_ms(8000);
    
    	//konczy polaczenie
    	USART_println(strunsign("ATZ;"));
    }
    
    void mobile_send(char* number, char* text) {
    	char num[30], txt[162];
    	int i=0;
    	strcpy(num, "AT+CMGS=\"");
    	i=strlen(num);
    	
    	while(*number) {
    		num[i]=*number;
    		number++;
    		i++;
    	}
    	num[i]='\"';
    	num[i+1]='\0';
    	i=0;
    	strcpy(txt, text);
    	i=strlen(text);
    	if(i>160) i=160;
    	txt[i]=26;
    	txt[i+1]='\0';
    
    	delay_ms(600);
    	USART_printlnnc(strunsign(num));
    	delay_ms(600);
    	USART_printnc(strunsign(txt));
    	delay_ms(600);
    	USART_printlnnc(strunsign(""));
    }
    
    void USART_Init( unsigned int ubrr) {
    	/* Set baud rate */
    	UBRRH = (unsigned char)(ubrr>>8);
    	UBRRL = (unsigned char)ubrr;
    	/* Enable receiver, transmitter //and the interrupts */
    	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);//;//
    	/* Set frame format: 8 data, 1 stop bit */
    	UCSRC = (1<<URSEL)|(3<<UCSZ0);
    }
    
    void USART_Flush( void ) {
    	unsigned char dummy;
    	while ( UCSRA & (1<<RXC) ) dummy = UDR;
    }
    
    
    void USART_Transmit( unsigned char data ) {
    	/* Wait for empty transmit buffer */
    	while ( !( UCSRA & (1<<UDRE)) )
    		;
    	/* Put data into buffer, sends the data */
    	UDR = data;
    	
    	/* Do nothing until transmission complete flag set */
    //	while ((UCSRA & (1 << TXC)) == 0) {}; //NIEEFEKTYWNE!
    }
    
    unsigned char USART_Receive( void ) {
    	/* Wait for data to be received */
    	while ( !(UCSRA & (1<<RXC)) )
    		;
    	/* Get and return received data from buffer */
    	return UDR;
    }
    
    void USART_println(unsigned char* str) {
    	unsigned int i=0;
    	char c='\0';
    	USART_Flush();
    	while(str[i]!='\0' && str[i]!='\n' && str[i]!='\r') {
    		while(c!=str[i]) {
    			c='\0';
    			USART_Transmit(str[i]);
    			c = USART_Receive();
    		}
    		i++;
    	}
    	c='\0';
    	while(c!='\r') {
    		USART_Transmit('\r');
    		c = USART_Receive();
    	}
    }
    
    void USART_print(unsigned char* str) {
    	unsigned int i=0;
    	char c='\0';
    	USART_Flush();
    	while(str[i]!='\0' && str[i]!='\n' && str[i]!='\r') {
    		while(c!=str[i]) {
    			USART_Transmit(str[i]);
    			c = USART_Receive();
    		}
    		i++;
    	}
    }
    
    void USART_printlnnc(unsigned char* str) {
    	unsigned int i=0;
    	while(str[i]!='\0' && str[i]!='\n' && str[i]!='\r') {
    		USART_Transmit(str[i++]);
    	}
    	USART_Transmit('\r');
    	USART_Transmit('\n');
    }
    
    void USART_printnc(unsigned char* str) {
    	unsigned int i=0;
    	while(str[i]!='\0' && str[i]!='\n' && str[i]!='\r') {
    		USART_Transmit(str[i++]);
    	}
    }
    
    char* USART_read( void ) {
    	unsigned int j=1;
    	unsigned int unit_size=10;
    	unsigned int i=0;
    	unsigned tmp_char;
    	char *str;
    	
    	str = malloc(sizeof(/*unsigned */char)*j*unit_size);
    	do {
    		tmp_char = USART_Receive();
    		if (tmp_char!='\0' && tmp_char!='\n' && tmp_char!='\r')
    			str[i]=(char)tmp_char;
    		else {
    			str[i]='\0';
    			break;
    		}
    		
    		i++;
    		
    		if (i==j*unit_size) {
    			j++;
    			str = realloc(str, sizeof(unsigned char)*j*unit_size);
    		}
    		
    	} while(tmp_char!='\0' && tmp_char!='\n' && tmp_char!='\r');
    	
    	USART_Transmit('\n');
    	USART_Transmit('\r');
    	
    	
    	return str;
    }
    
    char* USART_read_loud( void ) {
    	unsigned int j=1;
    	unsigned int unit_size=10;
    	unsigned int i=0;
    	unsigned tmp_char;
    	char *str;
    	
    	str = malloc(sizeof(char)*j*unit_size);
    	do {
    		tmp_char = USART_Receive();
    		if (tmp_char!='\0' && tmp_char!='\n' && tmp_char!='\r')
    			str[i]=(char)tmp_char;
    		else {
    			str[i]='\0';
    			break;
    		}
    		USART_Transmit(tmp_char);
    		
    		i++;
    		if (i==j*unit_size) {
    			j++;
    			str = realloc(str, sizeof(unsigned char)*j*unit_size);
    		}
    		
    	} while(tmp_char!='\0' && tmp_char!='\n' && tmp_char!='\r');
    	
    	USART_Transmit('\n');
    	USART_Transmit('\r');
    	
    	return str;
    }
    
    unsigned char *strunsign(char *str) {
    	unsigned int i=0;
    	unsigned char *nstr;
    	nstr=malloc(sizeof(unsigned char)*(strlen(str)+1));
    	while(str[i]!='\0') {
    		nstr[i] = (unsigned char) str[i];
    		i=i+1;
    	}
    	nstr[i]='\0';
    	return nstr;
    }
    
    void delay_ms(uint16_t ms) {
          uint16_t bla;
          while(ms--) {
                bla = 1000;
                while(bla--);
          }
    }
    
    
  • #2
    Bigfoot
    Level 25  
    tptak wrote:
    odbierałem tylko AT gdy wysłałem AT, OK gdy wysłałem OK


    Po wyslaniu AT i zatwierdzeniu <CR> powinienes otrzymac OK. Dzieje sie tak? Ty nigdy OK nie wysylasz - OK zwraca modem. Moze to co "odebrales" to po prostu lokalne echo Twojego programu terminala szeregowego - bedzie pojawialo sie zawsze, niewazne co wpiszesz. Odlacz telefon zupelnie i sprawdz wtedy - co sie dzieje? Jest tez komenda (nie pamietam ktora) mowiaca o echu - co z nia?

    tptak wrote:
    przy wysyłaniu smsa nie mogę kontrolować wysyłanej treści


    Mozesz uscislic?

    BF
  • #3
    tptak
    Level 2  
    Dzięki za odpowiedź

    Tutaj posprzątałem kod nieco, wysyłałem wcześniej OK.
    Miałem w nim:
    USART_println("OK")

    To wysyła na wyjście sekwencję znaków:
    OK\r\n
    wtedy byłem w stanie odczytać OK
    Tak samo było gdy pisałem AT, a nie OK - tzn też odczytałem AT.
    Ani razu po wysłaniu AT nie otrzymałem OK - jedynie AT.

    Jeśli dobrze rozumiem pytanie o komendę mówiącą o echu (rozumiem że chodzi Ci o tą, która ponawia wysłanie znaku do chwili gdy taki znak odczyta z wejścia) - gdy ją wykorzystuję, normalnie wypisuje, co wskazuje na to, że odczytuję dokładnie te znaki, które są wysłane, czyli echo telefonu działa poprawnie.

    po odłączeniu telefonu sprawdzę za jakiś czas, jak znów rozłożę to cudo na biurku ;] Domniemam jednak, że zawiesi się po wysłaniu pierwszego znaku, bo nie dostanie niczego z powrotem


    Mój program terminala szeregowego (minicom) nie odsyła echa, a nawet jeśliby odsyłał, nie dotrze to do atmegi, ponieważ wejście atmegi jest od max232 odseparowane i odczytuje tylko sygnał z telefonu.


    Co do kontroli wysyłanej treści - chodziło mi o to, że jeśli wysyłam smsa i wykorzystuję do jego wysyłania funkcje USART_print i USART_println, które nie wyślą kolejnego znaku, dopóki nie odbiorą z wyjścia znaku wysłanego, a jeśli odbiorą co innego, mają powtórzyć ostatnio wysyłany znak, sms nie zostaje wysłany. Muszę wykorzystywać funkcje USART_printnc i USART_printlnnc, które ostatnio wysłanego znaku nie sprawdzają.
  • #4
    Fyszo
    Level 37  
    Sonyeriscssony często nie łaczą z wtykiem (zabrudzone) - proponuję przeczyszczenie złącza systemowego. Dla testów zalecane również posiadanie kabelka DCU11 i testowanie na terminalu w PC.
  • #5
    tptak
    Level 2  
    Co prawda nie mam kabelka DCU11, ale zwykły kabel szeregowy umożliwia komunikację szeregową z komputerem, sprawdzałem na terminalu. Również styki były sprawdzane, przy czym dziwnie byłoby, gdyby się okazało, że to wina wtyków, skoro po każdym wysłanym znaku do mikroprocesora wraca dokładnie ten sam znak.

    EDIT

    Po odpięciu komórki, zgodnie z oczekiwaniami, wysyłany jest znak A i na tym poprzestaje - oczekuje na zwrot jakiegoś znaku z wejścia, ale nic nie otrzymuje
  • #6
    tptak
    Level 2  
    EDIT2: wygląda na to, że sobie poradziłem jakoś. Stworzyłem bufor wejściowy (na avr freaks nazywali to ring buffer, wiecie, tablica do której się wpisuje na okrągło aż do zapełnienia), uruchomiłem przerwania i odczytuję z bufora. Odczytałem już smsa, po AT jest odpowiedź OK, takie tam ;]
    Dziękuję za chęci, temat do zamknięcia chyba.
    Jak skończę, postaram się umieścić w "mój pierwszy projekt" ;]