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指令的主要内容,如果未能解决你的问题,请参考以下文章

ESP8089串口怎么接,AT指令发送无反应

通过串口接受的指令点亮LED

c#编程,通过向串口发数据的方式发送中文短信时,但中文显示乱码,如何软件解码?

为啥我向串口输进指令没反应?(下面是我的arduino代码)

ESP8266使用AT指令获取B站粉丝数和天气数据

Android 发送AT指令