中级会员
 
- 积分
- 227
- 金钱
- 227
- 注册时间
- 2016-7-14
- 在线时间
- 30 小时
|

楼主 |
发表于 2016-9-1 10:20:49
|
显示全部楼层
[mw_shl_code=applescript,true]/*****************************************************************
问题:
发现利用现有的串口判断程序是以STM原子 视频教程里面公布的以判断接收数据接收到的0X0A 0X0D结束的,而当发送AT+CIPSEND返回的是 " > " 这个符号并不是以0X0A 0X0D 结尾的,这样就导致判断不通过,进而一直死循环!
调试思路及方法:
修改串口接收数据结束标志的通信协议。暂定调试协议以判断数据长度为结束标志。
*********************************************************************************/
#include "stm32f10x.h"
#include "usart.h"
#include "string.h"
#include "SIM800L.h"
#include "delay.h"
u8 type[10]={"TCP"};
/***********************************************************************
函数功能: 向云端服务器发送数据,并获取数据,原始未解析的数据报文
入口参数: buf:向云端发送的数据,input_len:发送的数据长度,output_buf :云端返回的数据
出口参数: > 0:发送成功,收到的字节数,0:失败
***********************************************************************/
/*u16 SendDataToSeverAndGetData(u8 *buf , u16 input_len , u8* output_buf )
{
}*/
/********************************************************************
函数功能:
入口参数:
出口参数:
*********************************************************************/
void sim_at_response(u8 mode)
{
if(USART_RX_STA&0X8000) //接收到一次数据了
{
USART_RX_BUF[USART_RX_STA&0X7FFF]=0;//添加结束符
printf("%s",USART_RX_BUF); //发送到串口
if(mode)USART_RX_STA=0;
}
}
/***********************************************************************
函数功能:查找字符串在字符串的首次位置
入口参数:
出口参数:start:开始出现的位置,
***********************************************************************/
/*u8 StringSerach(u8 *string , u8 *serach ,u8 *start)
{
u16 len = strlen(string);
u16 lens = strlen(serach);
u16 i = 0 , st = 0 , j = 0;
for(i = 0 ; i < len - lens ; i ++)
{
if(serach[0] == string)
{
for(j = 0 ; j < lens ; j++)
{
if(serach[j] != string[i + j])
{
i += j;
break;
}
}
if(j == lens)
{
*start = i;
return 1;
}
}
}
return 0;
}
********************************
当收到返回的数据时判断返回中的数据是否包含期望数据如果包含则返回为出现的位置
************************************/
/***********************************************************************
函数功能:检查模块返回应答是否是期望应答
入口参数:模块返回应答ack的地址
出口参数:期望返回应答所在的地址
**********************************************************************/
u8* sim800L_check_cmd(u8 *str) //指针函数,函数返回值是一个指针,这个函数的作用其实就是指向返回值(的地址)
{
u8 len;
char *strx=0;
if(USART_RX_STA&0X8000) //接收到一次数据了
{
USART_RX_BUF[USART_RX_STA&0X7FFF]=0;//添加结束符
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
strx=strstr((const char*)USART_RX_BUF,(const char*)str);
USART_RX_STA=0;
}
return (u8*)strx; //strx是一个指针变量,里面存放的是期待返回命令值存放的地址
}
/**********************************************************************
函数功能:向sim800L模块发送指令
入口参数:cmd:发送的命令字符串(不需要添加回车),当cmd<0XFF的时候发送数字(比如发送0X1A),大于的时候发送字符串,
ack:期待的应答结果,如果为空则表示的不需要等待应答
waittime:等待时间(单位为10ms)
出库参数:1,发送成功(得到期待的应答结果)
0, 发送失败
**********************************************************************/
u8 sim800L_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
USART_RX_STA=0; //接收状态清零
if((u32)cmd<=0XFF) //当cmd<0XFF的时候发送1A(启动发送数据的命令)其1A<0XFF
{
while(DMA1_Channel7->CNDTR!=0);//等待通道7传输完成
USART1->DR=(u32)cmd;
}
else printf("%s\r\n",cmd);//当cmd>0XFF的时候发送字符串命令如:(AT+CIPSEND其十六进制为41542B43495053454E44 >0XFF)
if(ack&&waittime) //需要等待应答
{
for(waittime;waittime>0;waittime--)
{
delay_ms(10);
if(USART_RX_STA&0X8000) //接收到应答结果
{
if(sim800L_check_cmd(ack)) break; //得到有效数据 //break语句提前跳出循环 break语句不能用于循环语句和switch语句外的起的语句中
USART_RX_STA=0; //清零如果不清零可能导致这个状态标致寄存器里面的值混乱,不利于下次接收数据
}
}
if(waittime==0) return 0; //等待时间内一直没有收到期待的响应(ack)结果则返回值为0表示发送失败
}
return 1;
}
/***************************************************************************
函数功能:
入口参数:type:连接方式为TCP,ipaddr:入网ip地址,port:入网网络端口
出口参数:
****************************************************************************/
u8 sim800L_GPRS(u8 *type,u8* ipaddr,u8* port)
{
int t=0;
u8 tcp_lianjie[50];
u8 *out_buf;
u8 in_buf[]={"GET http://smart.cloud.uoko.com/smar ... 00059c6310b00000000 HTTP/1.1\r\nHOST:smart.cloud.uoko.com\r\n\r\n"};
USART_RX_STA=0; //将串口数据接收状态寄存器清零为了不耽误下次命令接收
sprintf(tcp_lianjie,"AT+CIPSTART=\"%s\",\"%s\",\"%s\"",type,ipaddr,port);//将[ AT+CIPSTART="TCP”."smart.cloud.uoko.com".80 ]传送给无符号指针tcp_lianjie
if(sim800L_send_cmd(tcp_lianjie,"OK",1000)) //发起连接
{
for(t=0;t<500;t++);
// printf("AT+CIPSEND/r/n");
// delay_ms(500);
if(sim800L_send_cmd("AT+CIPSEND","0",0)) //发送数据指令
{
delay_ms(1000);
printf("%s\r\n",in_buf); //通过USART2将数据传输给模块
delay_ms(1000);
USART_RX_STA=0;
printf("%s\r\n",in_buf);
delay_ms(500);
sim800L_send_cmd((u8*)0X1A,"SEND OK",1000); //启动数据传输
delay_ms(1000);
if(USART_RX_STA&0X8000) //接收到了数据
{
USART_RX_BUF[USART_RX_STA&0X7FFF]=0; //添加结束符
out_buf=USART_RX_BUF; //数据发送成功(?????)
return 1; //返回值为1表示成功访问网页并获取数据
}
// }
// if(sim800L_send_cmd("AT+CIPSEND","ERROR",500))
// {
// delay_ms(500);
// sim800L_init();
// }
// }
// if(sim800L_send_cmd(tcp_lianjie,"ALREADY CONNECT",2000))
// {
// delay_ms(100);
// if (sim800L_send_cmd("AT+CIPSEND",">",500))
// {
// delay_ms(1000);
// sim800L_send_cmd((u8*)0X1A,"SEND OK",1000);
// delay_ms(1000);
// if(USART_RX_STA&0X8000) //接收到了数据
// {
// USART_RX_BUF[USART_RX_STA&0X7FFF]=0; //添加结束符
// //out_buf=USART_RX_BUF; //数据发送成功(?????)
// }
// }
// return 2; //返回值为2:访问成功
// }
// return 8;
}return 0;
}
/******************************************************************
函数功能:SIM800l模块初始化
入口参数:
出口参数:返回值1:设置GPRS移动台类别为B,支持包交换和数据交换
返回值2:设置PDP上下文,互联网接协议,接入点等信息
返回值3:附着GPRS业务
返回值4:设置为GPRS连接模式
*******************************************************************/
u8 sim800L_init(void)
{
const u8 *port="80"; //端口固定为80
u8 ipbuf[30]={"smart.cloud.uoko.com"};
if(sim800L_send_cmd("AT","OK",1000))
{
delay_ms(200);
sim800L_send_cmd("AT+CIPCLOSE","CLOSE OK",500);
sim800L_send_cmd("AT+CIPSHUT","SHUT OK",500); //关闭移动场景
if(sim800L_send_cmd("AT+CGCLASS=\"B\"","OK",1000)==0)return 1; //设置GPRS移动台类别为B,支持包交换和数据交换
if(sim800L_send_cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000)==0)return 2;//设置PDP上下文,互联网接协议,接入点等信息
if(sim800L_send_cmd("AT+CGATT=1","OK",500)==0)return 3; //附着GPRS业务
if(sim800L_send_cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500)==0)return 4; //设置为GPRS连接模式
while(1)
{
sim800L_GPRS(type,ipbuf,(u8*)port);
sim_at_response(1);//检查GSM模块发送过来的数据,及时上传给电脑
}
}
return 0;
}
[/mw_shl_code]
|
|