您的位置:首页 > 运维架构 > Linux

Linux下的串口编程

2012-12-17 12:52 435 查看
    串口设备一般在/dev/ttyS0-ttyS4。Linux下一切皆文件,把ttyS0结点当做文件操作,当然,获取描述符后先配置一下,open、read、write、close你肯定会吧,那,串口编程,你也肯定会了。

    这代码我之前测试过,很ok,但发上来前,我可没测过哦,不过,看看,有思路也是不错的。

 

一:串口发送端程序

/***************************************************************************************************

**文件:w_uart.c

**编写者:huangminqiang

**编写日期:2012年10月15号

**简要描述:串口发送程序,在PC机上发送。

**修改者:

**修改日期:2012年11月12号

**注:

****************************************************************************************************/

#include <stdio.h>

#include <string.h>

#include <termios.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <sys/types.h>

#define COM "/dev/ttyS0"

typedef enum

{

 NON, //无校验

 ODD, //偶校验

 EVEN,//奇校验

}cal_t;

/****** 设置串口***************************************************************************************/

static int set_com(int fd, int speed, int bits, cal_t cal, int stop )

{

 struct termios curtio;

 memset(&curtio, 0, sizeof(curtio));

 //取得串口已有的属性

 if (0 != tcgetattr(fd, &curtio))

 {

  perror("Failed to tcgetattr");

  return -1;

 }

 //设置输入输出波特率

 cfsetispeed(&curtio, speed);

 cfsetospeed(&curtio, speed);

 //设置为原始模式

 curtio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG | ECHOE | ECHOK | ECHONL);

 curtio.c_iflag &= ~(BRKINT | IUCLC | ICRNL | INLCR | IGNCR);

 //激活相应选项

 curtio.c_cflag |= CLOCAL | CREAD;

 //设置数据位

 curtio.c_cflag &= ~CSIZE;

 curtio.c_cflag |= bits;

 

 //设置校验位

 if (ODD == cal)

 {

  curtio.c_iflag |= (INPCK | ISTRIP);

  curtio.c_cflag |= PARENB;

  curtio.c_cflag |= PARODD;

 }

 else if(EVEN == cal)

 {

  curtio.c_iflag |= (INPCK | ISTRIP);

  curtio.c_cflag |= PARENB;

  curtio.c_cflag &= ~PARODD;

 }

 else

 {

  curtio.c_cflag &= ~PARENB;

 }

 //设置停止位

 if (2 == stop)

 {

  curtio.c_cflag |= CSTOPB;

 }

 else

 {

  curtio.c_cflag &= ~CSTOPB;

 }

 //设置最少字符等待时间

 curtio.c_cc[VTIME] = 0;

 curtio.c_cc[VMIN] = 0;

 //清空缓冲

 tcflush(fd, TCIOFLUSH);

 //设置新串口属性

 if (0 != tcsetattr(fd, TCSANOW, &curtio))

 {

  perror("Failed to tcgetattr");

  return -1;

 }

 printf("set done!\n");

 return 0;

}

/****** 写入串口信息 **********************************************************************************/

int WriteUartInfo(void)

{

 int fd;

 int cnt = 0;

 int w_cnt = 0;

 unsigned char w_buf[128];

 //打开串口

 fd = open(COM, O_RDWR);

 if(0 > fd)

 {

  perror("uart open err:");

  return -1;

 }

 

 #if 0

 //设置串口参数

 if (0 != set_com(fd, B115200, CS8, NON, 1))

 {

  printf("set_com failed!\n");

  goto _out;

 }

 #endif

 

 //发送信息

 while(1)

 {

  printf("plese input a buffer : ");

  memset(w_buf, 0, sizeof(w_buf));

  fgets(w_buf, sizeof(w_buf), stdin);

  w_cnt = write(fd, w_buf, sizeof(w_buf));

  if(0 > w_cnt)

  {

   perror("write error : ");

   goto _out;

  }

  printf("sent out ! \n");

  

  //结束判断

  if( !strncmp(w_buf, "quit", 4) )

  {

   break;

  }

 }

 //关闭串口

 close(fd);

 return 0;

_out:

 close(fd);

 return -1;  

}

/****** 主函数 ****************************************************************************************/

int main(void)

{

 if( WriteUartInfo() )

 {

  printf("write uart data failed!\n");

  return -1;

 }

 

 return 0;

}

 

二:串口接收端程序

/***************************************************************************************************

 **文件:r_uart.c

 **编写者:huangminqiang

 **编写日期:2012年10月15号

 **简要描述:串口接收程序,在板子上运行。

 **修改者:

 **修改日期:2012年11月12号

 **注:

 ****************************************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <termios.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <sys/types.h>

#define COM "/dev/ttyAMA0"

/****** 读取串口信息 *********************************************************************************/

int ReadUartInfo(void)

{

 int fd;

 int cnt = 0;

 int r_cnt = 0;

 struct termios attr;

 fd_set r_fds;

 struct timeval tv;

 unsigned char r_buf[128] = {0};

 //打开串口

 fd = open(COM, O_RDWR);

 if(0 > fd)

 {

  perror("open uart error : ");

  return -1;

 }

 //由于串口设置已固化,故不需要设置。

 #if 0

 //设置串口参数

 if ( set_com(fd, B115200, CS8, NON, 1) )

 {

  printf("set_com failed!\n");

  goto _out;

 }

 #endif

 

 while(1)

 {

  //清除监测集合

  FD_ZERO(&r_fds);

  //将串口句柄加入到监测集合中

  FD_SET(fd, &r_fds);

  

  //设置超时为3秒

  tv.tv_sec = 3;

  tv.tv_usec = 0;

  

  //监测串口是否有数据接收到,超时为3秒

  cnt = select(fd + 1, &r_fds, NULL, NULL, &tv);

  switch(cnt)

  {

   case 0://超时

    //printf("time out !\n");

    break;

   case -1://错误

    perror("select : ");

    goto _out;

   default:

    if( FD_ISSET(fd, &r_fds) ) //有数据可读

    {

     //接收数据

     r_cnt = read(fd, r_buf, sizeof (r_buf));

     if(0 > r_cnt)

     {

      perror("read error : ");

      goto _out;

     }

     //printf("%s", r_buf);

     //system(r_buf);

    }

  }

  

  memset(r_buf, 0, sizeof(r_buf));  

 }

 

 //  关闭串口

 close(fd);

 return 0;

_out:

 close(fd);

 return -1; 

}

/****** 主函数 ***************************************************************************************/

int main(void)

{

 if( ReadUartInfo() )

 {

  printf("read uart data failed!\n");

  return -1;

 }

 

 return 0;

}

 

因为PC机上的串口设置已经固化,所以,没必要再配置了,串口的收发程序主要用于板子(新)上的,而上面的主要用于测试PC--板子间的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ttyAMA0 ttyS0 UART 串口