STC开发板看到RX的灯亮了起来,但无法进入串口中断的原因
吹牛逼喊我 2015-01-12 09:11:29 最近在用单片机控制SIM900A进行GPRS通信,可以打电话,但无法进入串口中断,STC开发板的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;
}
}