OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8931|回复: 19

sim900a程序中USART2_RX_STA接受状态标志清零以及sim_at_response()函数的问题

[复制链接]

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
发表于 2014-6-23 10:48:51 | 显示全部楼层 |阅读模式
5金钱
SIM900A的例程中有如下程序段:

//GSM信息显示(信号质量,电池电量,日期时间)
//返回值:0,正常
//    其他,错误代码
u8 sim900a_gsminfo_show(u16 x,u16 y)
{
u8 *p,*p1,*p2;
u8 res=0;
p=mymalloc(SRAMIN,50);//申请50个字节的内存
POINT_COLOR=BLUE;
USART2_RX_STA=0;
if(sim900a_send_cmd("AT+CPIN?","OK",200))res|=1<<0; //查询SIM卡是否在位 
USART2_RX_STA=0;         
if(sim900a_send_cmd("AT+COPS?","OK",200)==0) //查询运营商名字

p1=(u8*)strstr((const char*)(USART2_RX_BUF),"\""); 
if(p1)//有有效数据
{
p2=(u8*)strstr((const char*)(p1+1),"\"");
p2[0]=0;//加入结束符
sprintf((char*)p,"运营商:%s",p1+1);
Show_Str(x,y,200,16,p,16,0);

USART2_RX_STA=0; /////得到正确应答,的确不会清零接受状态,但是下一次发送的第一步就是清零接受状态标志啊,不明白这里为什么要清零
}else res|=1<<1;//////////////////出错标志位10
if(sim900a_send_cmd("AT+CSQ","+CSQ:",200)==0) //查询信号质量

p1=(u8*)strstr((const char*)(USART2_RX_BUF),":");
p2=(u8*)strstr((const char*)(p1),",");
p2[0]=0;//加入结束符
sprintf((char*)p,"信号质量:%s",p1+2);//////别忘了把空格也算进去
Show_Str(x,y+20,200,16,p,16,0);
USART2_RX_STA=0;
}else res|=1<<2;
if(sim900a_send_cmd("AT+CBC","+CBC:",200)==0) //查询电池电量

p1=(u8*)strstr((const char*)(USART2_RX_BUF),",");
p2=(u8*)strstr((const char*)(p1+1),",");
p2[0]=0;p2[5]=0;//加入结束符
sprintf((char*)p,"电池电量:%s%%  %smV",p1+1,p2+1);
Show_Str(x,y+40,200,16,p,16,0);
USART2_RX_STA=0;
}else res|=1<<3; 
if(sim900a_send_cmd("AT+CCLK?","+CCLK:",200)==0) //查询电池电量

p1=(u8*)strstr((const char*)(USART2_RX_BUF),"\"");
p2=(u8*)strstr((const char*)(p1+1),":");
p2[3]=0;//加入结束符
sprintf((char*)p,"日期时间:%s",p1+1);
Show_Str(x,y+60,200,16,p,16,0);
USART2_RX_STA=0;
}else res|=1<<4; 
myfree(SRAMIN,p); 
return res;


在此程序段里,为什么在每发送一条AT指令,并得到期待的返回值之后,都要在if语句里执行USART2_RX_STA=0?在发送AT指令的函数sim900a_send_cmd()里面第一条语句不就是清零USART2_RX_STA吗?那又为什么在以上程序段sim900a_gsminfo_show(u16 x,u16 y)中的if语句里额外再对USART2_RX_STA清零?

例程中的sim900a_send_cmd()函数如下:

u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0; 
USART2_RX_STA=0;///////接受状态清零!!!!!!!!!!!!!!!!!!!!!执行发送命令的第一条就是发送标志清零
if((u32)cmd<=0XFF)    ////////变量的地址不可能小于0xff,小于0xff的肯定是数字,比较时都转换为long
{
while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成   
USART2->DR=(u32)cmd;             //传输cmd数据
}else u2_printf("%s\r\n",cmd);//发送命令,发送字符串,%s表示发送字符串
if(ack&&waittime) //需要等待应答,如果是空指针
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART2_RX_STA&0X8000)//接收到期待的应答结果
{
if(sim900a_check_cmd(ack))break;//得到有效数据,不清零接受标志 
USART2_RX_STA=0;///接受到的应答不是期待的应答,清零标志,继续等待

}
if(waittime==0)res=1; 
}
return res;


