📄 at.c
字号:
{NULL,NULL},
};
//***********************************************************************************************************************
//函数作用:分析AT消息
//参数说明:无
//注意事项:
//返回说明:
//***********************************************************************************************************************
static void at_parse_msg(void)
{
at_msglist_t *list;
//数据包列表中查找并且调用相应处理函数
for(list=at_msglist;list->cmdstr!=NULL;list++)
{
//找到了以后 调用相应函数
if(str_comprise(at_receive_buffer,list->cmdstr))
{
list->callback();//调用相应函数
return;
}
}
}
//***********************************************************************************************************************
//函数作用:处理AT回应数据包
//参数说明:无
//注意事项:
//返回说明:无
//***********************************************************************************************************************
static void ATAnalyse(void)
{
if(!at_get_msg())return;//接收消息
//if(at_debug==1)//调试信息
//{
// print_line(at_receive_buffer);
//}
at_parse_msg();//分析消息
}
//*****************************************************************************************
//函数作用:等待回应
//参数说明:
//注意事项:
//返回说明:如果等到OK返回1
//*****************************************************************************************
static uchar at_wait_ack(uint wait_time, uchar ack_no)
{
at_ack=0;
while(!at_ack)//等返回
{
mdelay(20);
ATAnalyse();
if(wait_time&0x01)LED_CTRL=!LED_CTRL;
if(--wait_time==0)break;//超时退出
}
if(at_ack==ack_no)return 1;
return 0;
}
//*****************************************************************************************
//函数作用:等待ok
//参数说明:
//注意事项:
//返回说明:如果等到OK返回1
//*****************************************************************************************
static uchar at_wait_ok(void)
{
return at_wait_ack(500,AT_ACK_OK);
}
//***********************************************************************************************************************
//函数作用:发送AT命令
//参数说明:
//注意事项:
//返回说明:
//***********************************************************************************************************************
static void at_send_command(uchar *command, uchar *param)
{
AT_SEND_STR(AT_CMD_HEAD);
AT_SEND_STR(command);
AT_SEND_STR(param);
AT_SEND_STR(AT_CMD_END);
}
//***********************************************************************************************************************
//函数作用:发送AT命令并且等待OK
//参数说明:
//注意事项:
//返回说明:如果等到ok 返回1
//***********************************************************************************************************************
static uchar at_send_command_waitok(uchar *command, uchar *param)
{
at_send_command(command,param);
return(at_wait_ok());
}
//*****************************************************************************************
//函数作用:发送短信息
//参数说明:
//注意事项:
//返回说明:
//*****************************************************************************************
uchar ATSendSMS(uchar *dest_no, uchar *content_buf, uchar data_coding)
{
uint length;
uchar i;
uchar MoveTemp;
uchar temp_buf[16];
if(at_reset)return 0;
delay(1);//防止连续发送短信
//发送头
AT_SEND_STR(AT_CMD_HEAD);
AT_SEND_STR(AT_CMD_SENDSMS);
//发送PDU包长度
length=str_length(dest_no);//对方号码长度
if(length&0x01)length++;//修正奇偶
length+=20;//其他字节固定长度
if(data_coding==0x00)//英文
{
i=0;
while(content_buf[i]!=0)
{
MoveTemp=content_buf[i+1]<<(7-i%8);
MoveTemp+=(content_buf[i]>>i%8);
i++;
length+=2;
if(((i+1)%8)==0)if(content_buf[i])i++;
}
}
else if(data_coding==0x08)//中文
{
length+=str_length(content_buf);
}
int_to_dec(temp_buf,(length>>1)-1);//转化为十进制 并且修正为字节长度 然后减1
AT_SEND_STR(temp_buf);//发送
AT_SEND_CHAR('\r');
//等待 "> "
mdelay(100);
//状态报告码
AT_SEND_STR("001100");
//号码长度
length=str_length(dest_no)+2;//号码长度+86的长度
char_to_hex(temp_buf,length);//转化为hex字符串
AT_SEND_STR(temp_buf);//发送
//号码属性--国际号码
AT_SEND_STR("91");//发送
//号码内容 奇偶数修正-F 并且高低字节对调
str_copy(temp_buf,"86");//国家代码--中国地区
str_cat(temp_buf,dest_no);//拷贝号码
if(length&0x01)str_cat(temp_buf,"F");//修正奇偶
swap_low4_and_high4(temp_buf,length);//高低字节对调
AT_SEND_STR(temp_buf);//发送
//PID
AT_SEND_STR("00");
//编码方式
char_to_hex(temp_buf,data_coding);//转化为hex字符串
AT_SEND_STR(temp_buf);//发送
//有效期
AT_SEND_STR("8F");//发送
//内容长度
length=str_length(content_buf);//计算内容缓冲区长度
if(data_coding==0x08)length>>=1;//如果是中文把字符串长度转化字节长度--除以2
char_to_hex(temp_buf,length);//转化为hex字符串
AT_SEND_STR(temp_buf);//发送
//真正的内容
if(data_coding==0x00)//英文
{
uchar MoveTemp;
uchar i=0,j=0;
while(content_buf[i]!=0)
{
MoveTemp=content_buf[i+1]<<(7-i%8);
MoveTemp+=(content_buf[i]>>i%8);
Bcd2Char(temp_buf,MoveTemp);//转化为hex
AT_SEND_STR(temp_buf);//发送
i++;
j+=2;
if(((i+1)%8)==0)if(content_buf[i])i++;
}
}
else if(data_coding==0x08)//中文
{
AT_SEND_STR(content_buf);//发送
}
//发送结束符
AT_SEND_CHAR(0x1A);
//等待发送成功
if(!at_wait_ack(1000,AT_ACK_OK))goto error;
return 1;
error:
at_reset=1;
return 0;
}
//***********************************************************************************************************************
//函数作用:应答电话
//参数说明:
//注意事项:
//返回说明:如果等到 返回1
//***********************************************************************************************************************
uchar ATAnswer(void)
{
if(at_send_command_waitok(AT_CMD_ANSWER,""))
{
ring=0;
calling=1;
return 1;
}
return 0;
}
//***********************************************************************************************************************
//函数作用:挂机
//参数说明:
//注意事项:
//返回说明:如果等到 返回1
//***********************************************************************************************************************
uchar ATHangup(void)
{
if(at_send_command_waitok(AT_CMD_HANGUP,""))
{
ring=0;
calling=0;
str_copy(clip_no,"???????????");
return 1;
}
return 0;
}
//***********************************************************************************************************************
//函数作用:切换音频通道
//参数说明:
//注意事项:
//返回说明:如果等到 返回1
//***********************************************************************************************************************
uchar ATSetAC(uchar no)
{
uchar no_buf[2]="1";
no_buf[0]=no;
return at_send_command_waitok(AT_CMD_SWITCHAUDIO,no_buf);
}
//***********************************************************************************************************************
//函数作用:MIC增益
//参数说明:no--MIC号 gain--增益数量字符串 0-15
//注意事项:
//返回说明:如果等到 返回1
//***********************************************************************************************************************
uchar ATSetMic(uchar no, uchar *gain)
{
uchar buf[]="0,10";
buf[0]=no;
str_copy(&buf[2],gain);
return at_send_command_waitok(AT_CMD_MIC,buf);
}
//***********************************************************************************************************************
//函数作用:初始化
//参数说明:
//注意事项:
//返回说明:返回是否有错误 如果有错误送复位标志
//***********************************************************************************************************************
void ATInit(void)
{
uchar wait_time;
//清标志
at_reset=0;//需要复位
simok=0;//sim卡
loginok=0;//登陆成功
smsin=0;//收到短消息
ring=0;//来电
calling=0;//是否通话状态
str_copy(clip_no,"???????????");
//1.上电并初始化端口
print_line("AT重新上电");
AT_POWER_CTRL=0;
delay(2);//等待2秒
AT_PORTINIT(AT_BAUDRATE);//端口初始化
AT_FLUSH();
AT_POWER_CTRL=1;
//2.等待READY
print_line("AT等待RDY");
wait_time=20;//等待10秒
while(!at_wait_ack(30,AT_ACK_OK))
{
at_send_command("","");
if(--wait_time==0)goto error;
}
//3.等待SIM卡检测
print_line("SIM卡检测");
wait_time=100;//等待10秒
while(!simok)
{
ATAnalyse();
mdelay(100);
LED_CTRL=!LED_CTRL;
if(--wait_time==0)goto error;
}
//4.等待登陆网络
print_line("AT登录网络");
if(!at_send_command_waitok(AT_CMD_DISECHO,""))goto error;//关闭命令回显
if(!at_send_command_waitok(AT_CMD_CREG,""))goto error;//主动提供网络注册信息
at_send_command("+COPS=","4,0,\"CHINA MOBILE\"");//手动注册中国移动 如果不成功再自动注册
wait_time=120;//等待120秒
while(!loginok)
{
ATAnalyse();
delay(1);
LED_CTRL=!LED_CTRL;
if(--wait_time==0)goto error;
}
//5.初始化AT命令
print_line("AT设置命令");
if(!at_send_command_waitok(AT_CMD_SMSPDU,""))goto error;//短消息PDU模式
if(!at_send_command_waitok(AT_CMD_SMSTOCOMM,""))goto error;//短消息直接从串口出
if(!at_send_command_waitok(AT_CMD_GSMCHARSET,""))goto error;//设置GSM字符集
if(!at_send_command_waitok(AT_CMD_TCPIPRECEIVEHINT,""))goto error;//设置TCP/IP数据包接收提示
if(!at_send_command_waitok(AT_CMD_TCPIPSENDHINT,""))goto error;//关闭TCPIP数据发送时的 "> " 提示
if(!at_send_command_waitok(AT_CMD_FIXLOCALPORT,""))goto error;//取消固定本地端口号
if(!at_send_command_waitok("+CLIP=1",""))goto error;//开来电显示
if(!ATSetAC('1'))goto error;//切换到免提通道 提供振铃
if(!ATSetMic('0',"12"))goto error;//调节MIC增益
if(!ATSetMic('1',"12"))goto error;//调节MIC增益
//6.等待可以发送短消息了
//print_line("短信初始化");
//wait_time=120;//等待120秒
//while(!at_wait_ack(100,AT_ACK_OK))
//{
// at_send_command(AT_CMD_SMSCENTERNO,"?");
// if(--wait_time==0)goto error;
//}
//delay(5);
//7.正确返回
return;
error:
print_line("失败");
at_reset=1;
}
//***********************************************************************************************************************
//函数作用:AT处理函数
//参数说明:
//注意事项:
//返回说明:
//***********************************************************************************************************************
void ATProcess(void)
{
//初始化
if(at_reset)ATInit();
//接收数据分析
ATAnalyse();
//短信处理
if(smsin)
{
smsin=0;
print_line("GET A SMS");
//判断是否是自定义的有效命令
if(sms_coding==8 && str_compare(at_receive_buffer,"4F60572854EA91CC"))
{
print_line("位置查询短信");
if(!gis_search(at_receive_buffer,gps_longti(),gps_lati()))//查找地图
{
ATSendSMS(sms_no,at_receive_buffer,8);//发送应答
print_line("查询成功");
}
else
{
print_line("查询失败");
}
}
}
//来电处理
if(ring)
{
print_line("GET A CALL");
//判断是否是家人和朋友的号码
if(str_comprise(clip_no,"13389937509"))
{
ATAnswer();
print_line("接听监听电话");
}
else if(str_comprise(clip_no,"13332020931"))
{
ATAnswer();
print_line("接听监听电话");
}
else
{
ATHangup();mdelay(100);ATHangup();
print_line("拒绝接听");
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -