日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux系統(tǒng)下的UART測試程序詳解(linuxuart測試程序)

引言

UART是一種常用的串行通信接口,常用于單片機(jī)和外圍設(shè)備之間進(jìn)行數(shù)據(jù)傳輸。Linux系統(tǒng)下提供了豐富的串口通信工具和庫函數(shù),可以非常方便地進(jìn)行串口通信測試和開發(fā)。本文將介紹Linux系統(tǒng)下的UART測試程序,詳細(xì)講解其原理、實(shí)現(xiàn)和使用方法。

一、UART簡介

UART(Universal Asynchronous Receiver/Tranitter)是一個(gè)通用異步串行接口,它可以支持異步傳輸和少量同步傳輸。在UART串口通信中,數(shù)據(jù)以字節(jié)為單位通過串行通信線路進(jìn)行傳輸,通信線路包括一條單向數(shù)據(jù)線(TX)和一條單向接收線(RX),同時(shí)還有一個(gè)以上的控制線(如CTS、RTS等)。

在UART通信中,數(shù)據(jù)傳輸是以一定波特率進(jìn)行的。波特率表示傳輸速率,即單位時(shí)間內(nèi)傳輸?shù)谋忍財(cái)?shù)。例如,對(duì)于波特率為9600 bps的UART串口通信,每秒可以傳輸9600個(gè)比特(即9600/8=1200個(gè)字節(jié))的數(shù)據(jù)。波特率越高,傳輸速度越快,但是傳輸距離越短,誤碼率越高。

二、UART測試程序原理

Linux系統(tǒng)下提供了多種測試UART串口通信的工具和庫函數(shù),例如minicom、stty、termios等。這些工具和庫函數(shù)都是基于系統(tǒng)調(diào)用函數(shù)編寫的,主要目的是為了方便用戶進(jìn)行串口通信的測試和開發(fā)。而本文將介紹一種基于C語言的UART測試程序,它可以直接調(diào)用串口設(shè)備文件的讀寫函數(shù)進(jìn)行數(shù)據(jù)的收發(fā)。具體原理如下:

1. 打開串口設(shè)備文件

在Linux系統(tǒng)下,每個(gè)串口都會(huì)被表示為一個(gè)設(shè)備文件,例如/dev/ttyS0、/dev/ttyS1等。在UART測試程序中,首先需要打開指定的串口設(shè)備文件,以便后續(xù)進(jìn)行數(shù)據(jù)的讀寫。

2. 設(shè)置串口參數(shù)

在進(jìn)行串口通信時(shí),需要設(shè)置一些參數(shù),如波特率、數(shù)據(jù)位、校驗(yàn)位、停止位等。通過串口控制寄存器,可以對(duì)這些參數(shù)進(jìn)行設(shè)置。在UART測試程序中,可以通過調(diào)用tcgetattr和tcsetattr等函數(shù)設(shè)置指定的串口參數(shù)。

3. 發(fā)送數(shù)據(jù)

在UART測試程序中,可以通過調(diào)用write函數(shù)向串口發(fā)送數(shù)據(jù)。write函數(shù)會(huì)將指定的數(shù)據(jù)寫入串口設(shè)備文件,發(fā)送給外部設(shè)備。

4. 接收數(shù)據(jù)

在UART測試程序中,可以通過調(diào)用read函數(shù)從串口接收數(shù)據(jù)。read函數(shù)會(huì)從串口設(shè)備文件中讀取數(shù)據(jù),存儲(chǔ)到緩沖區(qū)中,供后續(xù)進(jìn)行處理。

5. 關(guān)閉串口設(shè)備文件

在串口通信完成后,需要關(guān)閉打開的串口設(shè)備文件,以便下次進(jìn)行訪問。

三、UART測試程序?qū)崿F(xiàn)

基于上述原理,可以編寫C語言程序?qū)崿F(xiàn)UART測試功能。下面給出一段完整的UART測試程序代碼:

#include

#include

#include

#include

#include

int set_interface_attribs (int fd, int speed, int parity)

{

struct termios tty;

memset (&tty, 0, sizeof tty);

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

{

perror (“error %s from tcgetattr”);

return -1;

}

cfsetospeed (&tty, speed);

cfsetispeed (&tty, speed);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars

// disable IGNBRK for miatched speed tests; otherwise receive break

// as \000 chars

tty.c_iflag &= ~IGNBRK; // disable break processing

tty.c_lflag = 0; // no signaling chars, no echo,

// no canonical processing

tty.c_oflag = 0; // no remapping, no delays

tty.c_cc[VMIN] = 0; // read doesn’t block

tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,

// enable reading

tty.c_cflag &= ~(PARENB | PARODD); // shut off parity

tty.c_cflag |= parity;

tty.c_cflag &= ~CSTOPB;

tty.c_cflag &= ~CRTSCTS;

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

{

perror (“error %s from tcsetattr”);

return -1;

}

return 0;

}

