亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Linux 操作系統下的串行口通訊編程

2019-11-17 05:02:11
字體:
來源:轉載
供稿:網友
    linux 操作系統從一開始就對串行口提供了很好的支持,本文就 Linux 下的串行口通訊編程進行簡單的介紹。串口簡介
    串行口是計算機一種常用的接口,具有連接線少,通訊簡單,得到廣泛的使用。常用的串口是 RS-232-C 接口(又稱 EIA RS-232-C)它是在 1970 年由美國電子工業協會(EIA)聯合貝爾系統、調制解調器廠家及計算機終端生產廠家共同制定的用于串行通訊的標準。它的全名是"數據終端設備(DTE)和數據通訊設備(DCE)之間串行二進制數據交換接口技術標準"該標準規定采用一個 25 個腳的 DB25 連接器,對連接器的每個引腳的信號內容加以規定,還對各種信號的電平加以規定。傳輸距離在碼元畸變小于 4% 的情況下,傳輸電纜長度應為 50 英尺。    Linux 操作系統從一開始就對串行口提供了很好的支持,本文就 Linux 下的串行口通訊編程進行簡單的介紹,假如要非常深入了解,建議看看本文所參考的《Serial PRogramming Guide for POSIX Operating Systems》計算機串口的引腳說明
<><>   
序號 信號名稱 符號 流向 功能
2 發送數據 TXD DTE→DCE DTE發送串行數據
3 接收數據 RXD DTE←DCE DTE 接收串行數據
4 請求發送 RTS DTE→DCE DTE 請求 DCE 將線路切換到發送方式
5 答應發送 CTS DTE←DCE DCE 告訴 DTE 線路已接通可以發送數據
6 數據設備預備好 DSR DTE←DCE DCE 預備好
7 信號地         信號公共地
8 載波檢測 DCD DTE←DCE 表示 DCE 接收到遠程載波
20 數據終端預備好 DTR DTE→DCE DTE 預備好
22 振鈴指示 RI DTE←DCE 表示 DCE 與線路接通,出現振鈴串口操作
串口操作需要的頭文件#include     <stdio.h>      /*標準輸入輸出定義*/
#include     <stdlib.h>     /*標準函數庫定義*/
#include     <unistd.h>     /*Unix 標準函數定義*/
#include     <sys/types.h> 
#include     <sys/stat.h>  
#include     <fcntl.h>      /*文件控制定義*/
#include     <termios.h>    /*PPSIX 終端控制定義*/
#include     <errno.h>      /*錯誤號定義*/打開串口
在 Linux 下串口文件是位于 /dev 下的串口一 為 /dev/ttyS0串口二 為 /dev/ttyS1打開串口是通過使用標準的文件打開函數操作:
int fd;
/*以讀寫方式打開串口*/
fd = open( "/dev/ttyS0", O_RDWR);
if (-1 == fd){
/* 不能打開串口一*/
perror(" 提示錯誤!");
}設置串口
最基本的設置串口包括波特率設置,效驗位和停止位設置。串口的設置主要是設置 strUCt termios 結構體的各成員值。
struct termio
{ unsigned short  c_iflag; /* 輸入模式標志 */ 
 unsigned short  c_oflag;  /* 輸出模式標志 */ 
 unsigned short  c_cflag;  /* 控制模式標志*/ 

 unsigned short  c_lflag;  /* local mode flags */ 
 unsigned char  c_line;      /* line discipline */ 
 unsigned char  c_cc[NCC];    /* control characters */
};設置這個結構體很復雜,我這里就只說說常見的一些設置:波特率設置下面是修改波特率的代碼:
struct  termios Opt;
tcgetattr(fd, &Opt);
cfsetispeed(&Opt,B19200);     /*設置為19200Bps*/
cfsetospeed(&Opt,B19200);
tcsetattr(fd,TCANOW,&Opt);設置波特率的例子函數:
/**
*@brief  設置串口通信速率
*@param  fd     類型 int  打開串口的文件句柄
*@param  speed  類型 int  串口速度
*@return  void
*/
int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
     B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {38400,  19200,  9600,  4800,  2400,  1200,  300, 38400, 
     19200,  9600, 4800, 2400, 1200,  300, };