麻烦原子哥了

最佳答案

查看完整内容[请看2#楼]

回复【11楼】yushengjiexy: --------------------------------- 有数据就返回,没数据待命.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-6-23 10:48:52 | 显示全部楼层
回复【11楼】yushengjiexy:
---------------------------------
有数据就返回,没数据待命.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-23 10:49:40 | 显示全部楼层
在此程序段里,为什么在每发送一条AT指令,并得到期待的返回值之后,都要在if语句里执行USART2_RX_STA=0?在发送AT指令的函数sim900a_send_cmd()里面第一条语句不就是清零USART2_RX_STA吗?那又为什么在以上程序段sim900a_gsminfo_show(u16 x,u16 y)中的if语句里额外再对USART2_RX_STA清零?
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-6-23 12:12:48 | 显示全部楼层
回复【2楼】yushengjiexy:
---------------------------------
在中断里面,会改变USART2_RX_STA的值,所以接收到的数据处理完以后,一定要清零USART2_RX_STA。否则下次接收无法正常进行。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-23 14:09:43 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
恩,像原子哥说的,的确接受中断里面会用USART2_RX_STA来标记接收到的数据长度和是否接受完毕,但是在sim900a_send_cmd()函数中的第一条语句就是USART2_RX_STA=0,也就是说每次stm32执行sim900a_send_cmd()函数,发送at命令前,都会对USART2_RX_STA清零。stm32发送命令给sim900a以后,接收到的数据处理完以后,就算不清零USART2_RX_STA,在下次执行sim900a_send_cmd()函数,发送AT指令前,都会对USART2_RX_STA清零,所以我觉得接收到的数据处理完以后,没有必要清零USART2_RX_STA。
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-23 14:11:25 | 显示全部楼层
if(sim900a_send_cmd("AT+CSQ","+CSQ:",200)==0)  //查询信号质量

p1=(u8*)strstr((const char*)(USART2_RX_BUF),":");
p2=(u8*)strstr((const char*)(p1),",");
p2[0]=0;//加入结束符
sprintf((char*)p,"信号质量:%s",p1+2);//////别忘了把空格也算进去
Show_Str(x,y+20,200,16,p,16,0);
USART2_RX_STA=0; /////////////////////////////////////////////请问原子哥,这一条语句是否可以删去??
}else res|=1<<2;
if(sim900a_send_cmd("AT+CBC","+CBC:",200)==0)  //查询电池电量,因为在执行这条雨具时会对USART2_RX_STA清零

