📄 dail.c
字号:
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#define FALSE -1
#define TRUE 0
#define MAX 256
/**
*@brief 设置串口通信速率
*@param fd 类型 int 打开串口的文件句柄
*@param speed 类型 int 串口速度
*@return void
*/
int speed_arr[] = {B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, 115200, 38400,
19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, int speed){
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < (sizeof(speed_arr) / sizeof(int)); i++) {
if (speed == name_arr[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄
*@param databits 类型 int 数据位 取值 为 7 或者8
*@param stopbits 类型 int 停止位 取值为 1 或者2
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n"); return (FALSE);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cflag |= CLOCAL|CREAD;//使能接受
options.c_cc[VTIME] = 50; /* 设置超时15 seconds*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
/* Set Raw mode */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~OPOST; /*Output*/
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
/*********************************************************************/
int OpenDev(char *Dev)
{
int fd = open( Dev, O_RDWR | O_NOCTTY | O_NDELAY ); //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("Can't Open Serial Port");
return -1;
}
else
//fcntl(fd, F_SETFL, 0);
return fd;
}
void send(int fd,char *str)
{
int nwbytes,nwnum;
nwnum=strlen(str);
if((nwbytes=write(fd,str,nwnum))!=nwnum)//CDMA和edge模块使用相同的自动接听指令
{
perror("communite error\n");
close(fd);
return -1;
}
printf("write %d bytes\n",nwbytes);
printf("write OK\n");
}
int check_ok(int fd,char *refbuf)
{
int nPos=0,nrbytes,res,nrnum=0;
char rbuffer[MAX];
while(1) //循环读取数据
{
if((nread = read(fd, rbuffer+nPos, 1))>0)
{
if((rbuffer[nPos]=='\r')||(rbuffer[nPos]=='\n'))
{
rbuffer[nPos]='\0';
printf("%s\n",rbuffer);
if ((n=strcmp(rbuffer,refbuf))==0)
{
res=1;
break;
}
else
{
for( i = 0; i < MAX; i++)
{
rbuffer[i] = 0;
}
nPos=0;
continue;
}
}
else
nPos ++;
}
else
{
printf("Read error\n");
res=0;
break;
}
}
return res;
}
void help()
{
printf("this is a tools for dial telphone number\n");
printf("init|dial|reset\n");
printf("init----initalize the telphone model\n");
printf("EXAM:%s -init\n",argv[0]);
printf("dail----dial a telphone number.\n");
printf("EXAM:%s -dial 13612342345\n",argv[0]);
printf("reset----reset the telphone model\n");
printf("EXAM:%s -reset\n",argv[0]);
}
/////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////SPI Write////////////////////////////////////////
//写串口使其发送数据会同时返回一个串口数据,相当于一次发送数据和接收数据
//返回值,return_data 表示发送数据同时返回的数值
//uart_num,表示返回值是哪个串口的,-1表示返回值无效
/////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv){
struct termios oldoptions;
int fd,type,i=0;//
char cdma_ref[MAX]="+GMM: Model 199";//CDMA模块的返回信息
char edge_ref[MAX]="+CGMM: "GSM900","GSM1800","GSM1900","GSM850","MODEL=G24"";
char moto_ref[MAX]="ATD";//MOTO模块的拨打电话指令
char huawei_ref[MAX]="AT+CDV";//HUAWEI模块的拨打电话指令
char ok_ref[MAX]="OK";//AT 指令执行成功的返回信息
char reset_ref[MAX]="ATF\r";//通用的模块恢复初始设置指令
char *dev = "/dev/ttyAMA1"; //使用串口1
char dial_buf[MAX]; //拨打电话指令
char auto_ref[MAX] = "ATS0=1\r";//自动接听电话指令
char req_buf[MAX] ="AT+GMM\r";//请求生产厂商,以便于区别模块
for(i=0;i<MAX;i++) buffer[i]='\0';
if(argc<2)
{
printf("please input args\n");
help();
return 0;
}
if(strcmp(argv[1],"-init")==0) type=1;//自动应答:类型1
else if(strcmp(argv[1],"-reset")==0) type=2;//恢复出厂设置:类型2
else if(strcmp(argv[1],"-dial")==0)
{
if(argc!=3)
{
printf("please input the telphone\n");
printf("ex:-dial 13522312334 ");
return 0;
}
else
type=3;//拨打电话:类型3
}
else
{
printf("error argument,please input agian\n");
help();
return 0;
}
fd = OpenDev(dev);//打开设备串口
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &oldoptions);
set_speed(fd,115200);//设置串口波特率
if (set_Parity(fd,8,1,'N') == FALSE) {//设置串口的标志等
printf("Set Parity Error\n");
return 0;
}
tcflush(fd, TCIFLUSH);
printf("config OK\n");
switch(type)
{
case 1:
send(fd,auto_ref);
if(check(fd,ok_ref)) printf("now moderm is in auto answer model\n");
else printf("fail to set moderm\n");
break;
case 2:
send(fd,reset_ref);
if(check(fd,ok_ref)) printf("now moderm is restore to manfautur states\n");
else printf("fail to set moderm\n");
break;
case 3:
send(fd,req_buf);
if(check(fd,cdma_ref))
{
printf("this is an cdma model\n");
strcpy(dial_buf,huawei_ref);
strcat(dial_buf,argv[2]);//加拨电话号码
strcat(dial_buf,"\r");
send(fd,dial_buf);
if(check(fd,ok_ref))
printf("now dial the number\n");
else
printf("huawei-- dial the number error");
break;
}
else if(check(fd,edge_ref))
{
printf("this is an cdma model\n");
strcpy(dial_buf,moto_ref);
strcat(dial_buf,argv[2]);//加拨电话号码
strcat(dial_buf,"\r");
send(fd,dial_buf);
if(check(fd,okbuf))
printf("now dial the number\n");
else
printf("moto-- dial the number error");
break;
}
else
printf("unknow model name\n");
break;
default:
printf("illegal number\n");
break;
}
tcsetattr(fd, TCSANOW, &oldoptions);
close(fd);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -