UART通信

来源:http://www.cnblogs.com/dq23578/archive/2017/05/23/6774179.html
-Advertisement-
Play Games

UART0串口調試過程:1、配置DTS節點 在Z:\rk3399\kernel\arch\arm64\boot\dts\rockchip路徑下打開rk3399.dtsi文件,裡面已經有UART0相關節點定義,如下所示: uart0: serial@ff180000 { compatible = "r ...


UART0串口調試過程:
1、配置DTS節點
  在Z:\rk3399\kernel\arch\arm64\boot\dts\rockchip路徑下打開rk3399.dtsi文件,裡面已經有UART0相關節點定義,如下所示:
    uart0: serial@ff180000 {
    compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart";
    reg = <0x0 0xff180000 0x0 0x100>;
    clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
    clock-names = "baudclk", "apb_pclk";
    interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH 0>;
    reg-shift = <2>;
    reg-io-width = <4>;
    pinctrl-names = "default";
    pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
    status = "disabled"; // 使用UART0時需將“disabled”改為“okay”
    };
  由於本次調試使用UART0作為調試外接串口,所以需對UART0進行使能配置,即將上述定義中的最後一句status = "disabled"改為status = "okay",從而完成使能配置,將內核重新編譯,並將kernel.img和resource.img燒寫到開發板中。

2、編寫測試代碼(見附件ursend.c和receive.c文件)
ursend.c用來發送開發板中的數據,主要包括波特率設置函數set_speed(),奇偶校驗設置函數set_parity(),串口數據發送函數serial_send()三個函數;
receive.c用來讀取從PC端發送的數據內容。
3、連接硬體
將開發板uart0的TX、RX、GND(分別對應圖1中引腳18、16、14)引腳分別和主機串口適配器的RX、TX、GND引腳相連,並PC端使用串口調試助手軟體將主機的波特率設置與開發板的波特率一致,同時連接到相應串口,uart0串口所在的GPIO_EXT部分硬體示意圖如下:

                  圖1 GPIO_EXT示意圖

4、開發板發送數據,PC端讀取串口數據
在Z:\rk3399\external路徑下新建一個文件夾,命名為uart_send,裡面包含兩個文件:ursend.c和Android.mk,執行mm指令後得到可執行文件ursend。將可執行文件ursend傳送到開發板/system/xbin目錄下,在/system/xbin路徑下執行./ursend指令後即完成發送操作,圖2為在開發板上運行數據發送程式ursend。

               圖2 開發板發送數據

然後在串口調試助手上就可以看到要接收到的數據內容,如下圖所示:

                    圖3 PC端數據接收

註:如果開發板發送端串口和主機接收端串口的波特率已經設置成一致,也可以在開發板終端上使用echo Hello, this is a Seria_Port test! > dev/ttyS1指令,向串口發送數據,並同樣能在串口調試助手上顯示接收內容。

5、PC端發送數據,開發板讀取串口數據
在Z:\rk3399\external路徑下新建一個文件夾,命名為uart_receive,裡面包含兩個文件:receive.c和Android.mk,執行mm指令後得到可執行文件receive。將可執行文件receive傳送到開發板/system/xbin目錄下,在/system/xbin路徑下執行./receive指令後即可開始執行數據接收操作,接著在串口調試助手上發送數據(如圖4所示),所發送的內容便會在開發板終端上顯示(如圖5所示)。

                     圖4 PC端發送數據

                        圖5 開發板數據接收

代碼區:

1、receive.c

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

#define TRUE 1

void setTermios(struct termios * pNewtio, int uBaudRate)
{
memset(pNewtio, 0, sizeof(struct termios));

pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;
pNewtio->c_iflag = IGNPAR;
pNewtio->c_oflag = 0;
pNewtio->c_lflag = 0;


pNewtio->c_cc[VINTR] = 0;
pNewtio->c_cc[VQUIT] = 0;
pNewtio->c_cc[VERASE] = 0;
pNewtio->c_cc[VKILL] = 0;
pNewtio->c_cc[VEOF] = 4;
pNewtio->c_cc[VTIME] = 5;
pNewtio->c_cc[VMIN] = 0;
pNewtio->c_cc[VSWTC] = 0;
pNewtio->c_cc[VSTART] = 0;
pNewtio->c_cc[VSTOP] = 0;
pNewtio->c_cc[VSUSP] = 0;
pNewtio->c_cc[VEOL] = 0;
pNewtio->c_cc[VREPRINT] = 0;
pNewtio->c_cc[VDISCARD] = 0;
pNewtio->c_cc[VWERASE] = 0;
pNewtio->c_cc[VLNEXT] = 0;
pNewtio->c_cc[VEOL2] = 0;
}

#define BUFSIZE 512

int main(int argc, char **argv)
{
int fd;
int nread;
int Rlength = BUFSIZE;
int Length = 0;
char buff[BUFSIZE] = {0};
char cMsg[BUFSIZE] = {0};
char *pch = buff;
int i = 0;
struct termios oldtio, newtio;
struct timeval tv;
char *dev =(char *)"/dev/ttyS0";
fd_set rfds;
if ((fd = open(dev, O_RDWR | O_NOCTTY))<0)
{
printf("err: can't open serial port!\n");
return -1;
}
tcgetattr(fd, &oldtio);
setTermios(&newtio, B9600);
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);

tv.tv_sec=3;
tv.tv_usec=0;
while (TRUE)
{
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
if (select(1+fd, &rfds, NULL, NULL, &tv)>0)
{
printf("wait.......\n");
if (FD_ISSET(fd, &rfds))
{
nread=read(fd, pch, BUFSIZE-Length);
for(i=Length;i<nread+Length;i++)
{
printf("%c ", buff[i]);
}
Length += nread;
if(Length >= BUFSIZE)
{
printf("######Length<%d> is too long.\n", Length);
return -1;
}
pch += nread;
}
}
else
{
printf("Uart msg is :\n");
printf("%s\n", buff);
memset(buff, 0, BUFSIZE);
pch = buff;
Length = 0;

tv.tv_sec=3;
tv.tv_usec=0;

sleep(1);
}
}
tcsetattr(fd, TCSANOW, &oldtio);
close(fd);
}

 