void set_speed(int fd, int speed){
 int   i;
 int   status;
 struct termios   Opt;
 tcgetattr(fd, &Opt);
 for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {
  if  (speed == name_arr[i]) {    
   tcflush(fd, TCIOFLUSH);    
   cfsetispeed(&Opt, speed_arr[i]); 
   cfsetospeed(&Opt, speed_arr[i]);  
   status = tcsetattr(fd1, TCSANOW, &Opt); 
   if  (status != 0) {       
    perror("tcsetattr fd1"); 
    return;    
   }   
   tcflush(fd,TCIOFLUSH);  
  } 
 }
}效驗位和停止位的設置:
無效驗 8位 Option.c_cflag &= ~PARENB;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS8;
奇效驗(Odd) 7位 Option.c_cflag = ~PARENB;
Option.c_cflag &= ~PARODD;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS7;
偶效驗(Even) 7位 Option.c_cflag &= ~PARENB;
Option.c_cflag = ~PARODD;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS7;
Space效驗 7位 Option.c_cflag &= ~PARENB;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= &~CSIZE;
Option.c_cflag = CS8;更多文章 更多內容請看java編程開發手冊  Linux安全應用寶典  Linux防火墻專題,或 設置效驗的函數:

/**
*@brief   設置串口數據位,停止位和效驗位
*@param  fd     類型  int  打開的串口文件句柄
*@param  databits 類型  int 數據位   取值 為 7 或者8
*@param  stopbits 類型  int 停止位   取值為 1 或者2
*@param  parity  類型  int  效驗類型 取值為N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
 struct termios options;
 if  ( tcgetattr( fd,&options)  !=  0) {
  perror("SetupSerial 1");    
  return(FALSE); 
 }
 options.c_cflag &= ~CSIZE;
 switch (databits) /*設置數據位數*/
 {  
 case 7:  
  options.c_cflag = CS7;
  break;
 case 8:    
  options.c_cflag = CS8;
  break;  
 default:   
  fprintf(stderr,"Unsupported data size
"); return (FALSE); 
 }
switch (parity)
{  
 case 'n':
 case 'N':   
  options.c_cflag &= ~PARENB;   /* Clear parity enable */
  options.c_iflag &= ~INPCK;     /* Enable parity checking */
  break; 
 case 'o':  
 case 'O':    
  options.c_cflag = (PARODD PARENB); /* 設置為奇效驗*/ 
  options.c_iflag = INPCK;             /* Disnable parity checking */
  break; 
 case 'e': 
 case 'E':  
  options.c_cflag = PARENB;     /* Enable parity */   
  options.c_cflag &= ~PARODD;   /* 轉換為偶效驗*/    
  options.c_iflag = INPCK;       /* Disnable parity checking */
  break;
 case 'S':
 case 's':  /*as no parity*/  
      options.c_cflag &= ~PARENB;
  options.c_cflag &= ~CSTOPB;break; 
 default:  
  fprintf(stderr,"Unsupported parity");
  return (FALSE); 
 } 
/* 設置停止位*/ 
switch (stopbits)
{  
 case 1:   
  options.c_cflag &= ~CSTOPB; 
  break; 
 case 2:   
  options.c_cflag = CSTOPB; 
    break;
 default:   
   fprintf(stderr,"Unsupported stop bits

"); 
   return (FALSE);
}
/* Set input parity option */
if (parity != 'n')  
 options.c_iflag = INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 150; /* 設置超時15 seconds*/  
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)  
{
 perror("SetupSerial 3");  
 return (FALSE); 
}
return (TRUE); 
}需要注重的是:    假如不是開發終端之類的,只是串口傳輸數據,而不需要串口來處理,那么使用原始模式(Raw Mode)方式來通訊,設置方式如下:
options.c_lflag  &= ~(ICANON ECHO ECHOE ISIG);  /*Input*/
options.c_oflag  &= ~OPOST;   /*Output*/讀寫串口
設置好串口之后,讀寫串口就很輕易了,把串口當作文件讀寫就是。    * 發送數據
      char  buffer[1024];int    Length;int    nByte;nByte = write(fd, buffer ,Length)    * 讀取串口數據      使用文件操作read函數讀取,假如設置為原始模式(Raw Mode)傳輸數據,那么read函數返回的字符數是實際串口收到的字符數。      可以使用操作文件的函數來實現異步讀取,如fcntl,或者select等來操作。
      char  buff[1024];int    Len;int  readByte = read(fd,buff,Len);關閉串口