void set_blocking (int fd, int should_block)

{

struct termios tty;

memset (&tty, 0, sizeof tty);

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

{

perror (“error %s from tggetattr”);

return;

}

tty.c_cc[VMIN] = should_block ? 1 : 0;

tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

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

perror (“error %s setting term attributes”);

}

int mn()

{

char buf[256];

int fd = open(“/dev/ttyS0”, O_RDWR | O_NOCTTY | O_SYNC);

if (fd

{

perror(“error opening”);

return -1;

}

set_interface_attribs(fd, B9600, 0); // set speed to 9600 bps, 8n1 (no parity)

set_blocking(fd, 0); // set no blocking

write(fd, “hello\n”, 6); // send 6 character greeting

usleep ((6 + 25) * 100); // sleep enough to tranit the 6 plus

// receive 25: approx 100 uS per char tranit

int n = read(fd, buf, sizeof buf); // read up to 100 characters if ready to read

printf(“received %d bytes: %s\n”, n, buf);

close(fd);

return 0;

}

本段代碼中,首先通過調(diào)用open函數(shù)打開指定的串口設(shè)備文件(/dev/ttyS0),然后通過tcgetattr和tcsetattr函數(shù)設(shè)置串口參數(shù)(波特率為9600,數(shù)據(jù)位為8位,校驗(yàn)位為無,停止位為1位)。通過write函數(shù)向串口發(fā)送一條數(shù)據(jù)“hello\n”,并通過read函數(shù)從串口接收數(shù)據(jù),存儲(chǔ)到buf緩沖區(qū)中。

在進(jìn)行編譯時(shí),需要將此代碼保存為uart_test.c文件,并通過gcc命令進(jìn)行編譯:

$ gcc uart_test.c -o uart_test

四、UART測試程序使用方法

在Linux系統(tǒng)上,進(jìn)行UART測試時(shí)需要先連接好串口線,將串口設(shè)備連接到計(jì)算機(jī)上。然后,執(zhí)行上述編譯好的uart_test程序即可進(jìn)行測試。如果測試通過,可以在終端上看到接收到的數(shù)據(jù)。

需要注意的是,在Linux系統(tǒng)下,串口設(shè)備文件的權(quán)限可能需要進(jìn)行修改才能進(jìn)行讀寫操作??梢酝ㄟ^chmod命令進(jìn)行修改,例如:

$ sudo chmod 666 /dev/ttyS0

這條命令將/dev/ttyS0串口設(shè)備文件的權(quán)限設(shè)置為666,即所有用戶都有讀寫權(quán)限。

結(jié)論

相關(guān)問題拓展閱讀:

  • linux下uart的文件節(jié)點(diǎn)是怎樣創(chuàng)建的
  • 如何在S3C2440上linux操作系統(tǒng)下將串口的波特率提高以致921600

linux下uart的文件節(jié)點(diǎn)是怎樣創(chuàng)建的

(1)試驗(yàn)?zāi)康?掌握通過文件系統(tǒng)操作UART設(shè)備的方爛槐法.

  (2)在linux中,所有設(shè)備都是以文件的形式被打開并進(jìn)行讀/寫慎橘操作的,本饑孝友試驗(yàn)中使用POSIX兼容的文件操作接口函數(shù)對(duì)底層設(shè)備進(jìn)行操作.其中,POSIX是Portable Operating System Interface for UNIX的首字母縮寫,是一套IEEE和ISO標(biāo)準(zhǔn).

如何在S3C2440上linux操作系統(tǒng)下將串口的波特率提高以致921600

就是把串口的波特率提上去,硬件環(huán)境呢,就是采用飛凌的TE2440-II(比較古老了,大家勿噴)操作系統(tǒng)是linux2.6.28,大家都知道,正常情況下,Linux下串口波特率更高到115200,因?yàn)槲覀兲厥庑枰脑颍枰巡ㄌ芈侍岣叩街辽?60800,當(dāng)然最理想的結(jié)果就是波特率達(dá)到921600,大的背景就是這個(gè)樣子了。

然后先考究硬件,看看在硬件上到底能不能滿足我們的要求,主控芯片S3C2440,在UART一章說在系統(tǒng)時(shí)鐘下,波特率更高可達(dá)115200,然后注釋中說如果Pclk達(dá)到60M,可以實(shí)現(xiàn)921600,我就按他說的,將主頻提高,順便將pclk提高到了60M,發(fā)現(xiàn)921600根本實(shí)現(xiàn)不了,230400波特率雖然能通,但是錯(cuò)誤率很高,根本無法用,然后我又嘗試著將Pclk提高到了70M,通過這種飲鴆止渴的方式,波特率可以提高到230400并且穩(wěn)定傳輸,但是更高的波特率則無法實(shí)現(xiàn),而Pclk不能無限提高,因?yàn)槲覀冮_發(fā)板還連接了觸摸屏,在Pclk70M的情況下,觸摸屏經(jīng)常重啟,說明這個(gè)方案不可行,所以就pass掉了,下面簡單說一下我怎么更改的系統(tǒng)時(shí)鐘Fclk,Hclk,Pclk。這三個(gè)時(shí)鐘的關(guān)系以及計(jì)算方法我就不贅述了,我主要參考博客

