医生开错药:Linux C编程连载串口编程

来源:百度文库 编辑:偶看新闻 时间:2024/04/30 06:21:28
Linux C编程连载串口编程[日期:2011-09-25] 来源:Linux社区  作者:tandesir 
 Linux C编程连载——串口编程:
1.. 设计目的
设计一个串口程序,该程序执行时,具有通信参数选择及串口收发数据功能,界面友好。
2 设计流程图及说明
       如图1.1所示,程序运行后,首先进入功能选择,共4中功能可供选择,分别为接收数据,发送数据,接收文件,发送文件。根据提示,键入不同的数字,可以进入不同的功能。设置完毕,进入参数设置,可以保持默认参数,也可以设置用户参数,若设置有误,还可以对参数重新设置。参数设置确认后,打开串口。若串口打开无误,则根据用户的选择进入不同的功能。  

 
图1.1 总体设计流程图
 
3 设计测试
3.1 测试环境及步骤
测试环境:VMware WorkStation 6.0.2+Fedora 10+minicom+广嵌开发板
测试步骤:
(1)    配置minicom
[tande@localhost ~]$sudo minicom –s


图3.1 配置minicom
(2)    建立nfs服务
[tande@localhost ~]$sudo ifconfig eth0 192.168.2.1 netmask 255.255.255.0
[tande@localhost ~]$sudo vi /etc/exports
添加
/mnt/share 192.168.2.*(rw,no_root_squash)
[tande@localhost ~]$ sudo service nfs restart
将交叉编译的程序拷贝至/mnt/share目录下。
(3)    开发板连接串口,用网线和宿主机相连,运行minicom进入开发板(目标机)
[tande@localhost ~]$sudo minicom
[root@(none) /]#mount –t nfs –o nolock 192.168.2.1:/mnt/share /mnt
(4)    打开另一个终端,进入宿主机程序目录
[tande@localhost ~]$cd work/c/device/serial/
[tande@localhost ~]$sudo ./serial
(5)    目标机
[root@(none) mnt]# ./serial
3.2 测试结果
(1)用2号功能(发送数据)控制目标机执行相应的命令
宿主机运行./serial,在功能选择时键入2,参数选择默认,进入数据发送。在宿主机输入相应的命令就可以控制目标机执行相应的命令。如图3.2所示,宿主机(图3.2左)分别发送ls、cd mnt、q(退出发送数据程序),目标机(图3.2右)执行了相应的命令。


图3.2 宿主机控制目标机
(2)目标机与宿主机数据收发
       宿主机运行./serial,键入2,选择数据发送。目标机运行./serial,键入1,选择数据接收。通信参数保持默认。宿主机发送hello,测试结果如图3.3(a)、(b)所示。


 图3.3(a) 宿主机发送数据


 图3.3(b) 目标机接收数据
(3)目标机接收宿主机启动信息
       如图3.4所示,关闭minicom,宿主机运行./serial,选择1号功能,接收数据,参数保持默认。开发板上电,宿主机即可接收开发板启动信息。


 图3.4 宿主机接收目标机启动信息
(4)目标机接收文件
       如图3.5所示,关闭minicom,宿主机运行./serial,选择3号功能,接收文件,参数保持默认。输入接收文件名为1.txt(可以指定保存路径,如/home/tande/1.txt)。打开宿主机开发板。接收完成后,文件夹中多了一个1.txt的文件。该文件的权限是root,要更改权限后才能查看。


 图3.5宿主机接收文件
(5)目标机发送文件
1)编辑发送文件(以root身份)
[tande@localhost serial]$ sudo vi 1.txt?
ls
cd home
q
2)打开minicom,进入目标机。
3)新建一个终端,执行./serial,选择4号功能,参数保持默认。键入发送的文件名为1.txt。实验结果如图3.6(a)、(b)所示。


 图3.6(a)宿主机发送文件


 图3.6(b)目标机接收文件数据
(6) 通信参数设置
       功能选择完成后,进入通信参数设置。程序提示“Use the default parameter ? y/n”。键入y,保持默认参数不变。键入n,进入用户参数设置。设置完成后,程序会提示参数信息,并询问“The parameter is OK? y/n”键入y,参数设置完成,键入n,返回重新设置,测试结果如图3.7(a-d)所示。若串口类型为USB转串口,则需要将uart.h中宏定义
#define COM_TYPE GNR_COM   改为 #define COM_TYPE USB_COM
重新编译即可。


 图3.7(a)参数设置
 
图3.7(b)参数设置


图3.7(c)参数设置


图3.7(d)参数设置
 