2、ursend.c

#include <unistd.h>
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>

#define max_buffer_size 100

int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300, };

int name_arr[] = {115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,
115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, };

/*-----------------------------------------------------------------------------
函數名: set_speed
參數: int fd ,int speed
返回值: void
描述: 設置fd 表述符的串口波特率
*-----------------------------------------------------------------------------*/
void set_speed(int fd ,int speed)
{
struct termios opt;
int i;
int status;

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(fd,TCSANOW,&opt);
if(status != 0)
perror("tcsetattr fd:");
return ;
}
tcflush(fd,TCIOFLUSH);
}
}

/*-----------------------------------------------------------------------------
函數名: set_parity
參數: int fd
返回值: int
描述: 設置fd 表述符的奇偶校驗
*-----------------------------------------------------------------------------*/
int set_parity(int fd)
{
struct termios opt;

if(tcgetattr(fd,&opt) != 0)
{
perror("Get opt in parity error:");
return -1;
}

opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
| INLCR | IGNCR | ICRNL | IXON);
opt.c_oflag &= ~OPOST;
opt.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
opt.c_cflag &= ~(CSIZE | PARENB);
opt.c_cflag |= CS8;

tcflush(fd,TCIFLUSH); \

if(tcsetattr(fd,TCSANOW,&opt) != 0)
{
perror("set attr parity error:");
return -1;
}

return 0;
}

