现在的位置: 首页 > 综合 > 正文

Makefile:依赖多个c文件的书写方式

2013年07月10日 ⁄ 综合 ⁄ 共 4426字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.