pmk_1969 Ответов: 2

GSM модем и PIC16F877A


уважаемый господин,

Я связался с GSM-модемом (SIMCOMM300) от PIC16F877A и могу нормально отправлять и принимать SMS/звонки. Но, когда я выдаю команду AT+CLCC, когда GSM получает звонок, чтобы узнать номер вызывающего абонента, я могу получить ответ на команду "AT+CLCC", а также я могу обработать все команды, за которыми следует "AT+CLCC". Но проблема в том, что я не могу обработать еще один входящий звонок (звонок) или SMS. Программа зависает. Я не знаю, в чем проблема. Итак, я даю вам код здесь для вашего удобства. ПЛ идти беспересадочный код и поправьте меня, если есть какие-либо ошибки. Я буду очень благодарен и скромен всем, кто окажет мне помощь. Заранее благодарю.
#include <stdio.h>
#include <htc.h>
#include "usart.h"
#include "lcd.h"
#include "string.h"

__CONFIG(HS & WDTDIS & UNPROTECT &  LVPDIS);

unsigned char gsmInput[60];
unsigned int i=0;
unsigned int lenOfGSMInput = 0;

bit OK;
bit Error;
bit Ring;

void showGSM_DATA(char GSM_DATA[]){ //to show the GSM OUTPUT after eliminating the chars '\r' and '\n'
    
    if (strcmp(GSM_DATA, "OK") == 0){ 
        OK = 1;
    }
    else if (strcmp(GSM_DATA, "ERROR") == 0){
            Error = 1;
    }
    else if (strcmp(GSM_DATA, "RING") == 0){
       
        Ring = 1;
        
        GSM_DATA[0] = '\x00';
        puts("AT+CLCC");
        putch(0x0D);
        
    }
    else{
        lcd_clear();
        lcd_goto(0);
        lcd_puts(GSM_DATA);
    }
  GSM_DATA[0] = '\x00';
 
} // end function showGSM_DATA

void main(int argc, char* argv[]){

	unsigned char input;
       
	INTCON=0;	// purpose of disabling the interrupts.
    
	lcd_init(); // initiate LCD
	
	init_comms();	// set up the USART - settings defined in usart.h
    			    
    puts("ATE0");
    putch(0X0D);
    
    puts("AT+CMGF=1");
    putch(0X0D);
    
    while(1){
		               
        input = getch();	// read a response from the GSM
        
        switch(input){
            
            case '\x0A': // if line feed detected in the GSM output i.e. '\n'
                        break;
            case '\x0D': // if carriage return detected i.e. '\r'
                        gsmInput[i] = '\x00';
                        
						lenOfGSMInput = strlen(gsmInput);
                        if (lenOfGSMInput > 0){
                            i = 0;
                            lenOfGSMInput = 0;
                            showGSM_DATA(gsmInput);
                        }
                        break;
            case '\x3E': // if greater-sign (in order to send SMS)
                        break;
            
        default: // if characters received
                gsmInput[i] = input;
                i++;
                break;
        }//end brace for switch
	} //end brace for while loop
}//end brace for main</htc.h></stdio.h>

Toniyo Jackson

Добавлен предварительный тег для кода.

pmk_1969

спасибо. Я неопытен для форума. Еще раз спасибо.

Toniyo Jackson

Добро пожаловать

2 Ответов

Рейтинг:
2

Albert Holguin

Проверять GSM_DATA[] потому что с кодом как есть, если там окажется лишнее пустое место, strcmp() не приведет к 0 (т. е. если в начале строки есть пустое место).


pmk_1969

Я проверил вывод GSM_DATA. получены правильные данные. Это прекрасно работает, если я ничего не делал, кроме как просто отображал результат. Но если я начну проверять GSM_DATA, то только разовая проверка будет выполнена и просто сидит. Я должен перезагрузить устройство, чтобы обработать следующую команду. Я не знаю, почему?

Следующий код работает нормально:

void showGSM_DATA(char GSM_DATA[]){ //чтобы показать выход GSM после устранения символов '\r' и '\n'

if (strcmp(GSM_DATA, "OK") == 0){
Ок = 1;

if (strcmp(NextCmd, "CMGF") == 0){
strcpy(NextCmd, "клип");
ставит("AT+CMGF=1");
путч(0X0D);

}
if (strcmp(NextCmd, "CLIP") == 0){
*NextCmd = 0;
ставит("AT+CLIP=1");
путч(0X0D);

}
вернуть;
}

if (strcmp(GSM_DATA, "ERROR") == 0){
Ошибка = 1;
*GSM_DATA = 0;
вернуть;
}
if(strlen(GSM_DATA) > 6){

lcd_clear();
lcd_goto(0);
lcd_puts(GSM_DATA);
}
*GSM_DATA = 0;
вернуть;

} // конечная функция showGSM_DATA

Но следующий код выполняется только один раз и сидит.

(Только что я добавил функцию подстроки):

пустота подстрока(реализация начнется, реализация стоп, чар ГРЦ[]){

int j = 0;

если (start >= stop){

вернуть;
}

Для(я = начать;я &л; остановить; я++){
substringOfInput[j] = src[i];
Дж++;
}

substringOfInput[j] = '\x00';
lcd_clear();
lcd_goto(0);
lcd_puts(substringOfInput);
*src=0;
*substringOfInput=0;
j=0;
вернуть;
}

if(strlen(GSM_DATA) > 6){
подстрока(0,5,GSM_DATA);
//lcd_clear();
//lcd_goto(0);
//lcd_puts(GSM_DATA);
}

pmk_1969

спасибо Альберту Ольгину.

Я решил эту проблему. Как вы уже сказали, я начал проверять GSM_DATA шаг за шагом. Я нашел проблему. Я объявил переменную i глобальной переменной. Я удалил это и объявил внутри цикла for.

То есть проблема здесь:

Для(я = начать;я &л; остановить; я++){

Просто я модифицировал следующим образом:

для(тип int я = начать;я &л; остановить; я++){

Теперь все работает нормально.

Еще раз спасибо Мистер Альберт Ольгин

Albert Holguin

рад, что ты нашел свою проблему... у вас есть очень много глобальных переменных, я бы рекомендовал попытаться сократить это, на самом деле в них нет необходимости, кроме того... вы опубликовали этот вопрос как C не C++, объявление переменной в цикле as for(int i;...;...) не является допустимым оператором C, все переменные должны быть объявлены в начале функции

pmk_1969

Я не могу отличить C++ от C. потому что я новичок в C и C++. Он хорошо работает на компиляторе PIC(HI-TECH C PRO Compiler / MPLAB IDE v8.63). Еще раз большое спасибо.

Рейтинг:
1

CPallini

То default код выглядит опасным: вы уверены i не дотянется 60 таким образом, переполнение буфера?


pmk_1969

Привет Cpallini,

Я изменил код следующим образом, чтобы ограничить символы. Но результат все тот же.

по умолчанию: // если символы получены
если (i < 13){
gsmInput[i] = вход;
я++;
}

перерыв;

pmk_1969

Привет Cpallini,

Я решил эту проблему. Спасибо Вам за оказанную помощь.