以下代码是通过串口发送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

以上代码在实际项目中编译通过。