進(jìn)行修改

1)首先找到bootloader中 INC文件夾下的Option.inc文件,打開以后,找到如下代碼段,這段代碼就是主頻400M時(shí)對(duì)應(yīng)的M,P和S值設(shè)置,需要更改主頻的話虛野更改其中相應(yīng)的數(shù)值幾個(gè)(后來我發(fā)現(xiàn),其實(shí)這個(gè)地方不改也行,因?yàn)樽罱K起作用的是第二步)

CLKDIV_VAL EQU5

;1:4:8

M_MDIV EQU

127 ;127

M_PDIV EQU

2 ;2

M_SDIV EQU

1 ; 2440A

|

M_SDIV EQU

0 ; 2440X

>

>

2)找到u2440mon.c,然后在main()函數(shù)中找到如下代碼,修改case2中的mpll_val = (92flags & UPF_SPD_MASK) == UPF_SPD_CUST)

quot = port->custom_divisor;

else

quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud);

/* check to see if we need to change clock source */

if (ourport->clksrc != clksrc || ourport->baudclk != clk) {

s3c24xx_serial_setsource(port, clksrc);

if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {

clk_disable(ourport->baudclk);

ourport->baudclk = NULL;

}

clk_enable(clk);

ourport->clksrc = clksrc;

ourport->baudclk = clk;

}

其中,uart_get_baud_rate()函數(shù)用于計(jì)算出上位機(jī)程序到設(shè)置的波特率的值,經(jīng)我調(diào)試得知,上位機(jī)波特率從2400到921600都可以被準(zhǔn)確的計(jì)算出來;所以這個(gè)函數(shù)跳過,然后看最后那個(gè)if語句,這個(gè)語句的作用是產(chǎn)看目前的時(shí)鐘源是否與設(shè)置的時(shí)鐘源相同,如果不相同,則按照設(shè)置的時(shí)鐘源進(jìn)行更改,這里面還涉及l(fā)inux下的關(guān)于管理時(shí)鐘的一個(gè)結(jié)構(gòu)體clk結(jié)構(gòu)體,參照博客

以及

我找到了linux下的mach-dk2440.c這個(gè)文件,這個(gè)文件中定義了串口所用的clk結(jié)構(gòu)體,這也是linux系統(tǒng)啟動(dòng)時(shí)對(duì)串口的初始化配置結(jié)構(gòu)體都在這,但是我更改過這個(gè)地方,讓他初始化配置是選擇fclk作為串口的時(shí)鐘源,但是我發(fā)現(xiàn)這并沒有效果,所以繼續(xù)尋找中。

這樣就剩下一個(gè)函數(shù)可以考慮了,s3c24xx_serial_getclk(),進(jìn)入這個(gè)函數(shù)你會(huì)發(fā)現(xiàn),這個(gè)函數(shù)是對(duì)串口時(shí)鐘及波特率一個(gè)全面的配置,進(jìn)入這個(gè)函數(shù)中,就有個(gè)結(jié)構(gòu)體tmp_clksrc,這個(gè)結(jié)構(gòu)體很關(guān)鍵,他的內(nèi)容如下:

static struct s3c24xx_uart_clksrc tmp_clksrc = {

.name = “pclk”,

.min_baud

= 0,

.max_baud

= 0,

.divisor

= 1,

};

從這個(gè)名字中就可以看出,它把串口的時(shí)鐘源內(nèi)定成為了pclk,這也是罪魁禍?zhǔn)?,但是?dāng)我把name更改為fclk時(shí),整個(gè)系統(tǒng)就無法啟動(dòng)了,包括前面說的更改mach-dk2440.c中初始化配置,也是無法啟動(dòng),后來在配置串口是做了一個(gè)判斷,當(dāng)波特率低于202300時(shí),才有系統(tǒng)源配置不變,當(dāng)波特率高于202300時(shí),不在采用tmp_clksrc這個(gè)結(jié)構(gòu)體,而是采用我自己定義的一個(gè)結(jié)構(gòu)體,當(dāng)然就是把name改成fclk,發(fā)現(xiàn)雖然只是能夠更改 里面部分參數(shù)的時(shí)鐘源,而正在的時(shí)鐘源還是pclk,說明我的更改根本么有生效,由于這個(gè)linux調(diào)用太龐雜了,我就抱著試試看的態(tài)度,也是沒有辦法的辦法,在配置完串口時(shí)鐘的代碼之后,添加了如下幾行代碼,直接更改S3C2440的寄存器,我知道這樣做是很不“道德”的,而且很容易引起系統(tǒng)混亂,但是我只是這么試試,沒想到還真的有用。

