国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Linux 操作系統(tǒng)下的串行口通訊編程

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

 unsigned short  c_lflag;  /* local mode flags */ 
 unsigned char  c_line;      /* line discipline */ 
 unsigned char  c_cc[NCC];    /* control characters */
};設(shè)置這個(gè)結(jié)構(gòu)體很復(fù)雜,我這里就只說(shuō)說(shuō)常見(jiàn)的一些設(shè)置:波特率設(shè)置下面是修改波特率的代碼:
struct  termios Opt;
tcgetattr(fd, &Opt);
cfsetispeed(&Opt,B19200);     /*設(shè)置為19200Bps*/
cfsetospeed(&Opt,B19200);
tcsetattr(fd,TCANOW,&Opt);設(shè)置波特率的例子函數(shù):
/**
*@brief  設(shè)置串口通信速率
*@param  fd     類(lèi)型 int  打開(kāi)串口的文件句柄
*@param  speed  類(lèi)型 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);  
  } 
 }
}效驗(yàn)位和停止位的設(shè)置:
無(wú)效驗(yàn) 8位 Option.c_cflag &= ~PARENB;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS8;
奇效驗(yàn)(Odd) 7位 Option.c_cflag = ~PARENB;
Option.c_cflag &= ~PARODD;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS7;
偶效驗(yàn)(Even) 7位 Option.c_cflag &= ~PARENB;
Option.c_cflag = ~PARODD;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= ~CSIZE;
Option.c_cflag = ~CS7;
Space效驗(yàn) 7位 Option.c_cflag &= ~PARENB;
Option.c_cflag &= ~CSTOPB;
Option.c_cflag &= &~CSIZE;
Option.c_cflag = CS8;更多文章 更多內(nèi)容請(qǐng)看java編程開(kāi)發(fā)手冊(cè)  Linux安全應(yīng)用寶典  Linux防火墻專(zhuān)題,或 設(shè)置效驗(yàn)的函數(shù):

/**
*@brief   設(shè)置串口數(shù)據(jù)位,停止位和效驗(yàn)位
*@param  fd     類(lèi)型  int  打開(kāi)的串口文件句柄
*@param  databits 類(lèi)型  int 數(shù)據(jù)位   取值 為 7 或者8
*@param  stopbits 類(lèi)型  int 停止位   取值為 1 或者2
*@param  parity  類(lèi)型  int  效驗(yàn)類(lèi)型 取值為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) /*設(shè)置數(shù)據(jù)位數(shù)*/
 {  
 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); /* 設(shè)置為奇效驗(yàn)*/ 
  options.c_iflag = INPCK;             /* Disnable parity checking */
  break; 
 case 'e': 
 case 'E':  
  options.c_cflag = PARENB;     /* Enable parity */   
  options.c_cflag &= ~PARODD;   /* 轉(zhuǎn)換為偶效驗(yàn)*/    
  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); 
 } 
/* 設(shè)置停止位*/ 
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; /* 設(shè)置超時(shí)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); 
}需要注重的是:    假如不是開(kāi)發(fā)終端之類(lèi)的,只是串口傳輸數(shù)據(jù),而不需要串口來(lái)處理,那么使用原始模式(Raw Mode)方式來(lái)通訊,設(shè)置方式如下:
options.c_lflag  &= ~(ICANON ECHO ECHOE ISIG);  /*Input*/
options.c_oflag  &= ~OPOST;   /*Output*/讀寫(xiě)串口
設(shè)置好串口之后,讀寫(xiě)串口就很輕易了,把串口當(dāng)作文件讀寫(xiě)就是。    * 發(fā)送數(shù)據(jù)
      char  buffer[1024];int    Length;int    nByte;nByte = write(fd, buffer ,Length)    * 讀取串口數(shù)據(jù)      使用文件操作read函數(shù)讀取,假如設(shè)置為原始模式(Raw Mode)傳輸數(shù)據(jù),那么read函數(shù)返回的字符數(shù)是實(shí)際串口收到的字符數(shù)。      可以使用操作文件的函數(shù)來(lái)實(shí)現(xiàn)異步讀取,如fcntl,或者select等來(lái)操作。
      char  buff[1024];int    Len;int  readByte = read(fd,buff,Len);關(guān)閉串口
關(guān)閉串口就是關(guān)閉文件。
close(fd);更多文章 更多內(nèi)容請(qǐng)看Java編程開(kāi)發(fā)手冊(cè)  Linux安全應(yīng)用寶典  Linux防火墻專(zhuān)題,或 例子
下面是一個(gè)簡(jiǎn)單的讀取串口數(shù)據(jù)的例子,使用了上面定義的一些函數(shù)和頭文件

/**********************************************************************
代碼說(shuō)明:使用串口二測(cè)試的,發(fā)送的數(shù)據(jù)是字符,
但是沒(méi)有發(fā)送字符串結(jié)束符號(hào),所以接收到后,后面加上了結(jié)束符號(hào)。
我測(cè)試使用的是單片機(jī)發(fā)送數(shù)據(jù)到第二個(gè)串口,測(cè)試通過(guò)。
**********************************************************************/
#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) //循環(huán)讀取數(shù)據(jù)
{  
 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更多文章 更多內(nèi)容請(qǐng)看Java編程開(kāi)發(fā)手冊(cè)  Linux安全應(yīng)用寶典  Linux防火墻專(zhuān)題,或

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 四川省| 锦州市| 房山区| 西和县| 张掖市| 鱼台县| 洛南县| 吴忠市| 西盟| 柳林县| 通河县| 邢台县| 青川县| 浦城县| 宣恩县| 永清县| 黄浦区| 米林县| 沙河市| 东阿县| 修文县| 民丰县| 虹口区| 财经| 顺平县| 平和县| 苗栗市| 高尔夫| 陵水| 宕昌县| 兰溪市| 景东| 永定县| 屏山县| 南陵县| 屏山县| 北海市| 沈丘县| 涪陵区| 玉林市| 清新县|