STC与SIM900A进行TCP通信问题
时间:10-02
整理:3721RD
点击:
最近在通过STC89C52控制SIM900A进行TCP通信,有一个很纠结的问题,我打算是通过串口中断进行判断然后发送数据的,但是单片机发AT指令过去后,看到开发板的RX灯已经闪烁起来了,就代表有数据传回来
,但是判断进入串口中断的灯却没有亮起来。然后我通过延时进行打电话和发送数据,打电话都没有问题,而发送数据也可以发送,但发送一次之后就会自动断了,并且这样发送数据不稳定。所以还是希望可以通过串口中断判断,希望各位大神帮帮忙,实在找不到问题所在。
以下为程序:
#include <REG51.H>
#include <string.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY4=P1^4;
sbit KEY5=P1^5;
sbit KEY6=P1^6;
sbit KEY7=P1^7;
sbit LED0=P0^0;
sbit LED1=P0^1;
sbit LED2=P0^2;
sbit LED3=P0^3;
sbit LED4=P0^4;
sbit LED5=P0^5;
sbit LED6=P0^6;
sbit LED7=P0^7;
//以下用于保存单片机收到模块发来的AT指令,通过这些指令单片机可以判断模块的状态
uchar GsmRcv[30] = {0};
uchar GsmRcvAt[50] = {0};
uchar GsmRcvCnt = 0;
uchar GsmAtFlag = 0;
uchar str1[] = "ATD10086;\r\n";
void SerialInti();
void Send(uchar c);
void Sends(uchar *str);
void Delay(int z);
void ATD();
void ATH();
void ATA();
void GPRS();
void main()
{
SerialInti();
while(1)
{
if(KEY4 == 0)
{
Delay(20);
if(KEY4 == 0)
{
ATD();
Delay(20);
}
}
if(KEY5 == 0)
{
Delay(20);
if(KEY5 == 0)
{
ATH();
Delay(20);
}
}
if(KEY6 == 0)
{
Delay(20);
if(KEY6 == 0)
{
ATA();
Delay(20);
}
}
// if(KEY7 == 0)
// {
// Delay(20);
// if(KEY7 == 0)
// {
GPRS();
Delay(2000);
// }
// }
}
}
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
void SerialInti()//初始化程序(必须使用,否则无法收发)
{
TMOD = 0x20; //定时器1操作模式2:8位自动重载定时器
TH1 = 0xfd; //装入初值,波特率9600
TL1 = 0xfd;
TR1 = 1; //打开定时器
SM0 = 0; //设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1 = 1; //(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN = 1; //串行接收允许位(要先设置sm0sm1再开串行允许)
EA = 1; //开总中断
ES = 1; //开串行口中断
}
/*串行通讯中断,收发完成将进入该中断*/
void Serial_interrupt() interrupt 4
{
uchar i = 0;
LED0 = 0;
if(RI == 1) //收到信息
{
LED1 = ~LED1;
GsmRcv[GsmRcvCnt] = SBUF;
GsmRcvCnt++;
//收到了完整的AT指令,完整的AT指令是以0x0a 0x0d结尾的。故作此判断,在接收的过程中是否收到0x0a 0x0d
/* if(GsmRcv[GsmRcvCnt-2] == 0x0d && GsmRcv[GsmRcvCnt-1] == 0x0a && GsmRcvCnt >= 2)
{
LED3 = ~LED3;
//一旦收到0x0a 0x0d,就将数据保存起来。用户主函数的判断。
for(i=0; i<GsmRcvCnt; i++)
{
GsmRcvAt[i] = GsmRcv[i];
GsmRcv[i] = 0;
}
GsmRcvCnt = 0;
GsmAtFlag = 1;//收到了完整的at指令,通过这个标志位置1,这样主函数就知道去判断了。
}
else if(GsmRcvCnt >= 50)//因为内存有限,收到了50个字符还是没有看到0x0a 0x0d的话,就重新开始接收吧。
{
GsmRcvCnt = 0;
} */
}
LED0 = 1;
RI = 0; //接收中断信号清零,表示将继续接收
}
void Send(uchar c)
{
SBUF = c;
while(!TI); //等待发送完成信号(TI=1)出现
TI = 0;
}
//串行口连续发送char型数组,遇到终止号/0将停止
void Sends(uchar *str)
{
ES = 0;
while(*str!='\0')
{
Send(*str);
str++;
}
ES = 1;
}
//延时函数
void Delay(int z)
{
uint x , y;
for(x = 110;x > 0;x--)
for(y = z;y > 0;y--);
}
void ATD() //拨打电话
{
LED4 = ~LED4;
Sends("ATD15296006606;\r\n");
}
void ATH() //挂断电话
{
LED5 = ~LED5;
Sends("ATH\r\n");
}
void ATA() //接听电话
{
LED6 = ~LED6;
Sends("ATA\r\n");
}
void GPRS()
{
uchar i = 0;
/* GsmAtFlag = 0;
while(GsmAtFlag == 0)
{
Sends("AT\r\n");
Delay(1);
}
GsmAtFlag = 0;
//检测信号
while(1)
{
Sends("AT+COPS?\r\n");
Delay(2);
while(GsmAtFlag == 0);
if(strstr(GsmRcvAt, "CHINA") )//检测是否收到 CHINA MOBILE 服务商信息。如果收到证明是连接上网络了
{
break;
}
} */
while(1)
{
Sends("AT+CIPCLOSE\r\n");
Delay(1000);
Sends("AT+CIPSHUT\r\n");
Delay(1000);
Sends("AT+CLPORT=\"TCP\",\"2022\"\r\n");//发送指令指定本地端口
Delay(1000);
Sends("AT+CIPSTART=\"TCP\",\"10.169.35.4\",\"8086\"\r\n");//此处修改你建立服务器的IP,服务器端口号8080
Delay(3000);
// if(GsmAtFlag == 1 && strstr(GsmRcvAt, "CONNECT OK") )//检测是否收到 CONNECT OK ,如果这连接成功
// {
Sends("AT+CIPSEND\r\n");
Delay(2000);
Sends("abc123"); //向服务器发送数据
Delay(1000);
Send(0x1a); //以0x1a结束
Delay(3000);
// break;
// }
LED7 = ~LED7;
}
}
,但是判断进入串口中断的灯却没有亮起来。然后我通过延时进行打电话和发送数据,打电话都没有问题,而发送数据也可以发送,但发送一次之后就会自动断了,并且这样发送数据不稳定。所以还是希望可以通过串口中断判断,希望各位大神帮帮忙,实在找不到问题所在。
以下为程序:
#include <REG51.H>
#include <string.h>
#include <stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY4=P1^4;
sbit KEY5=P1^5;
sbit KEY6=P1^6;
sbit KEY7=P1^7;
sbit LED0=P0^0;
sbit LED1=P0^1;
sbit LED2=P0^2;
sbit LED3=P0^3;
sbit LED4=P0^4;
sbit LED5=P0^5;
sbit LED6=P0^6;
sbit LED7=P0^7;
//以下用于保存单片机收到模块发来的AT指令,通过这些指令单片机可以判断模块的状态
uchar GsmRcv[30] = {0};
uchar GsmRcvAt[50] = {0};
uchar GsmRcvCnt = 0;
uchar GsmAtFlag = 0;
uchar str1[] = "ATD10086;\r\n";
void SerialInti();
void Send(uchar c);
void Sends(uchar *str);
void Delay(int z);
void ATD();
void ATH();
void ATA();
void GPRS();
void main()
{
SerialInti();
while(1)
{
if(KEY4 == 0)
{
Delay(20);
if(KEY4 == 0)
{
ATD();
Delay(20);
}
}
if(KEY5 == 0)
{
Delay(20);
if(KEY5 == 0)
{
ATH();
Delay(20);
}
}
if(KEY6 == 0)
{
Delay(20);
if(KEY6 == 0)
{
ATA();
Delay(20);
}
}
// if(KEY7 == 0)
// {
// Delay(20);
// if(KEY7 == 0)
// {
GPRS();
Delay(2000);
// }
// }
}
}
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
void SerialInti()//初始化程序(必须使用,否则无法收发)
{
TMOD = 0x20; //定时器1操作模式2:8位自动重载定时器
TH1 = 0xfd; //装入初值,波特率9600
TL1 = 0xfd;
TR1 = 1; //打开定时器
SM0 = 0; //设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1 = 1; //(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN = 1; //串行接收允许位(要先设置sm0sm1再开串行允许)
EA = 1; //开总中断
ES = 1; //开串行口中断
}
/*串行通讯中断,收发完成将进入该中断*/
void Serial_interrupt() interrupt 4
{
uchar i = 0;
LED0 = 0;
if(RI == 1) //收到信息
{
LED1 = ~LED1;
GsmRcv[GsmRcvCnt] = SBUF;
GsmRcvCnt++;
//收到了完整的AT指令,完整的AT指令是以0x0a 0x0d结尾的。故作此判断,在接收的过程中是否收到0x0a 0x0d
/* if(GsmRcv[GsmRcvCnt-2] == 0x0d && GsmRcv[GsmRcvCnt-1] == 0x0a && GsmRcvCnt >= 2)
{
LED3 = ~LED3;
//一旦收到0x0a 0x0d,就将数据保存起来。用户主函数的判断。
for(i=0; i<GsmRcvCnt; i++)
{
GsmRcvAt[i] = GsmRcv[i];
GsmRcv[i] = 0;
}
GsmRcvCnt = 0;
GsmAtFlag = 1;//收到了完整的at指令,通过这个标志位置1,这样主函数就知道去判断了。
}
else if(GsmRcvCnt >= 50)//因为内存有限,收到了50个字符还是没有看到0x0a 0x0d的话,就重新开始接收吧。
{
GsmRcvCnt = 0;
} */
}
LED0 = 1;
RI = 0; //接收中断信号清零,表示将继续接收
}
void Send(uchar c)
{
SBUF = c;
while(!TI); //等待发送完成信号(TI=1)出现
TI = 0;
}
//串行口连续发送char型数组,遇到终止号/0将停止
void Sends(uchar *str)
{
ES = 0;
while(*str!='\0')
{
Send(*str);
str++;
}
ES = 1;
}
//延时函数
void Delay(int z)
{
uint x , y;
for(x = 110;x > 0;x--)
for(y = z;y > 0;y--);
}
void ATD() //拨打电话
{
LED4 = ~LED4;
Sends("ATD15296006606;\r\n");
}
void ATH() //挂断电话
{
LED5 = ~LED5;
Sends("ATH\r\n");
}
void ATA() //接听电话
{
LED6 = ~LED6;
Sends("ATA\r\n");
}
void GPRS()
{
uchar i = 0;
/* GsmAtFlag = 0;
while(GsmAtFlag == 0)
{
Sends("AT\r\n");
Delay(1);
}
GsmAtFlag = 0;
//检测信号
while(1)
{
Sends("AT+COPS?\r\n");
Delay(2);
while(GsmAtFlag == 0);
if(strstr(GsmRcvAt, "CHINA") )//检测是否收到 CHINA MOBILE 服务商信息。如果收到证明是连接上网络了
{
break;
}
} */
while(1)
{
Sends("AT+CIPCLOSE\r\n");
Delay(1000);
Sends("AT+CIPSHUT\r\n");
Delay(1000);
Sends("AT+CLPORT=\"TCP\",\"2022\"\r\n");//发送指令指定本地端口
Delay(1000);
Sends("AT+CIPSTART=\"TCP\",\"10.169.35.4\",\"8086\"\r\n");//此处修改你建立服务器的IP,服务器端口号8080
Delay(3000);
// if(GsmAtFlag == 1 && strstr(GsmRcvAt, "CONNECT OK") )//检测是否收到 CONNECT OK ,如果这连接成功
// {
Sends("AT+CIPSEND\r\n");
Delay(2000);
Sends("abc123"); //向服务器发送数据
Delay(1000);
Send(0x1a); //以0x1a结束
Delay(3000);
// break;
// }
LED7 = ~LED7;
}
}
小编你好,我毕设要利用想利用单片机控制GSM的GPRS向手机APP发送程序,我现在不太明白你说的“此处修改你建立服务器的IP,服务器端口号8080”那个IP到底是什么东西,跟单片机有关系吗,还是指的是网络调试助手的电脑IP?
那个IP应该是一个公网IP,端口号是服务器的端口
学学血虚
亲,你这个问题解决了吗,我毕设也要单片机控制GSM的GPRS向手机APP发送程序,对这个问题也有疑惑,这个服务器ip、端口号是怎么知道的
你好,请问您解决了吗?
学习学习