關閉串口就是關閉文件。
close(fd);更多文章 更多內容請看Java編程開發手冊  Linux安全應用寶典  Linux防火墻專題,或 例子
下面是一個簡單的讀取串口數據的例子,使用了上面定義的一些函數和頭文件

/**********************************************************************
代碼說明:使用串口二測試的,發送的數據是字符,
但是沒有發送字符串結束符號,所以接收到后,后面加上了結束符號。
我測試使用的是單片機發送數據到第二個串口,測試通過。
**********************************************************************/
#define FALSE  -1
#define TRUE   0
/*********************************************************************/
int OpenDev(char *Dev)
{
 int fd = open( Dev, O_RDWR );         // O_NOCTTY O_NDELAY 
 if (-1 == fd) 
 {    
  perror("Can't Open Serial Port");
  return -1;  
 } 
 else 
  return fd;
}
int main(int argc, char **argv){
 int fd;
 int nread;
 char buff[512];
 char *dev  = "/dev/ttyS1"; //串口二
 fd = OpenDev(dev);
 set_speed(fd,19200);
 if (set_Parity(fd,8,1,'N') == FALSE)  {
  printf("Set Parity Error
");
  exit (0);
 }
while (1) //循環讀取數據
{  
 while((nread = read(fd, buff, 512))>0)

 {
  printf("
Len %d
",nread);
  buff[nread+1] = '';  
  printf( "
%s", buff);  
 }
}
 //close(fd); 
 // exit (0);
}
//////////////////////////////////////////////////////////////////
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>#include "MySQL.h"#define BAUDRATE B9600
#define DEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1int insertdb(int d1, int d2, int d3, int d4) {
    MYSQL connect;
    int res, no1, no2, sd1, sd2;
    char *query = "INSERT INTO mydata  ( stime, sno1, sno2, sdata1, sdata2 ) VALUES ( '%s', %d, %d, %x, %x)";
    char *sql, *st1;
    struct tm *ptr;
    time_t lt;
   
    no1 = d1;
    no2 = d2;
    sd1 = d3;
    sd2 = d4;
    lt = time(NULL);
    ptr = localtime(&lt);
    st1 = (char *)asctime(ptr);
    st1[strlen(st1) -1 ] = '/0';
    sql = (char *)malloc(255*sizeof(char));
    sprintf(sql, query, st1, no1, no2, sd1, sd2);
   
/* debug here
    printf("%c : ", st1[strlen(st1)]);
    printf("%s : %d :",sql, strlen(st1));
    return EXIT_SUCCESS;
*/
   
    mysql_init(&connect);
   
    if(mysql_real_connect(&connect, "localhost", "root", "root", "mytest", 0, NULL, 0)) {
        printf("connect success!/n");        res = mysql_query(&connect, sql);        if(!res) {
            printf("insert success!/n");
        } else {
            fprintf(stderr, "insert error %d: %s/n", mysql_errno(&connect), mysql_error(&connect));
            return EXIT_FAILURE;
        }        mysql_close(&connect);
    } else {
        fprintf(stderr, "connect fail!/n");
        return EXIT_FAILURE;

    }    return EXIT_SUCCESS;
}int main(void) {
    int fd, res_w, res_r, i, j, k;
    struct termios oldtio,newtio;
    char inbuf[255];
    char cbuf[4];
    int buf[4];    res_w = 0;
    res_r = 0;
   
    fd = open(DEVICE, O_RDWR O_NOCTTY ); // O_NDELAY);
    if(fd < 0) {
        perror(DEVICE);
        exit(-1);
    }    tcgetattr(fd, &oldtio);bzero(&newtio,sizeof(struct termios));newtio.c_cflag= (CLOCAL CREAD);
newtio.c_cflag=BAUDRATE;
newtio.c_cflag&=~CSTOPB;
newtio.c_cflag&=~PARENB;
newtio.c_cflag&=~CSIZE;
newtio.c_cflag=CS8;
newtio.c_cflag&=~CRTSCTS;newtio.c_lflag=0;newtio.c_oflag=0;newtio.c_cc[VMIN]=4;
newtio.c_cc[VTIME]=0;newtio.c_iflag&=~(IXONIXOFFIXANY);cfsetispeed(&newtio, BAUDRATE);
cfsetospeed(&newtio, BAUDRATE);tcsetattr(fd, TCSANOW, &newtio);tcflush(fd, TCIFLUSH);               cbuf[0] = 0x00;   
//        cbuf[1] = 0x00;        j = 0;for(k = 0; k < 4; k++) {
    switch (j) {
        case 0:   
        default:
            cbuf[1] = 0x00;
            j = 2;
            break;
        case 2:
            cbuf[1] = 0x02;
            j = 0;
            break;
    }
           
    res_w = write(fd, cbuf, 2);/* debug here   
printf("cbuf : %x %x /n", cbuf[0], cbuf[1]);
printf("buf : %x : %x : %x : %x /n", inbuf[0], inbuf[1], inbuf[2], inbuf[3]);
*/
    res_r = read(fd, &inbuf, 255);
   
    if(res_r != -1) {
        for(i = 0; i < res_r; i++) {
            buf[i] = (int)inbuf[i];
            buf[i] = buf[i] & 0xff;
        //    printf(" %x ", buf[i]);           

        }
        printf("/n");
        if(insertdb(buf[0], buf[1], buf[2], buf[3]))
            printf("insert into db success!");
    }
    else {
        perror("read fail");
        exit(-1);
    }// if end here
}// for end here        tcsetattr(fd, TCSANOW, &oldtio);    close(fd);
    exit(0);
} // main end here更多文章 更多內容請看Java編程開發手冊  Linux安全應用寶典  Linux防火墻專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久精品免费视频| 亚洲精品v欧美精品v日韩精品| 久久久久久亚洲精品| 66m—66摸成人免费视频| 精品美女国产在线| 国产精彩精品视频| 国产精品入口免费视| 亚洲www永久成人夜色| 性色av一区二区三区红粉影视| xxav国产精品美女主播| 亚洲成人av在线播放| 久久免费在线观看| 亚洲第一视频网| 日韩美女写真福利在线观看| 中文字幕自拍vr一区二区三区| 欧美日韩亚洲视频| 国产va免费精品高清在线观看| 奇米一区二区三区四区久久| 中文国产亚洲喷潮| 日本成熟性欧美| 欧美性猛交xxxx免费看久久久| 久热国产精品视频| 中文字幕精品在线| 日韩精品中文字幕有码专区| 中文字幕日韩在线播放| 久久中文字幕在线视频| 亚洲色图狂野欧美| 国产一区二区三区在线播放免费观看| 国产精品永久免费视频| 91精品在线看| 国精产品一区一区三区有限在线| 亚洲国产成人精品久久久国产成人一区| 国产精品久久久久免费a∨| 国产有码一区二区| 欧美极品少妇全裸体| 国产xxx69麻豆国语对白| 中文字幕欧美日韩在线| 青青草国产精品一区二区| 中文字幕欧美在线| 亚洲美女又黄又爽在线观看| 欧美色videos| 国产91精品久久久久久久| 成人春色激情网| 国产一区二区三区视频| 国产精品扒开腿做爽爽爽视频| 欧美亚洲国产另类| 国内外成人免费激情在线视频网站| 国产一区二区丝袜| 性欧美xxxx| 色狠狠av一区二区三区香蕉蜜桃| 综合国产在线视频| 中文字幕不卡在线视频极品| 亚洲美女免费精品视频在线观看| 国产精品久久久999| 午夜剧场成人观在线视频免费观看| 韩日欧美一区二区| 色爱av美腿丝袜综合粉嫩av| 日韩精品丝袜在线| 中文字幕亚洲专区| 91精品免费视频| 亚洲欧美国产精品久久久久久久| 少妇高潮久久久久久潘金莲| 国产精品成人播放| 欧美人成在线视频| 久久精品视频网站| 精品国产福利在线| 久久久久久久久久久网站| 久久伊人精品一区二区三区| 国产精品久久久av久久久| 欧美成年人视频网站欧美| 国模gogo一区二区大胆私拍| 欧美激情综合色综合啪啪五月| 国内精品一区二区三区四区| 日韩精品极品在线观看播放免费视频| 国产精品久久久久久超碰| 国产黑人绿帽在线第一区| 日韩av不卡电影| 欧美黄色三级网站| 成人黄色大片在线免费观看| 亚洲欧美综合图区| 日韩精品视频免费专区在线播放| 久久躁狠狠躁夜夜爽| 国产视频精品va久久久久久| 伊人男人综合视频网| 精品成人在线视频| 国产在线观看91精品一区| 精品国产欧美一区二区五十路| 国产成人精品久久| 中文字幕日韩欧美在线视频| 欧美视频在线观看免费网址| 国产精品九九九| 亚洲黄色av网站| 亚洲伊人一本大道中文字幕| 成人免费淫片视频软件| 成人淫片在线看| 国产精品一区二区久久国产| 国产精品永久在线| 久久中文久久字幕| 日韩最新中文字幕电影免费看| 亚洲精品98久久久久久中文字幕| 亚洲精品成人久久久| 日韩视频在线免费观看| 国产一区二区日韩精品欧美精品| 美女少妇精品视频| 国产91免费看片| 久久久久免费视频| 麻豆一区二区在线观看| 亚洲999一在线观看www| 欧美裸体视频网站| 国产又爽又黄的激情精品视频| 欧美午夜精品久久久久久久| 久久久久九九九九| 欧美激情在线观看| 午夜精品久久久久久久男人的天堂| 日韩欧美中文字幕在线观看| 日韩亚洲欧美成人| 欧美—级高清免费播放| 不卡中文字幕av| 人人爽久久涩噜噜噜网站| 日韩综合视频在线观看| 日韩美女中文字幕| 欧美一级在线亚洲天堂| 91在线播放国产| 法国裸体一区二区| 777777777亚洲妇女| 日韩大陆欧美高清视频区| 日韩激情视频在线播放| yw.139尤物在线精品视频| 激情成人中文字幕| 亚洲成人黄色网址| 亚洲欧美一区二区三区在线| 日韩精品在线视频观看| 中文字幕亚洲色图| www日韩欧美| 欧美精品精品精品精品免费| 国产精品大片wwwwww| 国产在线观看91精品一区| 美女久久久久久久久久久| 亚洲第一国产精品| 日韩国产激情在线| 91欧美日韩一区| 91成人免费观看网站| 色无极影院亚洲| 欧美在线视频导航| 在线观看免费高清视频97| 九九九久久久久久| 97色在线播放视频| 亚洲在线观看视频网站| 中文字幕成人精品久久不卡| 中文字幕欧美精品日韩中文字幕| 国产啪精品视频| 欧洲美女免费图片一区| 欧美一级成年大片在线观看| 日韩在线视频观看| 青草热久免费精品视频| 色偷偷av一区二区三区乱| 亚洲香蕉成人av网站在线观看| 欧美巨猛xxxx猛交黑人97人| 成人欧美一区二区三区在线湿哒哒| 国产成人一区二区三区电影| 久久国产精品久久久久| 欧美韩国理论所午夜片917电影| 麻豆乱码国产一区二区三区| 中文欧美在线视频|