/*-----------------------------------------------------------------------------
函數名: serial_init
參數: char *dev_path,int speed,int is_block
返回值: 初始化成功返回打開的文件描述符
描述: 串口初始化,根據串口文件路徑名,串口的速度,和串口是否阻塞,block為1表示阻塞
*-----------------------------------------------------------------------------*/
int serial_init(char *dev_path,int speed,int is_block)
{
int fd;
int flag;

flag = 0;
flag |= O_RDWR;
if(is_block == 0)
flag |=O_NONBLOCK;

fd = open(dev_path,flag);
if(fd < 0)
{
perror("Open device file err:");
close(fd);
return -1;
}

set_speed(fd,speed);

if(set_parity(fd) != 0)
{
perror("set parity error:");
close(fd);
return -1;
}

return fd;
}

/*-----------------------------------------------------------------------------
函數名: serial_send
參數: int fd,char *str,unsigned int len
返回值: 發送成功返回發送長度,否則返回小於0的值
描述: 向fd描述符的串口發送數據,長度為len,內容為str
*-----------------------------------------------------------------------------*/
int serial_send(int fd,char *str,unsigned int len)
{
int ret;

if(len > strlen(str))
len = strlen(str);

printf("str: %s \n", str);
printf("len: %d \n", len);

ret = write(fd,str,len);

printf("ret: %d \n", ret);

if(ret < 0)
{
perror("serial send err:");
return -1;
}

return ret;

}

int main()
{
int fd;
int ret;
char str[]="Hello, this is a Seria_Port test!";
char buf[100];
printf("buf is: %d \n", sizeof(buf));
fd = serial_init("/dev/ttyS0",9600,1);

if(fd < 0)
{
perror("serial init err:");
return -1;
}

ret = serial_send(fd,str,50);

printf("send %d bytes!\n",ret);

close(fd);
return 0;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要簡單介紹一下如何在RHEL 7 Pacemaker中配置一個fence_vmware_soap類型的STONITH設備(僅供測試學習)。 STONITH是Shoot-The-Other-Node-In-The-Head的簡稱,並且它能夠保護數據使其不會因為節點異常或者同時訪問而遭到損壞。 節 ...
  • 系統環境: CentOS 6.7 官網下載安裝包:http://www.zabbix.com/download 本文用的是Zabbix 3.0 LTS 上傳至客戶端伺服器並解壓 進入解壓後的文件夾開始編譯安裝 複製安裝包中的文件到安裝路徑下 啟動agent服務 配置agent 客戶端開啟埠1005 ...
  • 如何學習linux,公司有幾台伺服器,是aix系統,工作過程中不可能在伺服器上進行測試。現在想在本機安裝虛擬機,一方面便於工作,另一方面便於學習。剛剛申請博客園,希望在此想各位大牛學習! ...
  • 1.停服zabbix2,停服資料庫/etc/init.d/zabbix_server stop/etc/init.d/mysqld stop2.物理備份資料庫cd /var/lib/mysql/tar -zcvf /tmp/data_zabbix2_20170306.tar.gz *3.安裝依賴包y ...
  • //"乙太網"是win10的名稱 win7是網路連接 根據系統更改即可 ...
  • 恢復內容開始 背景: 1,使用lnmp環境 2,代碼可以在windows上面寫,直接映射到linux的lnmp環境下麵 第一步: vmware 新建一個linux虛擬機 一路下一步到完成 第二步: 安裝鏡像(自己去下載一個linux的鏡像) 然後確認 ,然後重新客戶機 然後一路next(語言可以選中 ...
  • 系統環境 Ubuntu 16.04 在Zabbix伺服器端 安裝sendmail 測試發送郵件 成功後繼續安裝郵件伺服器。 Ubuntu系統中為heirloom-mailx 安裝好後開始配置.sh發送腳本 增加可執行許可權 測試腳本 接下來進行伺服器web端設置 1、配置 動作 啟用;這一步詳細設置里 ...
  • 1、備份資料庫 Mysqldump –u用戶名 –p密碼 備份資料庫 > 備份資料庫.sql 如:mysqldump –uroot –proot zzl > zzl.sql 2、停止mysql服務 Service mysql stop 3、使用yum刪除 Yum remove mysql* 詢問是否 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...