p1=(u8*)strstr((const char*)(USART2_RX_BUF),",");
p2=(u8*)strstr((const char*)(p1+1),",");
p2[0]=0;p2[5]=0;//加入结束符
sprintf((char*)p,"电池电量:%s%%  %smV",p1+1,p2+1);
Show_Str(x,y+40,200,16,p,16,0);
USART2_RX_STA=0; 
}else res|=1<<3;
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-23 14:14:29 | 显示全部楼层
以原子哥例程里面的这一小段程序为例,在if(sim900a_send_cmd("AT+CSQ","+CSQ:",200)==0)中有USART2_RX_STA=0这条语句,但是在接下来执行if(sim900a_send_cmd("AT+CBC","+CBC:",200)==0) 时,因为子函数sim900a_send_cmd()中第一条就是USART2_RX_STA=0。所以,我觉得在if(sim900a_send_cmd("AT+CSQ","+CSQ:",200)==0)中的USART2_RX_STA=0可以删去。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-6-23 22:35:21 | 显示全部楼层
回复【6楼】yushengjiexy:
---------------------------------
你可以去掉试试。
我这里不是乱加的,你在发送之前,清零STA的好处,就是怕此时已经收到了一些计划外的数据,那如果你不清零,就不好处理了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-24 08:39:07 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
好吧,我试试,不过sim900a_send_cmd()命令里面第一条语句就是清零STA。
那么,就算我在发送AT指令之前,不清零STA,此时也收到了一些计划外的数据,可是在我发送AT指令时第一句就是清零STA啊,这样也不会影响我对接受数据的处理啊^_^
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-24 08:43:56 | 显示全部楼层
还有个问题,也想麻烦一下原子哥,在sim900a_test()也就是sim900a主测试程序中,有以下循环。在这里, sim_at_response(1)上传给电脑的是哪些数据,我感觉只是距离它最近的上一次发送AT指令的返回数据啊。
while(1)
{
delay_ms(10); 
sim_at_response(1);//检查GSM模块发送过来的数据,及时上传给电脑
if(sim_ready)//SIM卡就绪.
{
key=KEY_Scan(0); 
if(key)
{
switch(key)
{
case KEY_RIGHT:
sim900a_call_test();//拨号测试
break;
case KEY_DOWN:
sim900a_sms_test(); //短信测试
break;
case KEY_UP:
sim900a_gprs_test();//GPRS测试
break;
}
sim900a_mtest_ui(40,30);
timex=0;

}
if(timex==0) //2.5秒左右更新一次
{
if(sim900a_gsminfo_show(40,225)==0)sim_ready=1;
else sim_ready=0;
}
if((timex%20)==0)LED0=!LED0;//200ms闪烁 
timex++;  
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-6-24 23:24:28 | 显示全部楼层
回复【8楼】yushengjiexy:
---------------------------------
那就按你的写代码就是了,我的仅供参考.
没要求你一定要用我的,出问题了,在考虑下是不是这里的问题.

就是将收到的数据发给电脑啊,你以为是什么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-25 10:55:41 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
哦,感觉原子哥做的硬件很棒,程序更棒,希望可以多吸收学习,所以任何细节都不愿意放过。打扰了,其实我就想知道,是循环程序里面所有的AT指令返回的数据都发给电脑,还是只返回最近一句AT指令返回的数据。我感觉sim_at_response(1)这个函数只返回一次AT指令的数据,但程序应该是要求把所有AT指令返回的数据都显示出来吧?
回复

使用道具 举报

5

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2014-6-8
在线时间
0 小时
 楼主| 发表于 2014-6-26 18:00:24 | 显示全部楼层
回复【12楼】正点原子:
---------------------------------
谢谢
回复

使用道具 举报

170

主题

917

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1824
金钱
1824
注册时间
2013-4-13
在线时间
63 小时
发表于 2014-8-3 15:53:13 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
关于这里清零的问题,我的理解是:每次执行USART2_RX_STA=0,就是为下一次重新再接收数据做准备,如果不清零,可能导致几次接收到的数据叠加在一起;关键是看usart2中断服务函数。不知我的理解对不对?谢谢!
手艺人要内外兼修。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-8-4 00:07:45 | 显示全部楼层
回复【14楼】wangyan915205:
---------------------------------
是的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-8-4 00:08:16 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
但是不完全对。
不清零,就可能没办法开始下一次数据接收。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2014-8-3
在线时间
0 小时
发表于 2014-8-12 15:28:25 | 显示全部楼层
请问原子哥,有木有51单片机控制的的基站定位程序,stm32没学过= =!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-8-12 22:45:05 | 显示全部楼层
回复【17楼】xuchengsheng:
---------------------------------
没有
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
337
金钱
337
注册时间
2012-10-6
在线时间
100 小时
发表于 2015-9-10 15:31:41 | 显示全部楼层
*ack(应答结果) 何时 传到USART3_RX_BUF[]中的  一直没看出来
回复

使用道具 举报

5

主题

47

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
227
金钱
227
注册时间
2016-7-14
在线时间
30 小时
发表于 2016-8-16 14:59:57 | 显示全部楼层
wangyan915205 发表于 2014-8-3 15:53
回复【7楼】正点原子:
---------------------------------
关于这里清零的问题,我的理解是:每次执行USART ...

这个USART2_RX_STA是状态标志位寄存器吧,他里面应该不存在接收到的数据的,只是数据接收完成后他里面相应的为会被置高或置低电平,应该不存在数据叠加在一起的问题。只不过可能会导致标志位混乱,下次接收出现问题@正点原子,我解释的对不?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 07:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表