第一次使用 M26 ,很生疏,从手册入手开始一步一步的走,做透传,幸好是中文手册,看着不费劲,这里用的是AT指令开发,坐下流程笔记,以后用的着的时候看,这里做一些功能上的封装,框架可以直接用,具体怎么实现根据实际情况,用的是STM32F1系列的单片机通过串口向M26发送数据透传到服务器。
在TCP连接之前需要一些初始化,例如:AT测试指令,设置反显和初始化PDP上下文。
封装的发送指令函数M26_SendCmd其实就是向串口发送数据和延时一段时间等待串口接受M26返回后比较相应返回成功报文。第一个参数是AT指令,第二个参数是期待返回值,第三个参数是等待模块返回超时时间
unsigned char m25_conf_base()
{
while(M26_SendCmd("AT\r\n","OK",500))//测试指令
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
while(M26_SendCmd("ATE0\r\n","OK",500))//设置回显 ATE1设置回显 ATE0设置不回显 2019-3-22
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
while(M26_SendCmd("AT+CSQ\r\n","OK",500))//获取信号强度
{
Clear_Buffer2();
}
while(M26_SendCmd("AT+QREFUSECS=1,1\r\n","OK",500))//拒接来电和短信
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
return 1;
}
2.初始化APN配置 :
unsigned char m26_conf_APN()
{
while(M26_SendCmd("AT+QIFGCNT=0\r\n","OK",500)) //设置为前台
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
while(M26_SendCmd("AT+QICSGP=1,\042CMNET\042\r\n","OK",500)) //设置接入点
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
return 1;
}
unsigned char m26_conf_SIM()
{
int i;
unsigned char res = 0;
for(i = 0; i < 20; i++)
{
//10S内未找到SIM需要重启模块
if(M26_SendCmd("AT+CPIN?\r\n","+CPIN: READY",500))//SIM卡解密
{
res = 0;
Clear_Buffer2();
}
else
{
res = 1;
break;
}
}
delay_ms(500);
Clear_Buffer2();
M26_SendCmd("AT+QINISTAT\r\n","OK",500);
delay_ms(500);
Clear_Buffer2();
return res;
}
unsigned char m26_conf_GSM()
{
unsigned char res = 0;
int i = 0;
//30s未找到网络则需要重启
for(i = 0; i < 60; i++)
{
if(M26_SendCmd("AT+CREG?\r\n","+CREG: 0,1",500))//确定找网成功
{
res = 0;
Clear_Buffer2();
}
else
{
res = 1;
break;
}
}
delay_ms(500);
Clear_Buffer2();
return res;
}
unsigned char m26_conf_GPRS()
{
//30失败则强制执行下一步
int i = 0;
for(i = 0; i < 60; i++)
{
if(M26_SendCmd("AT+CGREG?\r\n","+CGREG: 0,1",500))//GPRS网络注册状态
{
Clear_Buffer2();
}
else
{
break;
}
}
delay_ms(500);
Clear_Buffer2();
return 1;
}
unsigned char m26_conf_PDP()
{
unsigned char res = 0;
int i;
int j;
for(i = 0; i < 10; i++)
{
if(M26_SendCmd("AT+QIREGAPP\r\n","OK",500) == 0) //启动应用
{
delay_ms(500);
Clear_Buffer2();
for(j = 0; j < 3; j++)
{
if(M26_SendCmd("AT+QIACT\r\n","OK",500) == 0)//开启PDP场景
{
M26_SendCmd("AT+QILOCIP\r\n","ERROR",500);//获取IP地址
res = 1;
break;
}
else
{
res = 0;
Clear_Buffer2();
}
}
return res;
}
else
{
res = 0;
Clear_Buffer2();
}
}
return res;
}
unsigned char m26_conf_other()
{
while(M26_SendCmd("ATV1\r\n","OK",500)) //设置回复的是OK
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
while(M26_SendCmd("AT+QIDNSIP=0\r\n","OK",500)) //设置使用IP连接 0IP 1域名
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
while(M26_SendCmd("AT+QIMODE?\r\n","OK",500)) //查询是否是透传模式
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
}
如果需要关闭PDP场景,需要发送AT指令关闭
unsigned char m26_close_PDP()
{
int i;
for(i = 0; i < 10; i++)
{
if(M26_SendCmd("AT+QIDEACT\r\n","ERROR",1000))
return 1;
}
return 0;
}
如果需要关机,M26关机比较简单只要发送AT指令即可
void m26_powerDown()
{
while(M26_SendCmd("AT+QPOWD=1\r\n","NORMAL POWER DOWN",500))
{
Clear_Buffer2();
}
delay_ms(500);
Clear_Buffer2();
}
void m26_init_new(int s)
{
//m26_poweron();
int i = s;
while(1)
{
switch(s)
{
case 0://判断是否开机,未开机开机
m26_poweron();
case 1://基础配置和APN配置
m25_conf_base();
m26_conf_APN();
case 2://查询SIM卡级初始化状态
if(m26_conf_SIM() == 0)
{
m26_powerDown();
i = 0;
continue;
}
case 3://GSM网络判断
if(m26_conf_GSM() == 0)
{
m26_powerDown();
i = 0;
continue;
}
case 4://GPRS网络判断
m26_conf_GPRS();
case 5://PDP场景配置
if(m26_conf_PDP() == 0)
{
if(m26_close_PDP() == 1)
{
i = 2;
continue;
}
else
{
m26_powerDown();
i = 0;
//m26_init_new(0);
continue;
}
}
default:
break;
}
break;
}
}
unsigned char m26_connect_new()
{
while(M26_SendCmd("AT+QIOPEN=\042TCP\042,\042www.xxxx.com\042,\0421301\042\r\n","OK",500));
while(1)
{
if(m26_CheckCmd("ALREADY CONNECT") == 0)
{
return 1;
}
else if(m26_CheckCmd("CONNECT OK") == 0)
{
return 1;
}
else if(m26_CheckCmd("CONNECT FAIL") == 0)
{
while(M26_SendCmd("AT+QISTAT\r\n","OK",500));
return 0;
}
}
}
1.发送指定长度的数据是推荐的,不推荐使用不指定长度
unsigned char m26_tcp_send_len(uint8_t * msg,int len)
{
while(M26_SendCmd("AT+QISEND=?\r\n","OK",500));
//Clear_Buffer2();
char ATbuff[50] = "";
memset(ATbuff,0,sizeof(ATbuff));
sprintf(ATbuff,"AT+QISEND=%d\r\n",len);
while(M26_SendCmd(ATbuff,"<",500))
{
//如果在服务器连接上瞬断后,发送发送指令悔返回ERROR
if(m26_CheckCmd("ERROR") == 0)
{
return 0;
}
}
Clear_Buffer2();
Uart1_serial_send(USART2,msg);
delay_ms(500);
if(m26_CheckCmd("SEND OK") == 0)
{
return 1;
}
else
{
return 0;
}
}
int m26_send_stat()
{
strx = NULL;
int length = -1;
int i;
//bixu duoqing jici 20190321
Clear_Buffer2();
Clear_Buffer2();
for(i = 0; (i < 30) && (length != 0); i++)
{
while(M26_SendCmd("AT+QISACK\r\n","OK",500));
strx=strstr((const char*)RI_Set2_Buffer,(const char*)"+QISACK");
if(strx != NULL)
{
strx = strstr((const char*)RI_Set2_Buffer,(const char*)",");
strx = strstr(strx+1,(const char*)",");
//解析后的长度是字符串,这里是将字符串转换成整形,没有atoi,只能自己封装
length = str2int(strx+2);
}
else
{
Clear_Buffer2();
return -1;
}
Clear_Buffer2();
}
return length;
}
这里是整个初始化,发送流程,具体发送AT指令和接受根据手里的单片机文档封装即可