在 samsung.c文件中添加

if (baud >=)

{

printk(“baud >=@samsung.c\n”);

__raw_writel(0x1fc5,S3C24XX_VA_UART0 + S3C2410_UCON);

__raw_writel(0x0fc5,S3C24XX_VA_UART1 + S3C2410_UCON);

__raw_writel(0x8fc5,S3C24XX_VA_UART2 + S3C2410_UCON);

__raw_writel(32,S3C24XX_VA_UART0 + S3C2410_UCON+0x24);//保證控制臺(tái)的波特率還是115200用于顯示

__raw_writel(3,S3C24XX_VA_UART1 + S3C2410_UCON+0x24);//921600

//__raw_writel(3,S3C24XX_VA_UART1 + S3C2410_UCON+0x24);

}

上面這段代碼經(jīng)我多次試驗(yàn)得到的,因?yàn)橐婚_始用的系統(tǒng)主時(shí)鐘fclk為400M,這樣算出來UBRDIV1分頻應(yīng)該為3,但是這樣的話錯(cuò)誤率比較高,還是導(dǎo)致無法傳輸,至此我終于明白手冊(cè)上為什么說pclk在60M 可以實(shí)現(xiàn)921600了,因?yàn)橛?0M時(shí)鐘計(jì)算的話,分頻UBRDIV1為3.069,最接近整數(shù)3,所以在這個(gè)錯(cuò)誤率下可以實(shí)現(xiàn)921600的波特率傳輸,所以我將系統(tǒng)時(shí)鐘fclk設(shè)置為420M,其中MDIV=97,PDIV=1,SDIV=1,而ucon0=0x1fc5,ucon1=0x0fc5,ucon2=0x8fc5,這樣n=1+6=7,所以串口的時(shí)鐘源為fclk/n=60M,可以得到精確的921600波特率,所以實(shí)現(xiàn)我剛開始的目標(biāo),其實(shí)要實(shí)現(xiàn)其他的波特率也可以,比如460800,計(jì)算后主時(shí)鐘fclk(盡量算出的分頻UBRDIV1最貼近整數(shù)),然后就可以實(shí)現(xiàn)了。

在這還有個(gè)小想法,提高串口波特率,還可以使用USB轉(zhuǎn)串口,因?yàn)閁SB轉(zhuǎn)串口可以實(shí)現(xiàn)921600,而linux中以及集成了USB轉(zhuǎn)串口的驅(qū)動(dòng),只需要在調(diào)用串口的那個(gè)open函數(shù)中改為調(diào)用USB轉(zhuǎn)串口的節(jié)點(diǎn)即可,當(dāng)然,這個(gè)方案我沒有試,因?yàn)槲覀兙鸵粋€(gè)USB口,而且還被占用了,所以希望有需要的朋友可以試一下。

用 stty 命令 (使用前請(qǐng)確認(rèn)你的終端設(shè)備確實(shí)支持這個(gè)速率), 比如

stty# 設(shè)置 baud rate 到

stty speed    # 查看當(dāng)前終端 baud rate

# 如果不是設(shè)置當(dāng)洞銷前終端段游,則用下面的命令納燃游設(shè)置指定終端設(shè)備

stty -F /dev/

88、四時(shí)田園雜興范大成

88、四時(shí)田園雜興 范大成

linux uart測試程序的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux uart測試程序,Linux系統(tǒng)下的UART測試程序詳解,linux下uart的文件節(jié)點(diǎn)是怎樣創(chuàng)建的,如何在S3C2440上linux操作系統(tǒng)下將串口的波特率提高以致921600的信息別忘了在本站進(jìn)行查找喔。

創(chuàng)新互聯(lián)服務(wù)器托管擁有成都T3+級(jí)標(biāo)準(zhǔn)機(jī)房資源,具備完善的安防設(shè)施、三線及BGP網(wǎng)絡(luò)接入帶寬達(dá)10T,機(jī)柜接入千兆交換機(jī),能夠有效保證服務(wù)器托管業(yè)務(wù)安全、可靠、穩(wěn)定、高效運(yùn)行;創(chuàng)新互聯(lián)專注于成都服務(wù)器托管租用十余年,得到成都等地區(qū)行業(yè)客戶的一致認(rèn)可。


分享題目:Linux系統(tǒng)下的UART測試程序詳解(linuxuart測試程序)
標(biāo)題網(wǎng)址:http://www.dlmjj.cn/article/cdeocgc.html