找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1931|回复: 0
收起左侧

在战舰STM32开发板上调试的SIM900A短信电话测试实验

[复制链接]
ID:383374 发表于 2018-12-7 17:49 | 显示全部楼层 |阅读模式
测试可用

单片机源程序如下:
  1. #include "sim900a.h"
  2. #include "usart.h"               
  3. #include "delay.h"       
  4. #include "led.h"            
  5. #include "key.h"                                             
  6. #include "lcd.h"
  7. #include "dma.h"           
  8. #include "w25qxx.h"          
  9. #include "touch.h"          
  10. #include "malloc.h"
  11. #include "string.h"   
  12. #include "text.h"               
  13. #include "usart3.h"
  14. #include "ff.h"
  15.        
  16.    
  17. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. //usmart支持部分
  19. //将收到的AT指令应答数据返回给电脑串口
  20. //mode:0,不清零USART3_RX_STA;
  21. //     1,清零USART3_RX_STA;
  22. void sim_at_response(u8 mode)
  23. {
  24.         if(USART3_RX_STA&0X8000)                //接收到一次数据了
  25.         {
  26.                 USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
  27.                 printf("%s",USART3_RX_BUF);        //发送到串口
  28.                 if(mode)USART3_RX_STA=0;
  29.         }
  30. }
  31. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. //ATK-SIM900A 各项测试(拨号测试、短信测试、GPRS测试)共用代码

  33. //sim900a发送命令后,检测接收到的应答
  34. //str:期待的应答结果
  35. //返回值:0,没有得到期待的应答结果
  36. //    其他,期待应答结果的位置(str的位置)
  37. u8* sim900a_check_cmd(u8 *str)
  38. {
  39.         char *strx=0;
  40.         if(USART3_RX_STA&0X8000)                //接收到一次数据了
  41.         {
  42.                 USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
  43.                 strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
  44.         }
  45.         return (u8*)strx;
  46. }
  47. //向sim900a发送命令
  48. //cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
  49. //ack:期待的应答结果,如果为空,则表示不需要等待应答
  50. //waittime:等待时间(单位:10ms)
  51. //返回值:0,发送成功(得到了期待的应答结果)
  52. //       1,发送失败
  53. u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
  54. {
  55.         u8 res=0;
  56.         USART3_RX_STA=0;
  57.         if((u32)cmd<=0XFF)
  58.         {
  59.                 while((USART3->SR&0X40)==0);//等待上一次数据发送完成  
  60.                 USART3->DR=(u32)cmd;
  61.         }else u3_printf("%s\r\n",cmd);//发送命令
  62.         if(ack&&waittime)                //需要等待应答
  63.         {
  64.                 while(--waittime)        //等待倒计时
  65.                 {
  66.                         delay_ms(10);
  67.                         if(USART3_RX_STA&0X8000)//接收到期待的应答结果
  68.                         {
  69.                                 if(sim900a_check_cmd(ack))break;//得到有效数据
  70.                                 USART3_RX_STA=0;
  71.                         }
  72.                 }
  73.                 if(waittime==0)res=1;
  74.         }
  75.         return res;
  76. }
  77. //将1个字符转换为16进制数字
  78. //chr:字符,0~9/A~F/a~F
  79. //返回值:chr对应的16进制数值
  80. u8 sim900a_chr2hex(u8 chr)
  81. {
  82.         if(chr>='0'&&chr<='9')return chr-'0';
  83.         if(chr>='A'&&chr<='F')return (chr-'A'+10);
  84.         if(chr>='a'&&chr<='f')return (chr-'a'+10);
  85.         return 0;
  86. }
  87. //将1个16进制数字转换为字符
  88. //hex:16进制数字,0~15;
  89. //返回值:字符
  90. u8 sim900a_hex2chr(u8 hex)
  91. {
  92.         if(hex<=9)return hex+'0';
  93.         if(hex>=10&&hex<=15)return (hex-10+'A');
  94.         return '0';
  95. }
  96. //unicode gbk 转换函数
  97. //src:输入字符串
  98. //dst:输出(uni2gbk时为gbk内码,gbk2uni时,为unicode字符串)
  99. //mode:0,unicode到gbk转换;
  100. //     1,gbk到unicode转换;
  101. void sim900a_unigbk_exchange(u8 *src,u8 *dst,u8 mode)
  102. {
  103.         u16 temp;
  104.         u8 buf[2];
  105.         if(mode)//gbk 2 unicode
  106.         {
  107.                 while(*src!=0)
  108.                 {
  109.                         if(*src<0X81)        //非汉字
  110.                         {
  111.                                 temp=(u16)ff_convert((WCHAR)*src,1);
  112.                                 src++;
  113.                         }else                         //汉字,占2个字节
  114.                         {
  115.                                 buf[1]=*src++;
  116.                                 buf[0]=*src++;
  117.                                 temp=(u16)ff_convert((WCHAR)*(u16*)buf,1);
  118.                         }
  119.                         *dst++=sim900a_hex2chr((temp>>12)&0X0F);
  120.                         *dst++=sim900a_hex2chr((temp>>8)&0X0F);
  121.                         *dst++=sim900a_hex2chr((temp>>4)&0X0F);
  122.                         *dst++=sim900a_hex2chr(temp&0X0F);
  123.                 }
  124.         }else        //unicode 2 gbk
  125.         {
  126.                 while(*src!=0)
  127.                 {
  128.                         buf[1]=sim900a_chr2hex(*src++)*16;
  129.                         buf[1]+=sim900a_chr2hex(*src++);
  130.                         buf[0]=sim900a_chr2hex(*src++)*16;
  131.                         buf[0]+=sim900a_chr2hex(*src++);
  132.                         temp=(u16)ff_convert((WCHAR)*(u16*)buf,0);
  133.                         if(temp<0X80){*dst=temp;dst++;}
  134.                         else {*(u16*)dst=swap16(temp);dst+=2;}
  135.                 }
  136.         }
  137.         *dst=0;//添加结束符
  138. }
  139. //键盘码表
  140. const u8* kbd_tbl1[13]={"1","2","3","4","5","6","7","8","9","*","0","#","DEL"};
  141. const u8* kbd_tbl2[13]={"1","2","3","4","5","6","7","8","9",".","0","#","DEL"};
  142. u8** kbd_tbl;
  143. u8* kbd_fn_tbl[2];
  144. //加载键盘界面(尺寸为240*140)
  145. //x,y:界面起始坐标(320*240分辨率的时候,x必须为0)
  146. void sim900a_load_keyboard(u16 x,u16 y,u8 **kbtbl)
  147. {
  148.         u16 i;
  149.         POINT_COLOR=RED;
  150.         kbd_tbl=kbtbl;
  151.         LCD_Fill(x,y,x+240,y+140,WHITE);
  152.         LCD_DrawRectangle(x,y,x+240,y+140);                                                  
  153.         LCD_DrawRectangle(x+80,y,x+160,y+140);         
  154.         LCD_DrawRectangle(x,y+28,x+240,y+56);
  155.         LCD_DrawRectangle(x,y+84,x+240,y+112);
  156.         POINT_COLOR=BLUE;
  157.         for(i=0;i<15;i++)
  158.         {
  159.                 if(i<13)Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),(u8*)kbd_tbl[i],16,80);
  160.                 else Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),kbd_fn_tbl[i-13],16,80);
  161.         }                                                             
  162. }
  163. //按键状态设置
  164. //x,y:键盘坐标
  165. //key:键值(0~8)
  166. //sta:状态,0,松开;1,按下;
  167. void sim900a_key_staset(u16 x,u16 y,u8 keyx,u8 sta)
  168. {                  
  169.         u16 i=keyx/3,j=keyx%3;
  170.         if(keyx>15)return;
  171.         if(sta)LCD_Fill(x+j*80+1,y+i*28+1,x+j*80+78,y+i*28+26,GREEN);
  172.         else LCD_Fill(x+j*80+1,y+i*28+1,x+j*80+78,y+i*28+26,WHITE);
  173.         if(j&&(i>3))Show_Str_Mid(x+j*80,y+6+28*i,(u8*)kbd_fn_tbl[keyx-13],16,80);
  174.         else Show_Str_Mid(x+j*80,y+6+28*i,(u8*)kbd_tbl[keyx],16,80);                                  
  175. }
  176. //得到触摸屏的输入
  177. //x,y:键盘坐标
  178. //返回值:按键键值(1~15有效;0,无效)
  179. u8 sim900a_get_keynum(u16 x,u16 y)
  180. {
  181.         u16 i,j;
  182.         static u8 key_x=0;//0,没有任何按键按下;1~15,1~15号按键按下
  183.         u8 key=0;
  184.         tp_dev.scan(0);                  
  185.         if(tp_dev.sta&TP_PRES_DOWN)                        //触摸屏被按下
  186.         {       
  187.                 for(i=0;i<5;i++)
  188.                 {
  189.                         for(j=0;j<3;j++)
  190.                         {
  191.                                  if(tp_dev.x[0]<(x+j*80+80)&&tp_dev.x[0]>(x+j*80)&&tp_dev.y[0]<(y+i*28+28)&&tp_dev.y[0]>(y+i*28))
  192.                                 {       
  193.                                         key=i*3+j+1;         
  194.                                         break;                           
  195.                                 }
  196.                         }
  197.                         if(key)
  198.                         {          
  199.                                 if(key_x==key)key=0;
  200.                                 else
  201.                                 {
  202.                                         sim900a_key_staset(x,y,key_x-1,0);
  203.                                         key_x=key;
  204.                                         sim900a_key_staset(x,y,key_x-1,1);
  205.                                 }
  206.                                 break;
  207.                         }
  208.                 }  
  209.         }else if(key_x)
  210.         {
  211.                 sim900a_key_staset(x,y,key_x-1,0);
  212.                 key_x=0;
  213.         }
  214.         return key;
  215. }
  216. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. //拨号测试部分代码

  218. //sim900a拨号测试
  219. //用于拨打电话和接听电话
  220. //返回值:0,正常
  221. //    其他,错误代码
  222. u8 sim900a_call_test(void)
  223. {
  224.         u8 key;
  225.         u16 lenx;
  226.         u8 callbuf[20];
  227.         u8 pohnenumlen=0;        //号码长度,最大15个数
  228.         u8 *p,*p1,*p2;
  229.         u8 oldmode=0;
  230.         u8 cmode=0;        //模式
  231.                                 //0:等待拨号
  232.                                 //1:拨号中
  233.                     //2:通话中
  234.                                 //3:接收到来电
  235.         LCD_Clear(WHITE);
  236.         if(sim900a_send_cmd("AT+CLIP=1","OK",200))return 1;        //设置来电显示
  237.         if(sim900a_send_cmd("AT+COLP=1","OK",200))return 2;        //设置被叫号码显示
  238.         p1=mymalloc(SRAMIN,20);                                                                //申请20直接用于存放号码
  239.         if(p1==NULL)return 2;       
  240.         POINT_COLOR=RED;
  241.         Show_Str_Mid(0,30,"ATK-SIM900A 拨号测试",16,240);                                             
  242.         Show_Str(40,70,200,16,"请拨号:",16,0);
  243.         kbd_fn_tbl[0]="拨号";
  244.         kbd_fn_tbl[1]="返回";
  245.         sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);
  246.         POINT_COLOR=BLUE;
  247.         while(1)
  248.         {
  249.                 delay_ms(10);
  250.                 if(USART3_RX_STA&0X8000)                //接收到数据
  251.                 {
  252.                         sim_at_response(0);
  253.                         if(cmode==1||cmode==2)
  254.                         {
  255.                                 if(cmode==1)if(sim900a_check_cmd("+COLP:"))cmode=2;        //拨号成功
  256.                                 if(sim900a_check_cmd("NO CARRIER"))cmode=0;        //拨号失败
  257.                                 if(sim900a_check_cmd("NO ANSWER"))cmode=0;        //拨号失败
  258.                                 if(sim900a_check_cmd("ERROR"))cmode=0;                //拨号失败
  259.                         }
  260.                         if(sim900a_check_cmd("+CLIP:"))//接收到来电
  261.                         {
  262.                                 cmode=3;
  263.                                 p=sim900a_check_cmd("+CLIP:");
  264.                                 p+=8;
  265.                                 p2=(u8*)strstr((const char *)p,"\"");
  266.                                 p2[0]=0;//添加结束符
  267.                                 strcpy((char*)p1,(char*)p);
  268.                         }
  269.                         USART3_RX_STA=0;
  270.                 }
  271.                 key=sim900a_get_keynum(0,180);
  272.                 if(key)
  273.                 {
  274.                         if(key<13)
  275.                         {
  276.                                 if(cmode==0&&pohnenumlen<15)
  277.                                 {
  278.                                         callbuf[pohnenumlen++]=kbd_tbl[key-1][0];
  279.                                         u3_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]);
  280.                                 }else if(cmode==2)//通话中
  281.                                 {
  282.                                         u3_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]);
  283.                                         delay_ms(100);
  284.                                         u3_printf("AT+VTS=%c\r\n",kbd_tbl[key-1][0]);
  285.                                         LCD_ShowChar(40+56,90,kbd_tbl[key-1][0],16,0);
  286.                                 }
  287.                         }else
  288.                         {
  289.                                 if(key==13)if(pohnenumlen&&cmode==0)pohnenumlen--;//删除
  290.                                 if(key==14)//执行拨号
  291.                                 {
  292.                                         if(cmode==0)//拨号模式
  293.                                         {
  294.                                                 callbuf[pohnenumlen]=0;                        //最后加入结束符
  295.                                                 u3_printf("ATD%s;\r\n",callbuf);//拨号
  296.                                                 cmode=1;                                                //拨号中模式
  297.                                         }else
  298.                                         {
  299.                                                 sim900a_send_cmd("ATH","OK",200);//挂机
  300.                                                 cmode=0;
  301.                                         }
  302.                                 }
  303.                                 if(key==15)
  304.                                 {
  305.                                         if(cmode==3)//接收到来电
  306.                                         {
  307.                                                 sim900a_send_cmd("ATA","OK",200);//发送应答指令
  308.                                                 Show_Str(40+56,70,200,16,callbuf,16,0);
  309.                                                 cmode=2;
  310.                                         }else
  311.                                         {
  312.                                                 sim900a_send_cmd("ATH",0,0);//不管有没有在通话,都结束通话
  313.                                                 break;//退出循环
  314.                                         }
  315.                                 }
  316.                         }
  317.                         if(cmode==0)//只有在等待拨号模式有效
  318.                         {
  319.                                 callbuf[pohnenumlen]=0;
  320.                                 LCD_Fill(40+56,70,239,70+16,WHITE);
  321.                                 Show_Str(40+56,70,200,16,callbuf,16,0);         
  322.                         }                               
  323.                 }
  324.                 if(oldmode!=cmode)//模式变化了
  325.                 {
  326.                         switch(cmode)
  327.                         {
  328.                                 case 0:
  329.                                         kbd_fn_tbl[0]="拨号";
  330.                                         kbd_fn_tbl[1]="返回";
  331.                                         POINT_COLOR=RED;
  332.                                         Show_Str(40,70,200,16,"请拨号:",16,0);  
  333.                                         LCD_Fill(40+56,70,239,70+16,WHITE);
  334.                                         if(pohnenumlen)
  335.                                         {
  336.                                                 POINT_COLOR=BLUE;
  337.                                                 Show_Str(40+56,70,200,16,callbuf,16,0);
  338.                                         }
  339.                                         break;
  340.                                 case 1:
  341.                                         POINT_COLOR=RED;
  342.                                         Show_Str(40,70,200,16,"拨号中:",16,0);
  343.                                         pohnenumlen=0;
  344.                                 case 2:
  345.                                         POINT_COLOR=RED;
  346.                                         if(cmode==2)Show_Str(40,70,200,16,"通话中:",16,0);
  347.                                         kbd_fn_tbl[0]="挂断";
  348.                                         kbd_fn_tbl[1]="返回";        
  349.                                         break;
  350.                                 case 3:
  351.                                         POINT_COLOR=RED;
  352.                                         Show_Str(40,70,200,16,"有来电:",16,0);
  353.                                         POINT_COLOR=BLUE;
  354.                                         Show_Str(40+56,70,200,16,p1,16,0);
  355.                                         kbd_fn_tbl[0]="挂断";
  356.                                         kbd_fn_tbl[1]="接听";
  357.                                         break;                               
  358.                         }
  359.                         if(cmode==2)Show_Str(40,90,200,16,"DTMF音:",16,0);        //通话中,可以通过键盘输入DTMF音
  360.                         else LCD_Fill(40,90,120,90+16,WHITE);
  361.                         sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);                //显示键盘
  362.                         oldmode=cmode;
  363.                 }
  364.                 if((lenx%50)==0)LED0=!LED0;                                              
  365.                 lenx++;         
  366.         }
  367.         myfree(SRAMIN,p1);
  368.         return 0;
  369. }
  370. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  371. //短信测试部分代码

  372. //SIM900A读短信测试
  373. void sim900a_sms_read_test(void)
  374. {
  375.         u8 *p,*p1,*p2;
  376.         u8 timex=0;
  377.         u8 msgindex[3];
  378.         u8 msglen=0;
  379.         u8 msgmaxnum=0;                //短信最大条数
  380.         u8 key=0;
  381.         u8 smsreadsta=0;        //是否在短信显示状态
  382.         p=mymalloc(SRAMIN,200);//申请200个字节的内存
  383.         LCD_Clear(WHITE);
  384.         POINT_COLOR=RED;
  385.         Show_Str_Mid(0,30,"ATK-SIM900A 读短信测试",16,240);                                             
  386.         Show_Str(30,50,200,16,"读取:     总信息:",16,0);        
  387.         kbd_fn_tbl[0]="读取";
  388.         kbd_fn_tbl[1]="返回";
  389.         sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);//显示键盘  
  390.         while(1)
  391.         {
  392.                 key=sim900a_get_keynum(0,180);
  393.                 if(key)
  394.                 {  
  395.                         if(smsreadsta)
  396.                         {
  397.                                 LCD_Fill(30,75,239,179,WHITE);//清除显示的短信内容
  398.                                 smsreadsta=0;
  399.                         }
  400.                         if(key<10||key==11)
  401.                         {
  402.                                 if(msglen<2)
  403.                                 {
  404.                                         msgindex[msglen++]=kbd_tbl[key-1][0];
  405.                                         u3_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]);
  406.                                 }
  407.                                 if(msglen==2)
  408.                                 {
  409.                                         key=(msgindex[0]-'0')*10+msgindex[1]-'0';
  410.                                         if(key>msgmaxnum)
  411.                                         {
  412.                                                 msgindex[0]=msgmaxnum/10+'0';
  413.                                                 msgindex[1]=msgmaxnum%10+'0';                                       
  414.                                         }
  415.                                 }
  416.                         }else
  417.                         {
  418.                                 if(key==13)if(msglen)msglen--;//删除  
  419.                                 if(key==14&&msglen)//执行读取短信
  420.                                 {
  421.                                         LCD_Fill(30,75,239,179,WHITE);//清除之前的显示                    
  422.                                         sprintf((char*)p,"AT+CMGR=%s",msgindex);
  423.                                         if(sim900a_send_cmd(p,"+CMGR:",200)==0)//读取短信
  424.                                         {
  425.                                                 POINT_COLOR=RED;
  426.                                                 Show_Str(30,75,200,12,"状态:",12,0);
  427.                                                 Show_Str(30+75,75,200,12,"来自:",12,0);
  428.                                                 Show_Str(30,90,200,12,"接收时间:",12,0);
  429.                                                 Show_Str(30,105,200,12,"内容:",12,0);
  430.                                                 POINT_COLOR=BLUE;
  431.                                                 if(strstr((const char*)(USART3_RX_BUF),"UNREAD")==0)Show_Str(30+30,75,200,12,"已读",12,0);
  432.                                                 else Show_Str(30+30,75,200,12,"未读",12,0);
  433.                                                 p1=(u8*)strstr((const char*)(USART3_RX_BUF),",");
  434.                                                 p2=(u8*)strstr((const char*)(p1+2),"\"");
  435.                                                 p2[0]=0;//加入结束符
  436.                                                 sim900a_unigbk_exchange(p1+2,p,0);                        //将unicode字符转换为gbk码
  437.                                                 Show_Str(30+75+30,75,200,12,p,12,0);                //显示电话号码
  438.                                                 p1=(u8*)strstr((const char*)(p2+1),"/");
  439.                                                 p2=(u8*)strstr((const char*)(p1),"+");
  440.                                                 p2[0]=0;//加入结束符
  441.                                                 Show_Str(30+54,90,200,12,p1-2,12,0);                //显示接收时间  
  442.                                                 p1=(u8*)strstr((const char*)(p2+1),"\r");        //寻找回车符
  443.                                                 sim900a_unigbk_exchange(p1+2,p,0);                        //将unicode字符转换为gbk码
  444.                                                 Show_Str(30+30,105,180,75,p,12,0);                        //显示短信内容
  445.                                                 smsreadsta=1;                                                                //标记有显示短信内容
  446.                                         }else
  447.                                         {
  448.                                                 Show_Str(30,75,200,12,"无短信内容!!!请检查!!",12,0);
  449.                                                 delay_ms(1000);
  450.                                                 LCD_Fill(30,75,239,75+12,WHITE);//清除显示
  451.                                         }          
  452.                                         USART3_RX_STA=0;
  453.                                 }
  454.                                 if(key==15)break;
  455.                         }
  456.                         msgindex[msglen]=0;
  457.                         LCD_Fill(30+40,50,86,50+16,WHITE);
  458.                         Show_Str(30+40,50,86,16,msgindex,16,0);         
  459.                 }
  460.                 if(timex==0)                //2.5秒左右更新一次
  461.                 {
  462.                         if(sim900a_send_cmd("AT+CPMS?","+CPMS:",200)==0)        //查询优选消息存储器
  463.                         {
  464.                                 p1=(u8*)strstr((const char*)(USART3_RX_BUF),",");
  465.                                 p2=(u8*)strstr((const char*)(p1+1),",");
  466.                                 p2[0]='/';
  467.                                 if(p2[3]==',')//小于64K SIM卡,最多存储几十条短信
  468.                                 {
  469.                                         msgmaxnum=(p2[1]-'0')*10+p2[2]-'0';                //获取最大存储短信条数
  470.                                         p2[3]=0;
  471.                                 }else //如果是64K SIM卡,则能存储100条以上的信息
  472.                                 {
  473.                                         msgmaxnum=(p2[1]-'0')*100+(p2[2]-'0')*10+p2[3]-'0';//获取最大存储短信条数
  474.                                         p2[4]=0;
  475.                                 }
  476.                                 sprintf((char*)p,"%s",p1+1);
  477.                                 Show_Str(30+17*8,50,200,16,p,16,0);
  478.                                 USART3_RX_STA=0;               
  479.                         }
  480.                 }       
  481.                 if((timex%20)==0)LED0=!LED0;//200ms闪烁
  482.                 timex++;
  483.                 delay_ms(10);
  484.                 if(USART3_RX_STA&0X8000)sim_at_response(1);//检查从GSM模块接收到的数据
  485.         }
  486.         myfree(SRAMIN,p);
  487. }
  488. //测试短信发送内容(70个字[UCS2的时候,1个字符/数字都算1个字])
  489. const u8* sim900a_test_msg="您好,这是一条测试短信,由ATK-SIM900A GSM模块发送,模块购买地址:http://eboard.taobao.com,谢谢支持!";
  490. //SIM900A发短信测试
  491. void sim900a_sms_send_test(void)
  492. {
  493.         u8 *p,*p1,*p2;
  494.         u8 phonebuf[20];                 //号码缓存
  495.         u8 pohnenumlen=0;                //号码长度,最大15个数
  496.         u8 timex=0;
  497.         u8 key=0;
  498.         u8 smssendsta=0;                //短信发送状态,0,等待发送;1,发送失败;2,发送成功
  499.         p=mymalloc(SRAMIN,100);        //申请100个字节的内存,用于存放电话号码的unicode字符串
  500.         p1=mymalloc(SRAMIN,300);//申请300个字节的内存,用于存放短信的unicode字符串
  501.         p2=mymalloc(SRAMIN,100);//申请100个字节的内存 存放:AT+CMGS=p1
  502.         LCD_Clear(WHITE);  
  503.         POINT_COLOR=RED;
  504.         Show_Str_Mid(0,30,"ATK-SIM900A 发短信测试",16,240);                                             
  505.         Show_Str(30,50,200,16,"发送给:",16,0);          
  506.         Show_Str(30,70,200,16,"状态:",16,0);
  507.         Show_Str(30,90,200,16,"内容:",16,0);  
  508.         POINT_COLOR=BLUE;
  509.         Show_Str(30+40,70,170,90,"等待发送",16,0);//显示状态       
  510.         Show_Str(30+40,90,170,90,(u8*)sim900a_test_msg,16,0);//显示短信内容               
  511.         kbd_fn_tbl[0]="发送";
  512.         kbd_fn_tbl[1]="返回";
  513.         sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);//显示键盘
  514.         while(1)
  515.         {
  516.                 key=sim900a_get_keynum(0,180);
  517.                 if(key)
  518.                 {   
  519.                         if(smssendsta)
  520.                         {
  521.                                 smssendsta=0;
  522.                                 Show_Str(30+40,70,170,90,"等待发送",16,0);//显示状态       
  523.                         }
  524.                         if(key<10||key==11)
  525.                         {
  526.                                 if(pohnenumlen<15)
  527.                                 {
  528.                                         phonebuf[pohnenumlen++]=kbd_tbl[key-1][0];
  529.                                         u3_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]);
  530.                                 }
  531.                         }else
  532.                         {
  533.                                 if(key==13)if(pohnenumlen)pohnenumlen--;//删除  
  534.                                 if(key==14&&pohnenumlen)                                //执行发送短信
  535.                                 {  
  536.                                         Show_Str(30+40,70,170,90,"正在发送",16,0);                        //显示正在发送               
  537.                                         smssendsta=1;                 
  538.                                         sim900a_unigbk_exchange(phonebuf,p,1);                                //将电话号码转换为unicode字符串
  539.                                         sim900a_unigbk_exchange((u8*)sim900a_test_msg,p1,1);//将短信内容转换为unicode字符串.
  540.                                         sprintf((char*)p2,"AT+CMGS=\"%s\"",p);
  541.                                         if(sim900a_send_cmd(p2,">",200)==0)                                        //发送短信命令+电话号码
  542.                                         {                                                                                                                                                            
  543.                                                 u3_printf("%s",p1);                                                                 //发送短信内容到GSM模块
  544.                                                 if(sim900a_send_cmd((u8*)0X1A,"+CMGS:",1000)==0)smssendsta=2;//发送结束符,等待发送完成(最长等待10秒钟,因为短信长了的话,等待时间会长一些)
  545.                                         }  
  546.                                         if(smssendsta==1)Show_Str(30+40,70,170,90,"发送失败",16,0);        //显示状态
  547.                                         else Show_Str(30+40,70,170,90,"发送成功",16,0);                                //显示状态       
  548.                                         USART3_RX_STA=0;
  549.                                 }
  550.                                 if(key==15)break;
  551.                         }
  552.                         phonebuf[pohnenumlen]=0;
  553.                         LCD_Fill(30+54,50,239,50+16,WHITE);
  554.                         Show_Str(30+54,50,156,16,phonebuf,16,0);         
  555.                 }
  556.                 if((timex%20)==0)LED0=!LED0;//200ms闪烁
  557.                 timex++;
  558.                 delay_ms(10);
  559.                 if(USART3_RX_STA&0X8000)sim_at_response(1);//检查从GSM模块接收到的数据
  560.         }
  561.         myfree(SRAMIN,p);
  562.         myfree(SRAMIN,p1);
  563.         myfree(SRAMIN,p2);
  564. }
  565. //sms测试主界面
  566. void sim900a_sms_ui(u16 x,u16 y)
  567. {
  568.         LCD_Clear(WHITE);
  569.         POINT_COLOR=RED;
  570.         Show_Str_Mid(0,y,"ATK-SIM900A 短信测试",16,240);  
  571.         Show_Str(x,y+40,200,16,"请选择:",16,0);                                              
  572.         Show_Str(x,y+60,200,16,"KEY0:读短信测试",16,0);                                              
  573.         Show_Str(x,y+80,200,16,"KEY1:发短信测试",16,0);                                             
  574.         Show_Str(x,y+100,200,16,"KEY_UP:返回上级菜单",16,0);
  575. }
  576. //sim900a短信测试
  577. //用于读短信或者发短信
  578. //返回值:0,正常
  579. //    其他,错误代码
  580. u8 sim900a_sms_test(void)
  581. {
  582.         u8 key;
  583.         u8 timex=0;
  584.         if(sim900a_send_cmd("AT+CMGF=1","OK",200))return 1;                        //设置文本模式
  585.         if(sim900a_send_cmd("AT+CSCS=\"UCS2\"","OK",200))return 2;        //设置TE字符集为UCS2
  586.         if(sim900a_send_cmd("AT+CSMP=17,0,2,25","OK",200))return 3;        //设置短消息文本模式参数
  587.         sim900a_sms_ui(40,30);
  588.         while(1)
  589.         {
  590.                 key=KEY_Scan(0);
  591.                 if(key==KEY0_PRES)
  592.                 {
  593.                         sim900a_sms_read_test();
  594.                         sim900a_sms_ui(40,30);
  595.                         timex=0;
  596.                 }else if(key==KEY1_PRES)
  597.                 {
  598.                         sim900a_sms_send_test();
  599.                         sim900a_sms_ui(40,30);
  600.                         timex=0;                       
  601.                 }else if(key==WKUP_PRES)break;
  602.                 timex++;
  603.                 if(timex==20)
  604.                 {
  605.                         timex=0;
  606.                         LED0=!LED0;
  607.                 }
  608.                 delay_ms(10);
  609.                 sim_at_response(1);                                                                                //检查GSM模块发送过来的数据,及时上传给电脑
  610.         }
  611.         sim900a_send_cmd("AT+CSCS=\"GSM\"","OK",200);                                //设置默认的GSM 7位缺省字符集
  612.         return 0;
  613. }
  614. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  615. const u8 *modetbl[2]={"TCP","UDP"};//连接模式
  616. //tcp/udp测试
  617. //带心跳功能,以维持连接
  618. //mode:0:TCP测试;1,UDP测试)
  619. //ipaddr:ip地址
  620. //port:端口
  621. void sim900a_tcpudp_test(u8 mode,u8* ipaddr,u8* port)
  622. {
  623.         u8 *p,*p1,*p2,*p3;
  624.         u8 key;
  625.         u16 timex=0;
  626.         u8 count=0;
  627.         const u8* cnttbl[3]={"正在连接","连接成功","连接关闭"};
  628.         u8 connectsta=0;                        //0,正在连接;1,连接成功;2,连接关闭;
  629.         u8 hbeaterrcnt=0;                        //心跳错误计数器,连续5次心跳信号无应答,则重新连接
  630.         u8 oldsta=0XFF;
  631.         p=mymalloc(SRAMIN,100);                //申请100字节内存
  632.         p1=mymalloc(SRAMIN,100);        //申请100字节内存
  633.         LCD_Clear(WHITE);  
  634.         POINT_COLOR=RED;
  635.         if(mode)Show_Str_Mid(0,30,"ATK-SIM900A UDP连接测试",16,240);
  636.         else Show_Str_Mid(0,30,"ATK-SIM900A TCP连接测试",16,240);
  637.         Show_Str(30,50,200,16,"KEY_UP:退出测试  KEY0:发送数据",12,0);        
  638.         sprintf((char*)p,"IP地址:%s 端口:%s",ipaddr,port);
  639.         Show_Str(30,65,200,12,p,12,0);                        //显示IP地址和端口       
  640.         Show_Str(30,80,200,12,"状态:",12,0);         //连接状态
  641.         Show_Str(30,100,200,12,"发送数据:",12,0);         //连接状态
  642.         Show_Str(30,115,200,12,"接收数据:",12,0);        //端口固定为8086
  643.         POINT_COLOR=BLUE;
  644.         USART3_RX_STA=0;
  645.         sprintf((char*)p,"AT+CIPSTART=\"%s\",\"%s\",\"%s\"",modetbl[mode],ipaddr,port);
  646.         if(sim900a_send_cmd(p,"OK",500))return;                //发起连接
  647.         while(1)
  648.         {
  649.                 key=KEY_Scan(0);
  650.                 if(key==WKUP_PRES)//退出测试                 
  651.                 {  
  652.                         sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",500);        //关闭连接
  653.                         sim900a_send_cmd("AT+CIPSHUT","SHUT OK",500);                //关闭移动场景
  654.                         break;                                                                                                 
  655.                 }else if(key==KEY0_PRES&(hbeaterrcnt==0))                                //发送数据(心跳正常时发送)
  656.                 {
  657.                         Show_Str(30+30,80,200,12,"数据发送中...",12,0);                 //提示数据发送中
  658.                         if(sim900a_send_cmd("AT+CIPSEND",">",500)==0)                //发送数据
  659.                         {
  660.                                 printf("CIPSEND DATA:%s\r\n",p1);                                 //发送数据打印到串口
  661.                                 u3_printf("%s\r\n",p1);
  662.                                 delay_ms(10);
  663.                                 if(sim900a_send_cmd((u8*)0X1A,"SEND OK",1000)==0)Show_Str(30+30,80,200,12,"数据发送成功!",12,0);//最长等待10s
  664.                                 else Show_Str(30+30,80,200,12,"数据发送失败!",12,0);
  665.                                 delay_ms(1000);
  666.                         }else sim900a_send_cmd((u8*)0X1B,0,0);        //ESC,取消发送
  667.                         oldsta=0XFF;                       
  668.                 }
  669.                 if((timex%20)==0)
  670.                 {
  671.                         LED0=!LED0;
  672.                         count++;       
  673.                         if(connectsta==2||hbeaterrcnt>8)//连接中断了,或者连续8次心跳没有正确发送成功,则重新连接
  674.                         {
  675.                                 sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",500);        //关闭连接
  676.                                 sim900a_send_cmd("AT+CIPSHUT","SHUT OK",500);                //关闭移动场景
  677.                                 sim900a_send_cmd(p,"OK",500);                                                //尝试重新连接
  678.                                 connectsta=0;       
  679.                                 hbeaterrcnt=0;
  680.                         }
  681.                         sprintf((char*)p1,"ATK-SIM900A %s测试 %d  ",modetbl[mode],count);
  682.                         Show_Str(30+54,100,200,12,p1,12,0);
  683.                 }
  684.                 if(connectsta==0&&(timex%200)==0)//连接还没建立的时候,每2秒查询一次CIPSTATUS.
  685.                 {
  686.                         sim900a_send_cmd("AT+CIPSTATUS","OK",500);        //查询连接状态
  687.                         if(strstr((const char*)USART3_RX_BUF,"CLOSED"))connectsta=2;
  688.                         if(strstr((const char*)USART3_RX_BUF,"CONNECT OK"))connectsta=1;
  689.                 }
  690.                 if(connectsta==1&&timex>=600)//连接正常的时候,每6秒发送一次心跳
  691.                 {
  692.                         timex=0;
  693.                         if(sim900a_send_cmd("AT+CIPSEND",">",200)==0)//发送数据
  694.                         {
  695.                                 sim900a_send_cmd((u8*)0X00,0,0);        //发送数据:0X00  
  696.                                 delay_ms(20);                                                //必须加延时
  697.                                 sim900a_send_cmd((u8*)0X1A,0,0);        //CTRL+Z,结束数据发送,启动一次传输       
  698.                         }else sim900a_send_cmd((u8*)0X1B,0,0);        //ESC,取消发送                
  699.                                
  700.                         hbeaterrcnt++;
  701.                         printf("hbeaterrcnt:%d\r\n",hbeaterrcnt);//方便调试代码
  702.                 }
  703.                 delay_ms(10);
  704.                 if(USART3_RX_STA&0X8000)                //接收到一次数据了
  705.                 {
  706.                         USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;        //添加结束符
  707.                         printf("%s",USART3_RX_BUF);                                //发送到串口  
  708.                         if(hbeaterrcnt)                                                        //需要检测心跳应答
  709.                         {
  710.                                 if(strstr((const char*)USART3_RX_BUF,"SEND OK"))hbeaterrcnt=0;//心跳正常
  711.                         }                               
  712.                         p2=(u8*)strstr((const char*)USART3_RX_BUF,"+IPD");
  713.                         if(p2)//接收到TCP/UDP数据
  714.                         {
  715.                                 p3=(u8*)strstr((const char*)p2,",");
  716.                                 p2=(u8*)strstr((const char*)p2,":");
  717.                                 p2[0]=0;//加入结束符
  718.                                 sprintf((char*)p1,"收到%s字节,内容如下",p3+1);//接收到的字节数
  719.                                 LCD_Fill(30+54,115,239,130,WHITE);
  720.                                 POINT_COLOR=BRED;
  721.                                 Show_Str(30+54,115,156,12,p1,12,0); //显示接收到的数据长度
  722.                                 POINT_COLOR=BLUE;
  723.                                 LCD_Fill(30,130,210,319,WHITE);
  724.                                 Show_Str(30,130,180,190,p2+1,12,0); //显示接收到的数据
  725.                         }
  726.                         USART3_RX_STA=0;
  727.                 }
  728.                 if(oldsta!=connectsta)
  729.                 {
  730.                         oldsta=connectsta;
  731.                         LCD_Fill(30+30,80,239,80+12,WHITE);
  732.                         Show_Str(30+30,80,200,12,(u8*)cnttbl[connectsta],12,0); //更新状态
  733.                 }
  734.                 timex++;
  735.         }
  736.         myfree(SRAMIN,p);
  737.         myfree(SRAMIN,p1);
  738. }
  739. //gprs测试主界面
  740. void sim900a_gprs_ui(void)
  741. {
  742.         LCD_Clear(WHITE);  
  743.         POINT_COLOR=RED;
  744.         Show_Str_Mid(0,30,"ATK-SIM900A GPRS通信测试",16,240);         
  745.         Show_Str(30,50,200,16,"KEY_UP:连接方式切换",16,0);                 
  746.         Show_Str(30,90,200,16,"连接方式:",16,0);         //连接方式通过KEY_UP设置(TCP/UDP)
  747.         Show_Str(30,110,200,16,"IP地址:",16,0);                //IP地址可以键盘设置
  748.         Show_Str(30,130,200,16,"端口:",16,0);                //端口固定为8086
  749.         kbd_fn_tbl[0]="连接";
  750.         kbd_fn_tbl[1]="返回";
  751.         sim900a_load_keyboard(0,180,(u8**)kbd_tbl2);//显示键盘
  752. }
  753. //sim900a GPRS测试
  754. //用于测试TCP/UDP连接
  755. //返回值:0,正常
  756. //    其他,错误代码
  757. u8 sim900a_gprs_test(void)
  758. {
  759.         const u8 *port="8086";        //端口固定为8086,当你的电脑8086端口被其他程序占用的时候,请修改为其他空闲端口
  760.         u8 mode=0;                                //0,TCP连接;1,UDP连接
  761.         u8 key;
  762.         u8 timex=0;
  763.         u8 ipbuf[16];                 //IP缓存
  764.         u8 iplen=0;                        //IP长度
  765.         sim900a_gprs_ui();        //加载主界面
  766.         Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0);        //显示连接方式       
  767.         Show_Str(30+40,130,200,16,(u8*)port,16,0);                        //显示端口        
  768.         sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",100);        //关闭连接
  769.         sim900a_send_cmd("AT+CIPSHUT","SHUT OK",100);                //关闭移动场景
  770.         if(sim900a_send_cmd("AT+CGCLASS=\"B\"","OK",1000))return 1;                                //设置GPRS移动台类别为B,支持包交换和数据交换
  771.         if(sim900a_send_cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000))return 2;//设置PDP上下文,互联网接协议,接入点等信息
  772.         if(sim900a_send_cmd("AT+CGATT=1","OK",500))return 3;                                        //附着GPRS业务
  773.         if(sim900a_send_cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500))return 4;                 //设置为GPRS连接模式
  774.         if(sim900a_send_cmd("AT+CIPHEAD=1","OK",500))return 5;                                         //设置接收数据显示IP头(方便判断数据来源)
  775.         ipbuf[0]=0;                
  776.         while(1)
  777.         {
  778.                 key=KEY_Scan(0);
  779.                 if(key==WKUP_PRES)                 
  780.                 {  
  781.                         mode=!mode;                //连接模式切换
  782.                         Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0);         //显示连接模式
  783.                 }
  784.                 key=sim900a_get_keynum(0,180);
  785.                 if(key)
  786.                 {   
  787.                         if(key<12)
  788.                         {
  789.                                 if(iplen<15)
  790.                                 {
  791.                                         ipbuf[iplen++]=kbd_tbl[key-1][0];
  792.                                         u3_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]);
  793.                                 }
  794.                         }else
  795.                         {
  796.                                 if(key==13)if(iplen)iplen--;        //删除  
  797.                                 if(key==14&&iplen)                                //执行GPRS连接
  798.                                 {   
  799.                                         sim900a_tcpudp_test(mode,ipbuf,(u8*)port);
  800.                                         sim900a_gprs_ui();                        //加载主界面
  801.                                         Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0);         //显示连接模式
  802.                                         Show_Str(30+40,130,200,16,(u8*)port,16,0);//显示端口        
  803.                                         USART3_RX_STA=0;
  804.                                 }
  805.                                 if(key==15)break;
  806.                         }
  807.                         ipbuf[iplen]=0;
  808.                         LCD_Fill(30+56,110,239,110+16,WHITE);
  809.                         Show_Str(30+56,110,200,16,ipbuf,16,0);                        //显示IP地址        
  810.                 }
  811.                 timex++;
  812.                 if(timex==20)
  813.                 {
  814.                         timex=0;
  815.                         LED0=!LED0;
  816.                 }
  817.                 delay_ms(10);
  818.                 sim_at_response(1);//检查GSM模块发送过来的数据,及时上传给电脑
  819.         }
  820.         return 0;
  821. }
  822. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  823. //ATK-SIM900A GSM/GPRS主测试控制部分

  824. //测试界面主UI
  825. void sim900a_mtest_ui(u16 x,u16 y)
  826. {
  827.         u8 *p,*p1,*p2;
  828.         p=mymalloc(SRAMIN,50);//申请50个字节的内存
  829.         LCD_Clear(WHITE);
  830.         POINT_COLOR=RED;
  831.         Show_Str_Mid(0,y,"ATK-SIM900A 测试程序",16,240);  
  832.         Show_Str(x,y+25,200,16,"请选择:",16,0);                                              
  833.         Show_Str(x,y+45,200,16,"KEY0:拨号测试",16,0);                                              
  834.         Show_Str(x,y+65,200,16,"KEY1:短信测试",16,0);                                             
  835.         Show_Str(x,y+85,200,16,"KEY_UP:GPRS测试",16,0);
  836.         POINT_COLOR=BLUE;        
  837.         USART3_RX_STA=0;
  838.         if(sim900a_send_cmd("AT+CGMI","OK",200)==0)                                //查询制造商名称
  839.         {
  840.                 p1=(u8*)strstr((const char*)(USART3_RX_BUF+2),"\r\n");
  841.                 p1[0]=0;//加入结束符
  842.                 sprintf((char*)p,"制造商:%s",USART3_RX_BUF+2);
  843.                 Show_Str(x,y+110,200,16,p,16,0);
  844.                 USART3_RX_STA=0;               
  845.         }
  846.         if(sim900a_send_cmd("AT+CGMM","OK",200)==0)//查询模块名字
  847.         {
  848.                 p1=(u8*)strstr((const char*)(USART3_RX_BUF+2),"\r\n");
  849.                 p1[0]=0;//加入结束符
  850.                 sprintf((char*)p,"模块型号:%s",USART3_RX_BUF+2);
  851.                 Show_Str(x,y+130,200,16,p,16,0);
  852.                 USART3_RX_STA=0;               
  853.         }
  854.         if(sim900a_send_cmd("AT+CGSN","OK",200)==0)//查询产品序列号
  855.         {
  856.                 p1=(u8*)strstr((const char*)(USART3_RX_BUF+2),"\r\n");//查找回车
  857.                 p1[0]=0;//加入结束符
  858.                 sprintf((char*)p,"序列号:%s",USART3_RX_BUF+2);
  859.                 Show_Str(x,y+150,200,16,p,16,0);
  860.                 USART3_RX_STA=0;               
  861.         }
  862.         if(sim900a_send_cmd("AT+CNUM","+CNUM",200)==0)                        //查询本机号码
  863.         {
  864.                 p1=(u8*)strstr((const char*)(USART3_RX_BUF),",");
  865.                 p2=(u8*)strstr((const char*)(p1+2),"\"");
  866.                 p2[0]=0;//加入结束符
  867.                 sprintf((char*)p,"本机号码:%s",p1+2);
  868.                 Show_Str(x,y+170,200,16,p,16,0);
  869.                 USART3_RX_STA=0;               
  870.         }
  871.         myfree(SRAMIN,p);
  872. }
  873. //GSM信息显示(信号质量,电池电量,日期时间)
  874. //返回值:0,正常
  875. //    其他,错误代码
  876. u8 sim900a_gsminfo_show(u16 x,u16 y)
  877. {
  878.         u8 *p,*p1,*p2;
  879. ……………………

  880. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
战舰开发板SIM900A GSM模块测试实验.rar (1.59 MB, 下载次数: 32)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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