SIM900A拨打电话核心代码
-
SIM900A
手机模块的
3
大功能:接拨电话,收发短信和
TCP/UDP
通信。
现在的手机基本上
可以不叫手机了,真正的手机功能(前面所说的
3
大功能)占用不到
1/5
的主机资
源。其实
手机的工作原理非常简单,
就是一个主机与从机
(
sim900a
之类的
DSP
或
MCU
)
之间的串口
通信,主机向从机发送指令,从机响应指令发回响应值,然后在
p>
LCD
上显示相应的界面。
原子的例程仅仅是最简单的芯片测试程序,
不足很多,
离以前的功能机的功能还差老远。
比如:
1
p>
,接拨电话,收发短信和
TCP/UDP
通
信这三个任务间没有通信机制,收到短信时不
能自动切换到收发短信界面;正常情况下最
好是处于待机等待拨号界面;
2
,没有通话计时
功能;
3
,只能发固定内容的短信即不能自由编辑短信
内容发送;
4
,没有通话记录功能等;
5
,没有电话薄功能。这些功能貌似很简单,实施起来不容易。最近一直在想以前那些简
单
功能手机(不带操作系统)各种功能任务是如何调度的程序上是怎样实现的。我的想法
是,
以
stm32
作为主机加入文件系
统和
ucosii
操作系统与
SIM9
00A
芯片构成一个简单的智能手
机。就当是自娱自乐吧!
p>
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
语句控制范围的语句都是基于已经接收到
p>
sim900a
模块返
回的数据,
*/
{
sim_at_response(0); /*
mode:0,
不清零
USART2_RX_STA;
将收到的来自
sim900a
模块的
AT
指令应答数据返
回给电脑串口
*/
if(cmode==1||cmode==2)/*
首次进入时
cmode
为
0
,模式
0:
等待拨号;模式
1:
拨
号中;模式
2:
通话中;模式
3:
p>
接收到来电
*/
{/*
首先发送:
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(
接收到来电,
如果返回值是
+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;
/*
将
接
收
到
的
数
据
清
零
,
以
便
p>
让
串
口
2
再
次
进
入
中
断
执
行
< br>“if(USART2_RX_STA==0)TIM4_Set(1)”
语句<
/p>
*/
} /*
对
sim900a
返回值的处理部分到此结束
;*/
/*
上面部分的语句主要是
对
sim900a
返回值的处理,并根据返回值的情况定义
p>
4
种工作状态:模式
0:
< br>等待拨号;模式
1:
拨号中;
模
式
2:
通话中;模式
3:
接收到来电
*/
key=sim900a_get_keynum(0,180);/*
检测是哪个触
摸键被按下,下面根据对触摸键触摸情况、对相关功能进行处理
*/
if(key) /*
下面的操作都是基于触摸键有被按下
*/
{
if(key<13)
{
if(cmode==0&&pohnenumlen<15) /*
< br>模式
0
:
等待拨号且
pohnenumlen
对应的键值小于
15
p>
,
首次进入时是
0
*/
{
callbuf[pohnenumlen++]=
kbd_tbl[key-1][0];/*
执行
pohnen
umlen++
的条件是必须有触摸键按下
*/
/*
二维数组
< br>kbd_tbl[key-1][0]
实际上等价于
kb
d_tbl[key-1]
;本句的作用是将被按下的触屏键值即对应的字符存储到
p>
callbuf[pohnenumlen++] */
/*
假设
< br>i=3
,
j=1
,则
key==11
即
key[1][3]
:
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>
最后加入结束符
,
字符串结束符是
p>
“
0”
也是
“0” */
//
u2_printf(
拨号,号码就是
callbuf
存储的内容
*/
u2_printf(
/*
给自己拨号拨号,号码就是
wa
ngyan
存储的内容即
;当按下
p>
“
拨号
”
键时,相
应的手机就接到了本
机的来电
*/
cmode=1;
//
拨号中模式
1:57:01
星期三
2014
年
8
月
6
日
}else /*
如果按了拨号键
key14*/
{