SIM900A拨打电话核心代码

萌到你眼炸
595次浏览
2021年02月20日 07:04
最佳经验
本文由作者推荐

-

2021年2月20日发(作者:美容院的经营)


SIM900A


手机模块的


3


大功能:接拨电话,收发短信和


TCP/UDP


通信。 现在的手机基本上


可以不叫手机了,真正的手机功能(前面所说的


3


大功能)占用不到


1/5


的主机资 源。其实


手机的工作原理非常简单,


就是一个主机与从机



sim900a


之类的

DSP



MCU



之间的串口


通信,主机向从机发送指令,从机响应指令发回响应值,然后在


LCD


上显示相应的界面。







原子的例程仅仅是最简单的芯片测试程序,


不足很多,


离以前的功能机的功能还差老远。


比如:


1


,接拨电话,收发短信和


TCP/UDP


通 信这三个任务间没有通信机制,收到短信时不


能自动切换到收发短信界面;正常情况下最 好是处于待机等待拨号界面;


2


,没有通话计时


功能;


3


,只能发固定内容的短信即不能自由编辑短信 内容发送;


4


,没有通话记录功能等;


5


,没有电话薄功能。这些功能貌似很简单,实施起来不容易。最近一直在想以前那些简 单


功能手机(不带操作系统)各种功能任务是如何调度的程序上是怎样实现的。我的想法 是,



stm32


作为主机加入文件系 统和


ucosii


操作系统与


SIM9 00A


芯片构成一个简单的智能手


机。就当是自娱自乐吧!





SIM900A


手机模块



拨号测试函数


“u8 sim900a_call_test( void)”


是本例程的核心代码;本人


做了非常详细的注解, 贴出来方便自己随时登陆温故学习。也供同道中人参考。




//


SIM900A


手机模块



拨号测试函数


“u8 sim900a_call_test(void)”



//


拨号测试部分代码



//sim900a


拨号测试



//


用于拨打电话和接听电话



//


返回值


:0,


正 常



//


其他


,


错误代码



u8 sim900a_call_test(void)


