C语言通过串口发送AT指令
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言通过串口发送AT指令相关的知识,希望对你有一定的参考价值。
以下代码是通过串口发送AT指令:
atcmd.c:
#include <stdio.h>
#include <string.h>
#include "atcmd.h"
static HANDLE hCom;
static char com_name[32] = {0};
static int BaudRate;
FILE *fp;
int AT_ComOpen()
{
fp = fopen("debug.txt", "w");
fputs("AT_ComOpen:", fp);
fputs(com_name, fp);
fputs("\n", fp);
fclose(fp);
hCom = SerialOpen(com_name, M_ASYNC);
if(!hCom)
{
printf("串口端口打开失败\n");
return -1;
}
SerialSet(hCom, BaudRate);
return 0;
}
int AT_ComClose()
{
SerialClose(hCom);
return 0;
}
int AT_SendCmd(char *cmd, int len)
{
if(SerialSend(hCom, cmd, len, M_ASYNC) <0)
{
printf("SendCmd Failed\n");
return -1;
}
return 0;
}
int AT_RecvData(char *rdata)
{
SerialRecv(hCom, rdata, M_ASYNC);
return 0;
}
static int ConverToUnicode(char *indata, char *outdata)
{
int len = strlen(indata);
int wlen = sizeof(wchar_t)*len;
int i=0;
char buf[1024];
wchar_t *wch = (wchar_t *)malloc(wlen);
memset(wch, 0, wlen);
MultiByteToWideChar(CP_ACP, 0, indata, len, wch, wlen);
memset(buf, 0, sizeof(buf));
for(i=0; i<len; i++)
{
if(wch[i] == 0)
continue;
sprintf(buf+strlen(buf), "%04x", wch[i]);
}
sprintf(outdata, "%02x", strlen(buf)/2);
strcat(outdata, buf);
free(wch);
return 0;
}
static int phonenum_parity_exchange(char *indata, char *outdata)
{
int i=0;
int len = strlen(indata);
char tmp[16];
int ret = len%2;
memset(tmp, 0, sizeof(tmp));
strcpy(tmp, indata);
if(ret != 0) {
strcat(tmp, "f");
len = len + 1;
}
for(i=0; i<len; i+=2)
{
outdata[i] = tmp[i+1];
outdata[i+1] = tmp[i];
}
return 0;
}
static int get_sms_center(char *sm)
{
char SendData[32];
char rdata[64];
char *num_start;
char *num_end;
int num_len;
char tmp[16];
sprintf(SendData, "%s\r", "AT+CSCA?");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("set pdumode Failed\n");
AT_ComClose();
return -1;
}
memset(rdata, 0, sizeof(rdata));
AT_RecvData(rdata);
printf("rdata:%s\n", rdata);
num_start = strchr(rdata, ‘"‘);
if(num_start == NULL)
return -1;
else
*num_start = ‘\0‘;
printf("rdata num:%s\n", num_start+1);
num_end = strchr(num_start+1, ‘"‘);
if(num_end == NULL)
return -1;
else
*num_end = ‘\0‘;
printf("rdata start:%s\n", num_start+2);
memset(tmp, 0, sizeof(tmp));
phonenum_parity_exchange(num_start+2, tmp);
num_len = (strlen(tmp) + 2)/2;
sprintf(sm, "%02x%s%s", num_len, "91", tmp);
return 0;
}
static int get_sms_dest(char *phonenum, char *dest)
{
char tmp[16];
int num_len = strlen(phonenum);
memset(tmp, 0, sizeof(tmp));
if(strchr(phonenum, ‘+‘))
{
num_len = num_len -1;
phonenum_parity_exchange(phonenum+1, tmp);
sprintf(dest, "%s%02x%s", "1100", num_len, "91");
}
else
{
phonenum_parity_exchange(phonenum, tmp);
sprintf(dest, "%s%02x%s", "1100", num_len, "81");
}
strcat(dest, tmp);
strcat(dest, "000800");
return 0;
}
int AT_ComConfig(char *name, int rate)
{
strcpy(com_name, name);
BaudRate = rate;
if(AT_ComOpen())
return -1;
AT_ComClose();
return 0;
}
int AT_ApnConfig(char *apn)
{
char SendData[512] = {0};
int cid=1;
char *pdp_type="ip";
if(AT_ComOpen())
return -1;
/* apn config cmd:at+CGDCONT=[<cid> [,<PDP_type> [,<APN> [,<PDP_addr> [,<d_comp> [,<h_comp>]]]]]*/
sprintf(SendData, "at+cgdcont=%d,\"%s\", \"%s\"", cid, pdp_type, apn);
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
AT_ComClose();
return -1;
}
AT_ComClose();
return 0;
}
int SMS_TextMode(char *phonenum, char *msg)
{
char SendData[512] = {0};
char RecvData[256] = {0};
/* 设置短信发送格式为文本格式 */
sprintf(SendData, "%s\r", "AT+CMGF=1");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("set textmode Failed\n");
AT_ComClose();
return -1;
}
#if 0
// for debug
Sleep(2);
SerialRecv(hCom, RecvData, M_ASYNC);
printf("Recv data:%s\n", RecvData);
#endif
/* 设置短信发送号码 */
sprintf(SendData,"AT+CMGS=\"%s\"\r", phonenum);
if(SerialSend(hCom, SendData, strlen(SendData), M_ASYNC) <0)
{
printf("send phone number Failed\n");
AT_ComClose();
return -1;
}
/* 发送短信内容 */
printf("send msg:%s\n", msg);
sprintf(SendData, "%s", msg);
strcat(SendData, "\x1a");
if(SerialSend(hCom, SendData, strlen(SendData), M_ASYNC) <0)
{
printf("send msg Failed\n");
AT_ComClose();
return -1;
}
return 0;
}
int SMS_PduMode(char *phonenum, char *msg)
{
char SendData[2048] = {0};
char RecvData[256] = {0};
char sms_dest[32];
char sms_center[32];
//char *center = "0891683110102105f0";
char pdumsg[1024];
int len;
/* 设置短信发送格式为pdu格式 */
sprintf(SendData, "%s\r", "AT+CMGF=0");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("set pdumode Failed\n");
AT_ComClose();
return -1;
}
memset(RecvData, 0, sizeof(RecvData));
AT_RecvData(RecvData);
if(!strstr(RecvData, "OK"))
{
AT_ComClose();
return -1;
}
/* get the service message center address */
memset(sms_center, 0, sizeof(sms_center));
if(get_sms_center(sms_center) !=0)
strcpy(sms_dest, "0891683110102105f0");
printf("sms_center:%s\n", sms_center);
/*get message send address */
memset(sms_dest, 0, sizeof(sms_dest));
get_sms_dest(phonenum, sms_dest);
/* convert gb2312 to unicode */
ConverToUnicode(msg, pdumsg);
printf("pdumsg:%s\n", pdumsg);
len = (strlen(pdumsg) + strlen(sms_dest))/2;
printf("the msg len:%d\n", len);
/* 设置短信发送号码 */
sprintf(SendData,"AT+CMGS=%d\r", len);
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("send phone number Failed\n");
AT_ComClose();
return -1;
}
/* 发送短信内容 */
sprintf(SendData, "%s%s%s", sms_center, sms_dest, pdumsg);
printf("send msg:%s, len=%d\n", SendData, strlen(SendData));
strcat(SendData, "\x1a");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("send msg Failed\n");
AT_ComClose();
return -1;
}
// for debug
Sleep(2);
SerialRecv(hCom, RecvData, M_ASYNC);
printf("Recv data:%s\n", RecvData);
return 0;
}
int AT_SendSMS(char *phonenum, char *msg, int msg_len)
{
if(AT_ComOpen())
return -1;
SMS_PduMode(phonenum, msg);
AT_ComClose();
return 0;
}
int AT_GetFlux(char *rdata, int buf_len)
{
char SendData[32];
char RecvData[512];
char *ptr;
*rdata = ‘\0‘;
if(AT_ComOpen())
return -1;
/* 获取流量信息 */
sprintf(SendData, "%s\r", "AT^DSFLOWQRY");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("send get flux cmd Failed\n");
AT_ComClose();
return -1;
}
memset(RecvData, 0, sizeof(RecvData));
AT_RecvData(RecvData);
printf("get flux read:%s\n", RecvData);
ptr = strchr(RecvData, ‘:‘);
if(ptr == NULL)
{
AT_ComClose();
return -1;
}
else
strncpy(rdata, ptr+1, buf_len);
AT_ComClose();
return 0;
}
int AT_GetCi(char *rdata, int buf_len)
{
char SendData[32];
char RecvData[64];
char *ptr;
*rdata = ‘\0‘;
if(AT_ComOpen())
return -1;
Sleep(1);
/* 设置允许获取位置信息 */
sprintf(SendData, "%s\r", "AT+CREG=2");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("set get cell id Failed\n");
AT_ComClose();
return -2;
}
memset(RecvData, 0, sizeof(RecvData));
AT_RecvData(RecvData);
if(!strstr(RecvData, "OK"))
{
AT_ComClose();
return -3;
}
/* 获取位置信息 */
sprintf(SendData, "%s\r", "AT+CREG?");
if(AT_SendCmd(SendData, strlen(SendData)) <0)
{
printf("Get cell id Failed\n");
AT_ComClose();
return -4;
}
AT_RecvData(RecvData);
printf("getci read:%s\n", RecvData);
ptr = strrchr(RecvData, ‘,‘);
if(ptr == NULL)
{
AT_ComClose();
return -5;
}
else
strncpy(rdata, ptr+1, buf_len);
AT_ComClose();
return 0;
}
int at_test(char *wdata, char *rdata, int len)
{
char *tmp;
strcpy(rdata, "at_test======");
strcat(rdata, wdata);
return len;
}
atcmd.h:
#ifndef _ATCMD_H_
#define _ATCMD_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <windows.h>
#define M_SYNC (0)
#define M_ASYNC (1)
#pragma comment(lib, "libcomm.lib")
/* 串口动态链接库接口*/
_declspec(dllimport) HANDLE SerialOpen(char *name, int type);
_declspec(dllimport) int SerialSet(HANDLE fd, int rate);
_declspec(dllimport) int SerialSend(HANDLE fd, char *data, int len, int method);
_declspec(dllimport) int SerialSendWithTimeout(HANDLE fd, char *data, int timeout);
_declspec(dllimport) int SerialRecv(HANDLE fd, char *data, int method);
_declspec(dllimport) int SerialRecvWithTimeout(HANDLE fd, char *data, int timeout);
_declspec(dllimport) int SerialClose(HANDLE fd);
/* AT 指令对外接口*/
_declspec(dllexport) AT_ComConfig(char *name, int rate);
_declspec(dllexport) AT_ApnConfig(char *apn);
_declspec(dllexport) AT_SendSMS(char *phonenum, char *msg, int len);
_declspec(dllexport) AT_GetFlux(char *rdata, int buf_len);
_declspec(dllexport) AT_GetCi(char *rdata, int buf_len);
_declspec(dllexport) at_test(char *wdata, char *rdata, int len);
#ifdef __cplusplus
}
#endif
#endif
以上代码在实际项目中编译通过。
本文出自 “记录生活点滴” 博客,请务必保留此出处http://qiangguozky.blog.51cto.com/3831429/1787474
以上是关于C语言通过串口发送AT指令的主要内容,如果未能解决你的问题,请参考以下文章
c#编程,通过向串口发数据的方式发送中文短信时,但中文显示乱码,如何软件解码?