一般编写稍微复杂的程序的时候,会有个多个C文件需要进行编译:
(1)通常有个头文件,它的作用是声明函数以及数据结构等待。
(2)其次是与头文件名称相对应的C文件(一般两个文件名称一样,后缀不一样),它的作用是头文件对应函数的具体实现。
(3)主程序文件,通过main()函数调用以上两个文件的结构或者函数。
(4)最后就是Makefile文件的编写了。
我已经编译,执行通过的例程包含文件如下图:
(1)rfid.h
#ifndef _RFID_H
#define _RFID_H
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
int open_port(int fd,int comport);
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);
#endif
简要说明:有的头文件好像没有 #ifndef _RFID_H #define _RFID_H #endif 这三条语句,反正加了没错,能通过。
(2)rfid.c 里面的内容只是串口的打开和设置两个函数
#include "rfid.h"
/*打开串口*/
int open_port(int fd,int comport)
{
char *dev[] = {"/dev/ttySAC0","/dev/ttySAC1","/dev/ttySAC2"};
//long vdisable;
if (comport==1) /*打开串口1*/
{
fd=open("/dev/ttySAC0",O_RDWR|O_NOCTTY|O_NDELAY);
if(-1==fd)
{
perror("Can't open SerialPort1!\n");
return(-1);
}
//else
//printf("Open SerialPort1 succeed!\n");
}
else if (comport==2) /*打开串口2*/
{
fd=open("/dev/ttySAC1",O_RDWR|O_NOCTTY|O_NDELAY);
if(-1==fd)
{
perror("Can't open SerialPort2!\n");
return(-1);
}
else
printf("Open SerialPort2 succeed!\n");
}
else if (comport==3) /*打开串口3*/
{
fd=open("/dev/ttySAC2",O_RDWR|O_NOCTTY|O_NDELAY);
if(-1==fd)
{
perror("Can't open SerialPort3!\n");
return(-1);
}
//else
//printf("Open SerialPort3 succeed!\n");
}
if(fcntl(fd, F_SETFL,0)<0) /*恢复串口的状态为阻塞状态,等待串口数据的读入*/
printf("fcntl failed!\n");
// else
// printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));
if(isatty(STDIN_FILENO)==0) /*测试打开的fd是否引用终端设备*/
printf("standard input is not a terminal device!\n");
//else
//printf("isatty success!\n");
//printf("fd-open=%d\n",fd);
return fd;
}
/*设置串口*/
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
struct termios newtio,oldtio;
if (tcgetattr(fd,&oldtio)!=0){/*获得之前串口的配置情况*/
perror("SetupSerial1");
return -1;
}
bzero(&newtio, sizeof(newtio));/*初始化新终端*/
newtio.c_cflag |= CLOCAL | CREAD;/*忽略调制解调器线路状态,使用接收器*/
newtio.c_cflag &= ~CSIZE;/*清除字符长度*/
switch(nBits) /*设置数据位长度*/
{
case 7:
newtio.c_cflag |= CS7;/*7位数据*/
break;
case 8:
newtio.c_cflag |= CS8;/*8位数据*/
break;
default:
newtio.c_cflag |= CS8;/*8位数据*/
break;
}
switch(nEvent) /*设置奇偶校验位*/
{
case 'O':
newtio.c_cflag |= PARENB;/*设置奇偶校验位*/
newtio.c_cflag |= PARODD;/*输入奇偶校验,输出偶校验*/
newtio.c_iflag |= (INPCK|ISTRIP);/*允许输入奇偶校验,去掉字符的第8个比特*/
break;
case 'E':
newtio.c_iflag |= (INPCK|ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'N':
newtio.c_cflag &= ~PARENB;/*不使用奇偶校验*/
break;
default:
newtio.c_cflag &= ~PARENB;/*不使用奇偶校验*/
break;
}
switch(nSpeed)
{
case 2400:
cfsetispeed(&newtio,B2400);
cfsetospeed(&newtio,B2400);
break;
case 4800:
cfsetispeed(&newtio,B4800);
cfsetospeed(&newtio,B4800);
break;
case 9600:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
default:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
}
if(nStop==1) /*一个停止位*/
newtio.c_cflag &= ~CSTOPB;
else if (nStop==2) /*两个停止位*/
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd,TCIOFLUSH);/*刷清输入,输出缓存队列*/
if((tcsetattr(fd,TCSANOW,&newtio))!=0) /*激活配置*/
{
perror("com set error");
return -1;
}
//printf("set done!\n");
return 0;
}
(3)主函数rfid_main.c
/*EPC标签识别
rfid3:阶段成果
前面是串口处理,该版本确定了通信协议的格式及其版本,可以按照预期操作reader。
[root@FriendlyARM /home]# ./main_rfid
Open SerialPort2 succeed!
write successful 5
read result is 6
E4 4 82 1 5 90 0 1 E2 11 20 69 87 18 2 44 15 20 出错返回显示,就是没有检测到tag
[root@FriendlyARM /home]# ./main_rfid
Open SerialPort2 succeed!
write successful 5
read result is 18
E0 10 82 1 1 E2 11 20 69 87 18 2 44 15 20 78 48 36 正常返回显示,返回18个字节数据,因为读的数组大小设置为18,所以后面还读出的数据没有存入
*/
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>
#include "rfid.h"
int main()
{
int fp, i, wnum, rnum;
char buff_w[5]={0xA0,0x03,0x82,0x00,0xDB}; //EPC Tag recognize
//char buff_w[1024];
char buff_r[18];//5+12+1
//char buff_r[1024];
fp=open_port(fp,2);
/*设置串口:波特率9600,数据位8位,无校验位,停止位1位*/
if(set_opt(fp,9600,8,'N',1)<0)
{
perror("Set_opt error!\n");
return;
}
wnum=write(fp,buff_w,sizeof(buff_w));
printf("write successful %d\n",wnum);
sleep(5);
rnum=read(fp,buff_r,sizeof(buff_r));
printf("read result is %d\n",rnum);
for(i=0;i<rnum;i++)
printf("%X ",buff_r[i]);
printf("\n");
sleep(2);
close(fp);
}
简要说明:我这个函数是RFID的测试函数,需要结合硬件环境下才能成功,读者如果只想学习Makefile的写法,可以把rfid.c里面函数实现换乘printf输出就很明显了。
(4)Makefile
CC = arm-linux-gcc
all: main_rfid
main_rfid: rfid_main.c rfid.o
$(CC) -o $@ rfid_main.c rfid.o
rfid.o: rfid.c rfid.h
$(CC) -c -o $@ rfid.c
clean:
rm -f *.a *.o main_rfid *~
简要说明:程序是运行在ARM板上的,在PC机上需要将arm-linux-gcc改成gcc