{






u8 key;






u16 lenx;






u8 callbuf[20];




u8 wangyan[]={


向 自己的手机拨号


,


因为程序中是把手机号码当作字符处理,所以 要加英文引号







u8 pohnenumlen=0;





//


号码长度

,


最大


15


个数,如



callbuf[pohnenumlen]; usart


通信时电话号码就是


ASCII


码;







u8 *p,*p1,*p2;






u8 oldmode=0;






u8 cmode=0;





/*


模式


0:


等待拨号;模式


1:


拨号中;模式


2:


通话中;模式


3:


接收到来电,共


4< /p>


种情况



*/






LCD_Clear(WHITE);






if(sim900a_send_cmd(





//


设置来电显示







if(sim900a_send_cmd(





//


设置被叫号码显示







p1=mymalloc(SRAMIN,20);





//


申请


20


个字节直接用于存放


SIM9 00A


模块返回的来电电话号码,


usart

< br>通信时电话号


码就是


ASCII


码;







if(p1==NULL)return 2;









POINT_COLOR=RED;






Show_Str_Mid(0,30,


拨号测试


























Show_Str(40,7 0,200,16,


请拨号


:






kbd_fn_tbl[0]=


拨号







kbd_fn_tbl[1]=


返回







sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);/*


加载拨号键盘界面,由此可见进入什么功能就加载相应的界面


*/







POINT_COLOR=BLUE;






while(1)






{


if(KEY_LEFT==KEY_Scan(0)) u2_printf(










delay_ms(10);










if(USART2_RX_STA&0X8000)





/*


以下凡是受此


if


语句控制范围的语句都是基于已经接收到


sim900a


模块返


回的数据,


*/










{














sim_at_response(0); /* mode:0,


不清零


USART2_RX_STA;


将收到的来自


sim900a


模块的


AT


指令应答数据返


回给电脑串口



*/















if(cmode==1||cmode==2)/*


首次进入时


cmode



0


,模式


0:


等待拨号;模式


1:


拨 号中;模式


2:


通话中;模式


3:


接收到来电


*/














{/*


首先发送:


ATE1


,设置回显,再发送:


AT+COLP=1


,设 置被叫号码显示。然后发送:


ATD10086;


,拨



10086


,在接通后,

SIM900A


模块返回:


+COLP:



,此时,我们就可以听到中国移动那熟悉的声音了


….


待一


堆废话结束后,我们发送:


AT+ VTS=1


,即可查询本机电话号码。最后,通过发送:


ATH


,挂断,结束本次



*/







if(cmode==1)if(sim900a_check_cmd(





//


拨号成功



















if(sim900a_check_cmd(





//


拨号失败



















if(sim900a_check_cmd(





//


拨号失败



















if(sim900a_check_cmd(









//


拨号失败















}














if(sim900a_check_cmd(

< p>
接收到来电,



如果返回值是

+CLIP:


则表示接收到来电



*/














{/*


的含义是:设置提示来电号码,带来电显示时的返回值格式是:





取值列表)






AT

< br>命令手册


P59









AT+CLIP


用于设置来电显示,通过发送:


AT+CL IP=1


,可以实现设置来电显示功能,模块接收到来电的时候,


会返回来电号码。并且可以在串口接收到来电号码,如:


+CLIP:


,表示当前接入号码为:





此时,我们发送:


ATA


,即可接听来 电,并进行通话。当对方挂断电话的时候,


SIM900A


模块 会返回:


NO


CARRIER


,并结 束


此次通话


;


当然,我们也可以通过发 送:


ATH


,来主动结束通话。


*/


















cmode=3; /*


模式


0:< /p>


等待拨号;模式


1:


拨号中;模式


2:


通话中;模式


3:


接收到来电


*/


















p=sim900a_che ck_cmd(


将接收到的



字符串(即 来自模块返回值)存储到


P */


















p+=8; /*


将模块返回的来电号码存储在(


P+8


)处,


p+8,


就是 偏移


8


个字节


,


不是一共


8


个内存空间



*/














p2=(u8*)strstr((const char *)p,


在(


P+8


)处开始,找到第一个出现





符号(每个字符串结束符





















都有





符 号)


的位置,实际上就是从模块返回值中取得电话号码;


并将电 话号码存储到


P2



始处


*/







p2[0]=0; /*


添加结束符。字符串的结束符是


'0'

< br>也是


0



p2=(u8*)st rstr((const char*)(p1),


指定结束符的位置



*/


















/*


上面两步的作用是给字符串加上




0”


这个字符串末尾标志


*/


















strcpy((char*)p1,(char*)p);/*

字符串


P


复制到


P1


,用于下面


case3


语句显示


*/















}














USART2_RX_STA=0;

/*













便





2









< br>“if(USART2_RX_STA==0)TIM4_Set(1)”


语句< /p>


*/










} /*



sim900a


返回值的处理部分到此结束



;*/


/*


上面部分的语句主要是 对


sim900a


返回值的处理,并根据返回值的情况定义


4


种工作状态:模式


0:

< br>等待拨号;模式


1:


拨号中;


模 式


2:


通话中;模式


3:


接收到来电



*/











key=sim900a_get_keynum(0,180);/*


检测是哪个触 摸键被按下,下面根据对触摸键触摸情况、对相关功能进行处理



*/










if(key) /*


下面的操作都是基于触摸键有被按下


*/










{














if(key<13)














{















if(cmode==0&&pohnenumlen<15) /*

< br>模式


0



等待拨号且

< p>
pohnenumlen


对应的键值小于


15



首次进入时是


0


*/















{

















callbuf[pohnenumlen++]= kbd_tbl[key-1][0];/*


执行


pohnen umlen++


的条件是必须有触摸键按下



*/





/*


二维数组

< br>kbd_tbl[key-1][0]


实际上等价于


kb d_tbl[key-1]


;本句的作用是将被按下的触屏键值即对应的字符存储到


callbuf[pohnenumlen++] */







/*


假设

< br>i=3



j=1


,则

< p>
key==11



key[1][3]

< p>


x


轴第二格,


y


轴第


4


格,该处就是存放

“11” */


















u2_printf(


/*


参考


AT


命令手册

P126



测试


DTMF


音,


时长


2





将命令和键值发送给模块,


功能:


每拨一个数字键


(只



0-9


号数字键有效)耳机发出相应的拨号音

< br>*/


















}else if(cmode==2)//


通话中,主叫拨通了通话中



















{






















u2_printf(






















delay_ms(100);






















u2_printf(






















LCD_ShowChar( 40+56,90,kbd_tbl[key-1][0],16,0);










/*




请拨号



后面显示按下的键值,即显示 拨号键



*/


















}














}else














{


















if(key==13)if(pohnenumlen& &cmode==0)pohnenumlen--;



/*


删除;


1



如果


pohnenumlen==0



则说明


callbuf[pohnenumlen]


数组中没 有存放任何号码,


所以就不必执行


“pohnenumlen< /p>


--


;”


2



“cmode==0”


即等待拨号模式;

3


,通过对数组下表的加减就可以增删数组元素;如,本例中通过执行


“pohnenumlen


--


;”


操作,就



callbuf[pohnenumlen ]


数组元素做了增删,重要!



*/


















if(key==14)//


执行拨号



















{






















if(cmode==0)/*


拨 号模式;如果按了拨号键且处于等待拨号模式


*/






















{


























callbuf[pohnenumlen]=0;/*< /p>


最后加入结束符


,


字符串结束符是




0”


也是


“0” */























//





u2_printf(


拨号,号码就是


callbuf


存储的内容



*/










u2_printf(









/*


给自己拨号拨号,号码就是


wa ngyan


存储的内容即



;当按下



拨号



键时,相 应的手机就接到了本


机的来电



*/


























cmode=1;




//


拨号中模式


1:57:01


星期三



2014


8



6
























}else /*


如果按了拨号键


key14*/






















{

-


-


-


-


-


-


-


-