【代码清单】
uart.h
#ifndef __UART_H__   #define __UART_H__      #include   #include   #include   #include   #include   #include   #include   #include      #define GNR_COM 0   #define USB_COM 1   #define COM_TYPE GNR_COM   #define MAX_COM_NUM 6      int set_com_config(int fd, int baud_rate, int data_bits, char parity, int stop_bits)   {   struct termios new_cfg,old_cfg;   int speed;      if(tcgetattr(fd,&old_cfg)!=0){   perror("tcgetattr");   return -1;   }      new_cfg=old_cfg;   cfmakeraw(&new_cfg);   new_cfg.c_cflag |= CLOCAL|CREAD;   new_cfg.c_cflag &= ~CSIZE;      switch(baud_rate){          case 2400:       {           speed=B2400;           }       break;       case 4800:       {           speed=B4800;           }       break;       case 9600:       {           speed=B9600;           }       break;       case 115200:       {           speed=B115200;         }       break;       default :       {           speed=B115200;         }       break;       }//end of switch      cfsetispeed(&new_cfg,speed);   cfsetospeed(&new_cfg,speed);      switch(data_bits){          case 7:       {           new_cfg.c_cflag|=CS7;          }       break;       case 8:       {           new_cfg.c_cflag|=CS8;          }       break;       default:       {           new_cfg.c_cflag|=CS8;       }       break;       }//end of switch      switch(parity){          default:       case 'n':       case 'N':       {           new_cfg.c_cflag &= ~PARENB;           new_cfg.c_iflag &= ~INPCK;       }       break;       case 'o':       case 'O':       {           new_cfg.c_cflag |= (PARODD | PARENB);           new_cfg.c_iflag |= INPCK;       }       break;       case 'e':       case 'E':       {           new_cfg.c_cflag |= PARENB;           new_cfg.c_cflag &= ~PARODD;           new_cfg.c_iflag |= INPCK;       }       break;       case 's':       case 'S':       {           new_cfg.c_cflag &= ~PARENB;           new_cfg.c_cflag &= ~CSTOPB;       }       break;       }//end of switch          switch(stop_bits){          default:       case 1:       {           new_cfg.c_cflag &= ~CSTOPB;       }       break;       case 2:       {           new_cfg.c_cflag |= CSTOPB;       }       break;       }//end of switch      new_cfg.c_cc[VTIME] = 0;   new_cfg.c_cc[VMIN] = 1;      tcflush(fd,TCIFLUSH);//flush cache data      if((tcsetattr(fd,TCSANOW,&new_cfg))!=0){       perror("tcsetattr");       return -1;   }      return 0;   }      int open_port(int com_port){      int fd;      #if (COM_TYPE==GNR_COM)       char *dev[] = {"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};   #else        char *dev[] = {"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"};   #endif      if((com_port<0)||(com_port>MAX_COM_NUM)){       return -1;       }      fd=open(dev[com_port-1],O_RDWR|O_NOCTTY|O_NDELAY);      if(fd<0){       perror("fcntl F_SETFL");       }      if(isatty(STDIN_FILENO)==0){       perror("standard input is not a terminal device");       }   return fd;      }   #endif  serial.c
#include   #include   #include   #include   #include   #include   #include   #include   #include   #include "uart.h"      #define BUFF_SIZE 1024      void rev_data(void);   void send_data(void);   void rev_file(void);   void send_file(void);      char init_set(void);      static int fd;      int main(int argc,char *argv[])   {       int func=0;       time_t sys_time;          printf("Welcome to use serial tools!\n");       printf("Author:Tan De\n");       //printf("Today is %s\n",gettimeofday());       sys_time = time(NULL);       printf("%s", ctime(&sys_time));          printf("Please choice function:\n");       printf("1-Receive data\n");       printf("2-Send data\n");       printf("3-Receive file\n");       //printf("If you want to use this function ,you must mkdir like serial /home/tande/serial(or ~/serial) in your home dir!\n");       printf("4-Send file\n");                  printf("Your choice:");       scanf("%d",&func);         getchar();//fflush(stdin);                      while(init_set()=='n')       {           init_set();       }              switch(func)       {           case 1:               printf("Receive data is ready!\n");               rev_data();               break;           case 2:               printf("Send data is ready!\n");               send_data();               break;           case 3:               printf("Receive file is ready!\n");               rev_file();               break;           case 4:               printf("Send file is ready\n");               send_file();               break;           default:               printf("Choose error!\nPleaserun again !\n");                      }   close(fd);   return 0;   }      char init_set(void)   {       int com_port=1;       int baud_rate=115200;       int data_bits=8;       char parity='N';       int stop_bits=1;       static char set_flag='y';       static char corr_flag='y';         static char def_flag='y';          if(def_flag=='y')   {          printf("Default parameter : COM%d,%d,%d,%c,%d\n",com_port,baud_rate,data_bits,parity,stop_bits);       printf("Use the default parameter? (y/n)\n");       scanf("%c",&set_flag);       getchar();       if(set_flag=='n')       {           set_flag='y';//Enable user set mode           def_flag='n';//Disable default paramter set mode       }       else if(set_flag=='y')       {           set_flag='n';//Disable user set mode       }   }      if(set_flag=='y'){       printf("Please set serial port num!\n");               printf("1-COM1\n2-COM2\n3-COM3\n4-COM4\n5-COM5\n6-COM6\n");       printf("Serial port:");       scanf("%d",&com_port);       getchar();          printf("Please set baud_rate!\n");       printf("2400 4800 9600 19200 38400 115200\n");       printf("Baud rate:");       scanf("%d",&baud_rate);       getchar();          printf("Please set data_bits!\n7 8\n");       printf("Data_bits:");       scanf("%d",&data_bits);       getchar();          printf("Please set parity\n");       printf("N-NONE O-ODD E-EVEN\n");       printf("Parity:");       scanf("%c",&parity);       getchar();          printf("Please set stop_bits\n");       printf("1 2\n");       printf("Stop bits:");       scanf("%d",&stop_bits);       getchar();          printf("Your choice is COM%d,%d,%d,%c,%d\n",com_port,baud_rate,data_bits,parity,stop_bits);       printf("The Parameter is OK! (y/n)");       scanf("%c",&corr_flag);       getchar();       if(corr_flag=='y')           set_flag='n';   }//end of set parameter              if(corr_flag=='y')       {           if((fd=open_port(com_port))>0)           {              printf("fd is %d\n",fd);           if(set_com_config(fd,baud_rate,data_bits,parity,stop_bits)<0){           perror("Set_com_config");       }           printf("Open Serial %d is OK!\n",com_port);           }           else           {               perror("open_port");                   exit(1);           }       }   return corr_flag;   }      void rev_data(void)   {          char buff[BUFF_SIZE];          do {           memset(buff,0,BUFF_SIZE);              if(read(fd,buff,BUFF_SIZE)>0)           {               printf("The receive data is :%s",buff);           }           else           {           }           }while(strncmp(buff,"quit",4)&&strncmp(buff,"q",1)&&strncmp(buff,"Q",1));       close(fd);   }      void send_data(void)   {       char buff[BUFF_SIZE];       do{           printf("Input string (enter 'quit' or 'q' to exit):");           memset(buff,0,BUFF_SIZE);           if(fgets(buff,BUFF_SIZE,stdin)==NULL)           {               perror("fgets");               break;           }           write(fd,buff,strlen(buff));       }while(strncmp(buff,"quit",4)&&strncmp(buff,"q",1)&&strncmp(buff,"Q",1));       close(fd);   }      void rev_file(void)   {       int len;       int count;       int page=5;        int file_fd;       char *content_path="";       char file_path[100];       char buff[BUFF_SIZE];       mode_t mode;          //  printf("You must make sure dir serial in ~/serial!\n");   //  getchar();   //  if((mkdir(content_path,mode &0777))==0)   //      printf("mkdir /home/tande/serial successful!\n");          //memset(file_path,0,100);       printf("Please input the file_path to save the file data:\n");          fgets(file_path,sizeof(file_path),stdin);          do {           memset(buff,0,BUFF_SIZE);              if((len=read(fd,buff,BUFF_SIZE))>0)           {                              printf("File saving in %s\n",file_path);                                  if((file_fd=open(file_path,O_RDWR|O_CREAT|O_APPEND,644))>0)                   if(count=write(file_fd,buff,strlen(buff))>0)                   {                       lenlen=len-count;                     }                   else{                       perror("Write data to file");                   }               else                   perror("Save data!\n");           }           else           {               }           }while(strncmp(buff,"quit",4)&&strncmp(buff,"q",1)&&strncmp(buff,"Q",1)&&((len!=0)||(page--)));          printf("File saved in %s\n",file_path);          close(file_fd);       close(fd);   }      void send_file(void)   {       int file_fd;       int len=1024;       int count=0;       int page=4;       char *content_path="";           char file_path[100];       char buff[BUFF_SIZE*page];                 printf("Please input the file_path to send the file:\n");       fgets(file_path,sizeof(file_path),stdin);       printf("File Path :%s\n",file_path);                 if((file_fd=open(file_path,O_RDWR))>0)       {           memset(buff,0,BUFF_SIZE*page);           if((len=read(file_fd,buff,sizeof(buff)))>0)           {                          }           else{               perror("Read file!\n");               }           }       else {           perror("Open file!\n");           }              do {           if((count=write(fd,buff,len))>0)           {               lenlen=len-count;               printf("Sending file in %s\n",file_path);               printf("Buff:%s\n",buff);              }           else           {               }           memset(buff,0,BUFF_SIZE*page);           }while((len!=0));              printf("Send file finish!\n");              close(file_fd);       close(fd);   }  
本篇文章来源于 Linux公社网站(www.linuxidc.com)  原文链接:http://www.linuxidc.com/Linux/2011-09/43776p3.htm