一般编写稍微复杂的程序的时候,会有个多个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