我正在编写代码来制作一个通过短信打开微控制器端口的模块。我正在使用Pic16F88和Sim900模块,正在mplab X和XC8中编程。它在Proteus中工作,但在电路中没有,我已经解决了一些电容器的功耗问题,因此我认为问题出在代码中。也许模块无法将'\ r'字符识别为回车符?
/*
* File: ContGsmMain.c
* Author: camil
*
* Created on 28 de enero de 2020, 22:08
*/
// CONFIG1
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CCPMX = RB0 // CCP1 Pin Selection bit (CCP1 function on RB0)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// CONFIG2
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal External Switchover mode disabled)
#define _XTAL_FREQ 8000000
#include <xc.h>
#include "pic16f88.h"
#include "uart.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//Funcion retorna la posición donde comienza la cadena seleccionada
int existe(char linea[], char busq[]);
void main(void) {
TRISA=0; // Program Init
TRISB=0x04;
PORTA=0;
PORTB=0;
OSCCON = 0b01111100;
UART_Init(9600);
__delay_ms(200);
int porta[8]={0,0,0,0,0,0,0,0}; //Variable declaration
char buffer[80]="";
char *buff;
char textbuf[10]="";
int i=0,e=0;
buff=buffer;
RA3=1; //Module Init
__delay_ms(3000);
RA3=0;
UART_Write_Text("AT+CMGF=1\r");
__delay_ms(100);
UART_Write_Text("AT+IPR=9600\r");
__delay_ms(100);
UART_Write_Text("AT+CNMI=2,2,0,0,0\r");
__delay_ms(100);
while(1){
if(RCIF==1){ // Try if message is received
for(i=0;i<80;i++){
while(!RCIF);
buff[i]=UART_Read();
if(buff[i]=='\r')
break;
}
/* itoa(textbuf,existe(buff, "L"),10 ); //Debugging segment
UART_Write_Text(textbuf); */
if(existe(buffer, "L")==1) {
porta[2]=!porta[2];
RA2=porta[2];
/* itoa(textbuf,porta[3],10 ); //Debugging segment
UART_Write_Text("Existe ");
UART_Write_Text(textbuf);
UART_Write_Text("\r");*/
}
for(i=0;i<80;i++) buff[i]=0;
}
}
}
int existe(char linea[], char busq[]){
int e=0,a=0;
char *carpal, *carbus;
carpal=linea;
carbus=busq;
for(e=0;e<strlen(linea);e++){
if(carpal[e]==carbus[a]){
a++;
if(a==strlen(busq)){
return 1;
}
continue;
}
else a=0;
}
return 0;
}
最后我确实解决了2个问题:
-使用命令“ UART1_Write_Text(” AT + ICF = 3,0 \ r“);”这使得GSM模块使用软件流控制而不是硬件控制。使用此解决方案时,对“ L”之类的小输入有反应,但是当我将输入更改为“ Luz”之类时,它就不起作用了。
-然后我确实在输入中使用了控制字符来破坏if(buff [i] =='\ r')的循环,在这种情况下为'_'。
我认为问题在于模块在发送“ Luz”输入之前先发送了“ \ r”字符。然后,它退出循环并开始处理,直到UART停止接收为止,然后当微型计算机执行其余代码时,recevinig 3个字符给出错误标志。使用“ Luz_”输入,并在收到“ _”后立即停止阅读。