1..用户常见的数据通信的基本方式有两种:
并行通信;
串行通信;
串行通信是计算机常用的接口,如:RS-232-C接口。该标准规定采用一个DB25芯引脚连接器或DB9芯引脚连接器。
芯片内部常具有UART控制器,其可工作于Interrupt(中断模式)DMA(直接内存访问)模式。
2. UART的操作主要包括以下几个部分:
数据发送;
数据接收;
产生中断;
产生波特率;
Loopback模式;
红外模式;
自动流控模式
 串口参数的配置主要包括:波特率、数据位、停止位、流控协议。
3. linux中的串口设备文件存放于/dev目录下,其中串口一,串口二对应设备名依次为“/dev/ttyS0”、“/dev/ttyS1”。在linux下操作串口与操作文件相同。
4. 在使用串口之前必须设置相关配置,包括:波特率、数据位、校验位、停止位等。串口设置由下面结构体实现:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

4.1该结构中c_cflag最为重要,可设置波特率、数据位、校验位、停止位。在设置波特率时需在数字前加上‘B’,如B9600B19200。使用其需通过“与”“或”操作方式。
4.2输入模式c_iflag成员控制端口接收端的字符输入处理。
5.串口控制函数
Tcgetattr          取属性(termios结构)
Tcsetattr           设置属性(termios结构)
cfgetispeed     得到输入速度
Cfgetospeed             得到输出速度
Cfsetispeed               设置输入速度
Cfsetospeed              设置输出速度
Tcdrain              等待所有输出都被传输
tcflow               挂起传输或接收
tcflush              刷清未决输入和/或输出
Tcsendbreak              BREAK字符
tcgetpgrp                 得到前台进程组ID
tcsetpgrp                  设置前台进程组ID
6.串口配置流程
6.1保存原先串口配置使用tcgetattr(fd,&oldtio)函数
struct termios newtio,oldtio;
tcgetattr( fd,&oldtio );
6.2激活选项有CLOCALCREAD,用于本地连接和接收使能。
 newtio.c_cflag | =  CLOCAL | CREAD;

 

以下是我自己写的一个串口,仅供参考
/*****************************************************************************/

 

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>

 

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
         struct termios newtio,oldtio;
         if  ( tcgetattr( fd,&oldtio)  !=  0) {
                   perror("SetupSerial 1");
                   return -1;
         }
         memset( &newtio, sizeof( newtio ) );//将串口配置的结构体清零
         newtio.c_cflag  |=  CLOCAL | CREAD; //激活选项有CLOCALCREAD,用于本地连接和接收使能
         newtio.c_cflag &= ~CSIZE; //使原先的数据位清零

 

         switch( nBits )//选择数据位的个数
         {
         case 7:
                   newtio.c_cflag |= CS7;
                   break;
         case 8:
                   newtio.c_cflag |= CS8;
                   break;
         }

 

         switch( nEvent )
         {
         case 'O'://奇校验
                   newtio.c_cflag |= PARENB;
                   newtio.c_cflag |= PARODD;
                   newtio.c_iflag |= (INPCK | ISTRIP);
                   break;
         case 'E': //偶校验
                   newtio.c_iflag |= (INPCK | ISTRIP);
                   newtio.c_cflag |= PARENB;
                   newtio.c_cflag &= ~PARODD;
                   break;
         case 'N': //不进行奇偶校验
                   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, B9600);
                   cfsetospeed(&newtio, B9600);
                   break;
         }
         if( nStop == 1 )
                   newtio.c_cflag &=  ~CSTOPB;//设置停止位为1
         else if ( nStop == 2 )
         newtio.c_cflag |=  CSTOPB;//设置停止位为2
         newtio.c_cc[VTIME]  = 1;//read调用读到数据则立即返回,否则将为每个字符最多等待1个时间
         newtio.c_cc[VMIN] = 0;
         tcflush(fd,TCIFLUSH);//发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被删除(刷清)
         if((tcsetattr(fd,TCSANOW,&newtio))!=0)
         {
                   perror("com set error");
                   return -1;
         }
         printf("set done!\n");
         return 0;
}

 

int open_port(int fd,int comport)
{
         char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2","/dev/ttyS3"};
         long  vdisable;
         if (comport==1)
         {        fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);
                   if (-1 == fd){
                            perror("Can't Open Serial Port");
                            return(-1);
                   }
                   else
                            printf("open ttyS0 .....\n");
         }
         else if(comport==2)
         {        fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
                   if (-1 == fd){
                            perror("Can't Open Serial Port");
                            return(-1);
                   }
                   else
                            printf("open ttyS1 .....\n");
         }
         else if (comport==3)
         {
                   fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);
                   if (-1 == fd){
                            perror("Can't Open Serial Port");
                            return(-1);
                   }
                   else
                            printf("open ttyS2 .....\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)
                   printf("standard input is not a terminal device\n");
         else
                   printf("isatty success!\n");
         printf("fd-open=%d\n",fd);
         return fd;
}

 

int main(void)
{
         int fd;
         int nread,i;
         char buff[]="Hello\n";

 

         if((fd=open_port(fd,1))<0){
                   perror("open_port error");
                   return;
         }
         if((i=set_opt(fd,115200,8,'N',1))<0){
                   perror("set_opt error");
                   return;
         }
         printf("fd=%d\n",fd);
//      fd=3;
         while(1)
         {
         完成文件的读写操作
         }
         close(fd);
         return;
}
/*****************************************************************************/