串口的基本原理
1 串口通訊
串口通訊(Serial Communication),是指外設(shè)和計(jì)算機(jī)間,通過數(shù)據(jù)信號(hào)線、地線等,按位進(jìn)行傳輸數(shù)據(jù)的一種通訊方式。
串口是一種接口標(biāo)準(zhǔn),它規(guī)定了接口的電氣標(biāo)準(zhǔn),沒有規(guī)定接口插件電纜以及使用的協(xié)議。
2 串口通訊的數(shù)據(jù)格式
一個(gè)字符一個(gè)字符地傳輸,每個(gè)字符一位一位地傳輸,并且傳輸一個(gè)字符時(shí),總是以“起始位”開始,以“停止位”結(jié)束,字符之間沒有固定的時(shí)間間隔要求。
每一個(gè)字符的前面都有一位起始位(低電平),字符本身由7位數(shù)據(jù)位組成,接著字符后面是一位校驗(yàn)位(檢驗(yàn)位可以是奇校驗(yàn)、偶校驗(yàn)或無校驗(yàn)位),最后是一位或一位半或二位停止位,停止位后面是不定長(zhǎng)的空閑位,停止位和空閑位都規(guī)定為高電平。實(shí)際傳輸時(shí)每一位的信號(hào)寬度與波特率有關(guān),波特率越高,寬度越小,在進(jìn)行傳輸之前,雙方一定要使用同一個(gè)波特率設(shè)置。
3 通訊方式
單工模式(Simplex Communication)的數(shù)據(jù)傳輸是單向的。通信雙方中,一方固定為發(fā)送端,一方則固定為接收端。信息只能沿一個(gè)方向傳輸,使用一根傳輸線。
半雙工模式(Half Duplex)通信使用同一根傳輸線,既可以發(fā)送數(shù)據(jù)又可以接收數(shù)據(jù),但不能同時(shí)進(jìn)行發(fā)送和接收。數(shù)據(jù)傳輸允許數(shù)據(jù)在兩個(gè)方向上傳輸,但是,在任何時(shí)刻只能由其中的一方發(fā)送數(shù)據(jù),另一方接收數(shù)據(jù)。因此半雙工模式既可以使用一條數(shù)據(jù)線,也可以使用兩條數(shù)據(jù)線。半雙工通信中每端需有一個(gè)收發(fā)切換電子開關(guān),通過切換來決定數(shù)據(jù)向哪個(gè)方向傳輸。因?yàn)橛星袚Q,所以會(huì)產(chǎn)生時(shí)間延遲,信息傳輸效率低些。
全雙工模式(Full Duplex)通信允許數(shù)據(jù)同時(shí)在兩個(gè)方向上傳輸。因此,全雙工通信是兩個(gè)單工通信方式的結(jié)合,它要求發(fā)送設(shè)備和接收設(shè)備都有獨(dú)立的接收和發(fā)送能力。在全雙工模式中,每一端都有發(fā)送器和接收器,有兩條傳輸線,信息傳輸效率高。
顯然,在其它參數(shù)都一樣的情況下,全雙工比半雙工傳輸速度要快,效率要高。
4 偶校驗(yàn)與奇校驗(yàn)
在標(biāo)準(zhǔn)ASCII碼中,其最高位(b7)用作奇偶校驗(yàn)位。所謂奇偶校驗(yàn),是指在代碼傳送過程中用來檢驗(yàn)是否出現(xiàn)錯(cuò)誤的一種方法,一般分奇校驗(yàn)和偶校驗(yàn)兩種。奇校驗(yàn)規(guī)定:正確的代碼一個(gè)字節(jié)中1的個(gè)數(shù)必須是奇數(shù),若非奇數(shù),則在最高位b7添1;偶校驗(yàn)規(guī)定:正確的代碼一個(gè)字節(jié)中1的個(gè)數(shù)必須是偶數(shù),若非偶數(shù),則在最高位b7添1。
5 停止位
停止位是按長(zhǎng)度來算的。串行異步通信從計(jì)時(shí)開始,以單位時(shí)間為間隔(一個(gè)單位時(shí)間就是波特率的倒數(shù)),依次接受所規(guī)定的數(shù)據(jù)位和奇偶校驗(yàn)位,并拼裝成一個(gè)字符的并行字節(jié);此后應(yīng)接收到規(guī)定長(zhǎng)度的停止位“1”。所以說,停止位都是“1”,1.5是它的長(zhǎng)度,即停止位的高電平保持1.5個(gè)單位時(shí)間長(zhǎng)度。一般來講,停止位有1,1.5,2個(gè)單位時(shí)間三種長(zhǎng)度。
6 波特率
波特率就是每秒鐘傳輸?shù)臄?shù)據(jù)位數(shù)。
波特率的單位是每秒比特?cái)?shù)(bps),常用的單位還有:每秒千比特?cái)?shù)Kbps,每秒兆比特?cái)?shù)Mbps。串口典型的傳輸波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps,38400bps。
PLC/PC與稱重儀表通訊時(shí),最常用的波特率是9600bps,19200bps。PLC/PC或儀表與大屏幕通訊時(shí),最常用的波特率是600bps。
7 典型的串口通訊標(biāo)準(zhǔn)
EIA RS232(通常簡(jiǎn)稱“RS232”): 1962年由美國電子工業(yè)協(xié)會(huì)(EIA)制定。
EIA RS485(通常簡(jiǎn)稱“RS485”): 1983年由美國電子工業(yè)協(xié)會(huì)(EIA)制定。
8 RS232串口
RS232是計(jì)算機(jī)與通信工業(yè)應(yīng)用中最廣泛一種串行接口。它以全雙工方式工作,需要地線、發(fā)送線和接收線三條線。RS232只能實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)的通信方式。
8.1 RS232串口缺點(diǎn)
●接口信號(hào)電平值較高,接口電路芯片容易損壞。
●傳輸速率低,最高波特率19200bps。
●抗干擾能力較差。
●傳輸距離有限,一般在15m以內(nèi)。
●只能實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)的通訊方式。
8.2 RS232串口接口定義
RXD:接收數(shù)據(jù),TXD:發(fā)送數(shù)據(jù),GND/SG:信號(hào)地。
8.3 電腦DB9針接口定義
電腦DB9針接口是常見的RS232串口,其引腳定義如下:
2號(hào)腳:RXD(接收數(shù)據(jù))
3號(hào)腳:TXD(發(fā)送數(shù)據(jù))
5號(hào)腳:SG或GND(信號(hào)地)
其它腳:我們不用
電腦RS232串口與儀表串口連接圖:
9 RS485串口
9.1 RS485串口特點(diǎn)
●RS485采用平衡發(fā)送和差分接收,具有良好的抗干擾能力,信號(hào)能傳輸上千米。
●RS485有兩線制和四線制兩種接線。采用四線制時(shí),只能實(shí)現(xiàn)點(diǎn)對(duì)多的通訊(即只能有一個(gè)主設(shè)備,其余為從設(shè)備)。四線制現(xiàn)在很少采用,現(xiàn)在多采用兩線制接線方式。
●兩線制RS485只能以半雙式方式工作,收發(fā)不能同時(shí)進(jìn)行。
●RS485在同一總線上最多可以接32個(gè)結(jié)點(diǎn),可實(shí)現(xiàn)真正的多點(diǎn)通訊,但一般采用的是主從通信方式,即一個(gè)主機(jī)帶多個(gè)從機(jī)。
●因RS485接口具有良好的抗干擾能力,長(zhǎng)的傳輸距離和多站能力等優(yōu)點(diǎn)使其成為首選的串行接口。
10 串口通訊硬件常見的注意事項(xiàng)
●通訊電纜端子一定接牢,不可有任何松動(dòng),否則,可能會(huì)燒壞儀表或上位機(jī)的通訊板。
●不可帶電拔插通訊端子,否則,可能會(huì)燒壞儀表或上位機(jī)的通訊板,一定要關(guān)閉儀表電源后才能去拔插通訊端子或接通訊線。
●通訊用的屏蔽電纜最好選用雙層隔離型屏蔽電纜,其次選用單層屏蔽電纜,最好不要選用無屏蔽層的電纜,且電纜屏蔽層一定要能完全屏蔽,有些質(zhì)量差的電纜,屏蔽層很松散,根本起不到屏蔽的作用。單層屏蔽的電纜屏蔽層應(yīng)一端接地,雙層屏蔽的電纜屏蔽層其外層(含鎧裝)應(yīng)兩端接地,內(nèi)層屏蔽則應(yīng)一端接地。
●儀表使用RS232通訊時(shí),通訊電纜長(zhǎng)度不得超過15米。
●一般RS485協(xié)議的接頭沒有固定的標(biāo)準(zhǔn),可能根據(jù)廠家的不同引腳順序和管腳功能可能不盡相同,用戶可以查閱相關(guān)產(chǎn)品RS485的引腳圖。
●RS485通訊電纜最好選用阻阬匹配、低衰減的RS485專用通訊電纜(雙絞線),不要使用普通的雙絞電纜或質(zhì)量較差的通訊電纜。因?yàn)槠胀娎|或質(zhì)量差的通訊電纜,可能阻抗不匹配、衰減大、絞合度不夠、屏蔽層太松散,這樣會(huì)導(dǎo)致干擾將非常大,會(huì)造成通訊不暢,甚至通訊不上。
●儀表使用RS485通訊時(shí),每臺(tái)儀表必須手牽手地串下去,不可以有星型連接或者分叉,如果有星型連接或者分叉,干擾將非常大,會(huì)造成通訊不暢,甚至通訊不上。
●485總線結(jié)構(gòu)理論上傳輸距離達(dá)到1200米,一般是指通訊線材優(yōu)質(zhì)達(dá)標(biāo),波特率9600,只有一臺(tái)485設(shè)備才能使得通訊距離達(dá)到1200米,而且能通訊并不代表每次通訊都正常,所以通常485總線實(shí)際的穩(wěn)定通訊距離遠(yuǎn)遠(yuǎn)達(dá)不到1200米。負(fù)載485設(shè)備多,線材阻抗不同時(shí),通訊距離更短。
●儀表使用RS485通訊時(shí),必要時(shí),請(qǐng)接入終端電阻,以增強(qiáng)系統(tǒng)的抗干擾性,典型的終端電阻阻值是120歐。
11 串口通訊軟件設(shè)置要點(diǎn)
11.1 有關(guān)通訊的一些基本概念
●主機(jī)與從機(jī):在通訊系統(tǒng)中起主要作用、發(fā)布主要命令的稱為主機(jī),接受命令的稱為從機(jī)。
●連續(xù)方式:指主機(jī)不需要發(fā)布命令,從機(jī)就能自動(dòng)地向主機(jī)發(fā)送數(shù)據(jù)。
●指令方式:指主機(jī)向從機(jī)發(fā)布命令,從機(jī)根據(jù)指令執(zhí)行動(dòng)作,并將結(jié)果“應(yīng)答”給主機(jī)的模式。
●輸出數(shù)據(jù)類型:指在連續(xù)方式通訊時(shí),從機(jī)輸出給主機(jī)的數(shù)據(jù)類型。
●通訊協(xié)議:指主機(jī)與從機(jī)通訊時(shí),按哪一種編碼規(guī)則來通訊。
●波特率:主從機(jī)之間通訊的速度。
●數(shù)據(jù)位:每次傳輸數(shù)據(jù)時(shí),數(shù)據(jù)由幾位組成。
●校驗(yàn)位:數(shù)據(jù)傳輸錯(cuò)誤檢測(cè),可以是奇校驗(yàn)、偶校驗(yàn)或無校驗(yàn)。
●地址:每一臺(tái)從機(jī)的編號(hào)。
11.2 主從機(jī)之間通訊設(shè)置要點(diǎn)
●要點(diǎn)一:主/從RS232/485硬件有無設(shè)置正確,通訊線有無接對(duì)。有些通訊板卡是RS422與RS485共用的,依靠板上跳線來實(shí)現(xiàn)的,有些儀表RS232/485也需要通訊跳線來實(shí)現(xiàn)。
●要點(diǎn)二:主機(jī)上的通訊端口有無設(shè)置正確;超時(shí)(一般設(shè)置為2s)、通訊延時(shí)(一般設(shè)置為5~20ms)、ACK信號(hào)延時(shí)(一般設(shè)置為0ms)有無設(shè)置正確。
●要點(diǎn)三:主/從機(jī)通訊協(xié)議有無選擇正確。
●要點(diǎn)四:主/從機(jī)波特率有無選擇正確。
●要點(diǎn)五:主/從機(jī)數(shù)據(jù)位有無選擇正確。數(shù)據(jù)位可以選擇7位,8位。
●要點(diǎn)六:主/從機(jī)校驗(yàn)位有無選擇正確。校驗(yàn)位一般可選擇偶校驗(yàn)、奇校驗(yàn)、無校驗(yàn)。
●要點(diǎn)七:主/從機(jī)停止位有無選擇正確。停止位可以選擇1位、1.5位還是2位。
●要點(diǎn)八:從機(jī)地址有無選擇正確。
●要點(diǎn)九:主/從機(jī)的通訊方式有無選擇正確。
進(jìn)行通訊測(cè)試的時(shí)候經(jīng)常會(huì)進(jìn)行線路測(cè)試,測(cè)試所用的串口線是否可用,方法有二如下:
1》 把串口線接到不同的串口,用串口調(diào)試工具從一個(gè)串口發(fā)數(shù)據(jù),另一個(gè)能正常收到說明串口線是OK的。
2》 把串口線的一端短接(用金屬把2,3號(hào)腳連通),用萬用表測(cè)另一端的2,3號(hào)如果正常的話會(huì)有嘀嘀的短接報(bào)警聲。
二、linux下串口的基本操作
1、串口的操作
1.1打開:fd = open(“/dev/ttySAC1”, O_RDWR | O_NOCTTY | O_NDELAY);
O_RDWR 讀寫方式打開;
O_NOCTTY 不允許進(jìn)程管理串口(不太理解,一般都選上);
O_NDELAY 非阻塞(默認(rèn)為阻塞,打開后也可以使用fcntl()重新設(shè)置)
1.2寫入:n = write(fd, “l(fā)inux”, 5);
n實(shí)際寫入字節(jié)數(shù);
1.3讀取:res = read(fd,buf,len);
res 讀取的字節(jié)數(shù);
1.4設(shè)置:fcntl(fd, F_SETFL, FNDELAY); //非阻塞
fcntl(fd, F_SETFL, 0); // 阻塞
1.5關(guān)閉:close(fd);
2、串口配置
struct termios options; // 串口配置結(jié)構(gòu)體
tcgetattr(fd,&options); //獲取當(dāng)前設(shè)置
bzero(&options,sizeof(options));
options.c_cflag |= B115200 | CLOCAL | CREAD; // 設(shè)置波特率,本地連接,接收使能
options.c_cflag &= ~CSIZE; //屏蔽數(shù)據(jù)位
options.c_cflag |= CS8; // 數(shù)據(jù)位為 8 ,CS7 for 7
options.c_cflag &= ~CSTOPB; // 一位停止位, 兩位停止為 |= CSTOPB
options.c_cflag &= ~PARENB; // 無校驗(yàn)
//options.c_cflag |= PARENB; //有校驗(yàn)
//options.c_cflag &= ~PARODD // 偶校驗(yàn)
//options.c_cflag |= PARODD // 奇校驗(yàn)
options.c_cc[VTIME] = 0; // 等待時(shí)間,單位百毫秒 (讀)。后有詳細(xì)說明
options.c_cc[VMIN] = 0; // 最小字節(jié)數(shù) (讀)。后有詳細(xì)說明
tcflush(fd, TCIOFLUSH); // TCIFLUSH刷清輸入隊(duì)列。
TCOFLUSH刷清輸出隊(duì)列。
TCIOFLUSH刷清輸入、輸出隊(duì)列。
tcsetattr(fd, TCSANOW, &options); // TCSANOW立即生效;
TCSADRAIN:Wait until everything has been transmitted;
TCSAFLUSH:Flush input and output buffers and make the change
3、VTIME 和 VMIN
VTIME 定義要求等待的零到幾百毫秒的值(通常是一個(gè)8位的unsigned char變量)。
VMIN 定義了要求等待的最小字節(jié)數(shù), 這個(gè)字節(jié)數(shù)可能是0。
只有設(shè)置為阻塞時(shí)這兩個(gè)參數(shù)才有效,僅針對(duì)于讀操作。
說起來比較復(fù)雜,舉個(gè)例子吧,設(shè)置為阻塞狀態(tài),寫操作未進(jìn)行實(shí)驗(yàn),這里僅討論讀操作,
read(fd,&buf,8); // 讀串口
3.1
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
VMIN = 0,當(dāng)緩沖區(qū)字節(jié)數(shù) 》= 0 時(shí)進(jìn)行讀操作,實(shí)際上這時(shí)讀串口操作并未被阻塞,因?yàn)闂l件始終被滿足。
3.2
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 1;
VMIN = 1,當(dāng)緩沖區(qū)字節(jié)數(shù) 》= 1 時(shí)進(jìn)行讀操作,當(dāng)沒有數(shù)據(jù)時(shí)讀串口操作被阻塞。
3.3
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 4;
VMIN = 4,當(dāng)緩沖區(qū)字節(jié)數(shù) 》= 4 時(shí)進(jìn)行讀操作,否則讀串口操作被阻塞。每次讀出的最大字節(jié)數(shù)由read函數(shù)中第三個(gè)參數(shù)決定。直到緩沖區(qū)剩下的數(shù)據(jù)《 read 第三個(gè)參數(shù) 并且《 4 (如果這時(shí)read第三參數(shù)為 1 則進(jìn)行4次讀操作直至讀完緩沖區(qū),如read第三參數(shù)為2,連續(xù)進(jìn)行讀操作,直至緩沖區(qū)空或還剩一個(gè)字符)。沒有設(shè)置VTIME,剩下的字符沒有確定的期限,直到下次滿足讀條件的時(shí)候才被讀出。
----------------------------------考慮VTIME-----------------------------
3.4
options.c_cc[VTIME] = 10; //單位百毫秒
options.c_cc[VMIN] = 4;
同3.3的區(qū)別就是,沒滿足條件或讀緩沖區(qū)中剩下的數(shù)據(jù)會(huì)在1秒(10百毫秒)后讀出。另外特別注意的是當(dāng)設(shè)置VTIME后,如果read第三個(gè)參數(shù)小于VMIN ,將會(huì)將VMIN 修改為read的第三個(gè)參數(shù),即使用read(fd,&buf,2);,以上設(shè)置變?yōu)椋?/p>
options.c_cc[VTIME] = 10;
options.c_cc[VMIN] = 2;
1》打開串口函數(shù)open_port()中要實(shí)現(xiàn)的函數(shù):
(1)open(“/dev/ttys0”,O_RDWR | O_NOCTTY | O_NDELAY);/*打開串口0*/
(2)fcntl(fd,F(xiàn)_SETFL,0)/*恢復(fù)串口為阻塞狀態(tài)*/
(3)isatty(STDIN_FILENO) /*測(cè)試是否為中斷設(shè)備 非0即是中斷設(shè)備*/
2》 配置串口參數(shù)函數(shù)set_opt()中要實(shí)現(xiàn)的函數(shù):
(1)保存原先有串口配置
tcgetattr(fd,&oldtio);
(2)先將新串口配置清0
bzore(&newtio,sizeof(newito));
(3)激活選項(xiàng)CLOCAL和CREAD 并設(shè)置數(shù)據(jù)位大小
newtio.c_cflag |=CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
newtio.c_cflag |=CS8;
(4)設(shè)置奇偶校驗(yàn)
奇校驗(yàn):
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
偶校驗(yàn):
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PAREND;
newtio.c_cflag &= ~PARODD;
無奇偶校驗(yàn):
newtio.c_cflag &= ~PARENB;
(5) 設(shè)置停止位
newtio.c_cflag &= ~CSTOPB; /*停止位為1*/
newtio.c_cflag |= CSTOPB;/*停止位為0*/
(6)設(shè)置波特率:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
(7)設(shè)置等待時(shí)間和最小接受字符:
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
(8)處理為接收字符:
tcflush(fd,TCIFLUSH);
(9)激活新配置:
tcsetattr(fd,TCSANOW,&newtio);
3.讀寫串口
write(fd,buff,8);
read(fd,buff,8);
三、串口編程實(shí)例:
[cpp] view plain copy#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)
{
/* 五個(gè)參量 fd打開文件 speed設(shè)置波特率 bit數(shù)據(jù)位設(shè)置 neent奇偶校驗(yàn)位 stop停止位 */
struct termios newtio,oldtio;
if ( tcgetattr( fd,&oldtio) != 0) {
perror(“SetupSerial 1”);
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
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;
else if ( nStop == 2 )
newtio.c_cflag |= CSTOPB;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror(“com set error”);
return -1;
}
printf(“set done! ”);
return 0;
}
int open_port(int fd,int comport)
{
/* fd 打開串口 comport表示第幾個(gè)串口 */
char *dev[]={“/dev/ttyS0”,“/dev/ttyS1”,“/dev/ttyS2”};
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 。。.。。 ”);
}
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 。。.。。 ”);
}
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 。。.。。 ”);
}
if(fcntl(fd, F_SETFL, 0)《0)
printf(“fcntl failed! ”);
else
printf(“fcntl=%d ”,fcntl(fd, F_SETFL,0));
if(isatty(STDIN_FILENO)==0)
printf(“standard input is not a terminal device ”);
else
printf(“isatty success! ”);
printf(“fd-open=%d ”,fd);
return fd;
}
int main(void)
{
int fd;
int nread,i;
char buff[]=“Hello ”;
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 ”,fd);
// fd=3;
nread=read(fd,buff,8);
printf(“nread=%d,%s ”,nread,buff);
close(fd);
return;
}
評(píng)論