99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

ZYNQ-UART串口中斷讀寫測試

學習內容

本文主要介紹關于ZYNQ芯片的串口中斷功能,并編寫相關讀寫測試代碼,完成串口中斷的讀寫測試。

開發環境

vivado 18.3&SDK,PYNQ-Z2開發板。

UART控制器

簡介

UART控制器是一個全雙工異步接收和發送,支持可編程波特率和I/O信號格式。 該控制器可實現奇偶校驗自動生成和多主檢測模式。UART操作由配置和模式寄存器控制。

FIFO、調制解調器信號和其他控制器功能的狀態是使用狀態、中斷狀態和調制解調器狀態寄存器讀取的。UART控制器有獨立的RX和TX數據路徑。每個路徑包括一個64字節的FIFO。 控制器TX和RX FIFO中的數據進行串行化和反串行化,并包括一個模式開關,以支持RXD和TXD信號的各種環回配置。(RXD和TXD使用模式:正常模式、各種環回診斷測試模式)

FIFO中斷狀態位支持輪詢或中斷驅動的處理程序。 軟件使用RX和TX數據端口寄存器讀取和寫入數據字節。當在類似于調制解調器的應用程序中使用UART時,調制解調器控制模塊檢測并生成調制解調器握手信號,并且還根據握手協議控制接收和發送器路徑。(調制解調器控制信號:CTS, RTS, DSR, DTR, RI和DCD只有在EMIO接口可用

系統框圖

UART控制器的系統框圖如下圖所示:

在圖中,SLCR寄存器(系統級控制寄存器(SLCR)由用于控制PS行為的各種寄存器組成。這些寄存器可以通過中央互連使用加載和存儲指令訪問。)包括控制位用于UART時鐘,復位和MIO-EMIO信號映射。軟件可以使用APB 32位的從接口訪問UART控制器寄存器。每個控制器的IRQ(中斷號為59,82)連接到PS中斷控制器,并連接到PL。UART控制器由參考時鐘( UART REF_CLK)驅動,同時控制器也需要連接APB 總線時鐘( CPU_1x clock), UART REF_CLK 和 CPU_1x clock 都是來自于 PS 時鐘子系統。

內部框圖

UART控制器內部框圖如下圖所示。

由上圖可知,UART控制器使用PS AXI interconnect 進行數據交互,通過APB Slave接口來接收PS端口的配置信息和一些數據信息。假設要發送數據,則系統先將發生的字符串緩存到TxFIFO下,然后經Transmitter模塊實現并轉串,如果工作在正常模式下,則數據之間接到MIO/EMIO引腳上,正常向接收設備發送;假設要接收其他設備傳來的串口信息,則首先通過串口接收引腳接收串行數據,然后經過receiver模塊實現串轉并,轉換過后存入到RxFIFO下,經過APB從接口傳輸到PS端,即可對接收數據進行處理。

通過控制狀態寄存器可以對UART控制器進行控制,而這些引腳只能連接到EMIO。UART控制器內部包括一個中斷模塊,所以可以和其他模塊一樣正常接收到來自系統的中斷信號。對于UART的參考時鐘在控制器內部首先進行了一個八分頻,接著再產生波特率時鐘。

Transmit FIFO

Transmit FIFO (Tx FIFO)存儲由APB從接口寫入的數據,發送模塊收到FIFO中的數據后刪除FIFO的數據然后進行串并轉換,并裝入其移位寄存器。TxFIFO的最大數據寬度為8位。數據通過寫入TxFIFO寄存器加載到TxFIFO。

當數據加載到TxFIFO時,TxFIFO空標志將被清除并保持在這個Low狀態,直到TxFIFO中的最后一個字符被刪除并加載到發送器移位寄存器中。TxFIFO滿中斷狀態(TFULL)表明TxFIFO已經完全寫滿了,并且阻止數據被寫入到TxFIFO中。如果對TxFIFO執行另一個APB寫入操作,則觸發溢出,寫入數據不會加載到TxFIFO中。

發送 FIFO接近滿標志(TNFULL)表明在FIFO中沒有足夠的空間來進行一次程序大小的寫入,這是由模式寄存器的WSIZE位控制的。TxFIFO接近滿標志(TNFULL)表示TxFIFO中只有字節空閑。

可以在TxFIFO填充級別上設置一個閾值觸發器(TTRIG)。發射器觸發寄存器可以用來設置這個值,這樣當TxFIFO填充深度達到設定的閾值時觸發可以設置。

Receiver FIFO

Receiver FIFO和Transmit FIFO類似。RxFIFO存儲由接收器串行移位寄存器接收的數據。RxFIFO的最大數據寬度是8位。當數據加載到RxFIFO時,RxFIFO空標志被清除,并且這種狀態保持為低,直到RxFIFO中的所有數據通過APB接口傳輸完畢。空標志重新置位為高,如果接著讀FIFO的話,則會從空的RxFIFO讀取返回0。

RxFIFO滿狀態(Chnl_int_sts_reg0 [RFUL]和Channel_sts_reg0 [RFUL]位)表明RxFIFO滿了,阻止數據被加載到RxFIFO。同時也可以在RxFIFO上設置一個閾值觸發器(RTRIG)。接收器觸發級別寄存器(Rcvr_FIFO_trigger_level0)可以用來設置這個值,取值范圍是1 ~ 63。

I / O模式切換

這里的模式切換即為內部框圖中的 Mode Switch 模塊,如下圖所示。

該模式由mode_reg0 [CHMODE]寄存器設置控制,總共分為四種模式,分別 為:正常模式( Normal Mode)、自動回音模式( Automatic Echo Mode)、本地環回模式( Local Loopback Mode)和遠程環回模式( Remote Loopback Mode)。

正常模式( Normal Mode) :用于標準UART操作,就是發送接收功能。

自動回音模式( Automatic Echo Mode) :Automatic Echo Mode模式在RxD上接收數據,模式開關將數據連接到接收端和UARTx_TxD。而PS的TXD端口的數據無法正常發出。

本地環回模式( Local Loopback Mode) :本地環回模式不連接到RxD或TxD引腳,而是直接把PS發送的數據傳輸到PS的接收端。

遠程環回模式( Remote Loopback Mode) :遠程環回模式將RxD信號連接到TxD信號。在這種模式下,控制器不能在TxD上發送任何內容,也不能在RxD上接收任何內容。

UART啟動順序

UART 的啟動順序如下:

  1. 復位UART控制器,在PS進行系統復位時進行控制器的復位。
  2. 配置 IO 引腳信號。
  3. 配置 UART 參考時鐘(可以保護默認)。
  4. 配置控制器功能( UART 控制器初始化)。
  5. 配置中斷,通過中斷來管理 RxFIFO 和 TxFIFO。
  6. 配置串口模式控制(可選)。
  7. 管理發送和接收的數據,采用輪詢或中斷驅動處理兩種方式。

配置控制器功能步驟

在UART控制器中,控制器可以配置字符幀、波特率、FIFO觸發級別、Rx超時機制,并使能控制器。所有步驟都必須在復位之后。 配置控制器的功能步驟如下:

  1. 配置 UART 數據幀格式。 數據位長度、停止位、校驗方式、 IO 模式等。
  2. 設置波特率。
  3. 設置 RxFIFO 觸發器等級,可以選擇啟用或禁用該功能。
  4. 使能 UART 控制器。
  5. 配置接收器的超時機制,可以選擇啟用或禁用該功能。

發送數據步驟

編寫軟件程序時,可以通過使用輪訓和中斷的方式控制RxFIFO和TxFIFO中的數據流。

使用輪詢方式發送數據順序

  1. 檢查TxFIFO是否為空。直到uart.Channel sts rego[TEMPTY] =1,執行后續步驟。
  2. 用數據填充TxFIFO。向uart.TX_RX_FIFO0寄存器寫入64字節的數據。
  3. 向TxFIFO寫入數據。有兩種方法:方法一: 可以等待 TxFIFO 為空之后再寫入 64 個字節,即執行第 2 步;方法一: 可以檢測 TxFIFO 是否寫滿,即不停的讀取 TFUL 標志和寫單個字節的數據。

使用中斷方法發送數據的順序

  1. 禁用 TxFIFO 空狀態中斷。
  2. 寫入數據到TxFIFO中。
  3. 檢測TxFIFO是否還有足夠的空間容納數據。
  4. 重復2和3操作。
  5. 使能中斷。
  6. 等待TxFIFO為空,然后從步驟 1 重新開始。

接收數據步驟

使用輪詢方式發送數據順序

  1. 等待RxFIFO被填滿到觸發器級別。
  2. 從RxFIFO讀取數據。
  3. 重復步驟2,直到FIFO為空。
  4. 設置Rx超時中斷狀態位時清除。

使用中斷方法發送數據順序

  1. 使能中斷。
  2. 等待RxFIFO被填滿到觸發級別或Rx超時。
  3. 從RxFIFO讀取數據。
  4. 重復步驟2和3,直到FIFO為空。
  5. 如果設置了中斷狀態位,則清除中斷狀態位。

系統框圖

這里僅僅使用了UART部分,所以可以利用前文的helloworld工程,不需要進行特殊的配置。通過串口的中斷功能把發送的數據再接收到PS端進行一個回環顯示。

硬件平臺搭建

新建工程,創建 block design。添加ZYNQ7 ip,根據本次工程需要對IP進行配置。勾選本次工程使用的uart資源

將ZYNQ無用資源進行取消勾選:

硬件系統構建完成如下:

然后我們進行generate output product 然后生成HDL封裝。這里只用到了UART,是MIO引腳,所以不需要進行管腳分配。點擊導出硬件資源(可以不包含bit流文件,因為只用到了PS資源),接著launch SDK。

SDK軟件部分

打開SDK后,新建application project。 在system.mss中可以打開相關參考文檔輔助設計。

這里使用串口中斷可以參考賽靈思提供的例程代碼進行修改設計:

這里導入uart_intr_example例程模板在main.c中輸入以下代碼:

#include "xparameters.h"
#include "stdio.h"
#include "xuartps.h"
#include "xuartps_hw.h"
#include "xscugic.h"
#define UART_0_DEVICE_ID XPAR_PS7_UART_0_DEVICE_ID
#define INTR_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID		XPAR_XUARTPS_0_INTR
XUartPs Uart_Inst;
XScuGic ScuGic_Inst;
int uart_init();
void intr_init(XScuGic *intr, XUartPs *uart);
void UartIntr_Handler(void *call_back_ref);
int main(){

	//uart初試化函數
	uart_init();
	xil_printf("intr\n");
	//中斷初始化
	intr_init(&ScuGic_Inst,&Uart_Inst);
	while(1);
	return0;
}

//uart初始化
int uart_init(){
	XUartPs_Config *UartPs_Cfg;
	int Status;
	//查找配置信息
	UartPs_Cfg= XUartPs_LookupConfig(UART_0_DEVICE_ID);
	//對uart控制器進行初始化
	XUartPs_CfgInitialize(&Uart_Inst, UartPs_Cfg, UartPs_Cfg->BaseAddress);
	//檢測硬件搭建是否正確
	Status = XUartPs_SelfTest(&Uart_Inst);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	//設置波特率
	XUartPs_SetBaudRate(&Uart_Inst,115200);
	//設置RXFIFO觸發閾值
	XUartPs_SetFifoThreshold(&Uart_Inst,1);
	//設置操作模式
	XUartPs_SetOperMode(&Uart_Inst, XUARTPS_OPER_MODE_NORMAL);

	return XST_SUCCESS;
}

//中斷初始化
void intr_init(XScuGic *intr, XUartPs *uart){
	XScuGic_Config *IntcConfig;
	//中斷控制器初始化
	IntcConfig = XScuGic_LookupConfig(INTR_DEVICE_ID);
	XScuGic_CfgInitialize(intr,IntcConfig,IntcConfig->CpuBaseAddress);
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
					(Xil_ExceptionHandler) XScuGic_InterruptHandler,
					(void *)intr);
	Xil_ExceptionEnable();
	//為中斷設置中斷處理函數
	XScuGic_Connect(intr, UART_INT_IRQ_ID,
					  (Xil_ExceptionHandler) UartIntr_Handler,
					  (void *) uart);
	//設置觸發類型
	XUartPs_SetInterruptMask(uart, XUARTPS_IXR_RXOVR);
	//使能中斷
	XScuGic_Enable(intr, UART_INT_IRQ_ID);

}
//中斷處理函數
void UartIntr_Handler(void *call_back_ref){
	XUartPs *uartinst =(XUartPs *)call_back_ref;
	u32 read_data = 0;
	u32 intr_status;
	//讀取中斷ID寄存器
	intr_status = XUartPs_ReadReg(uartinst->Config.BaseAddress,
			XUARTPS_IMR_OFFSET);//讀取掩碼
	intr_status &= XUartPs_ReadReg(uartinst->Config.BaseAddress,
			XUARTPS_ISR_OFFSET);//讀取狀態
	if(intr_status & (u32)XUARTPS_IXR_RXOVR){
		read_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);//接收發送的字節
		XUartPs_WriteReg(uartinst->Config.BaseAddress,XUARTPS_ISR_OFFSET,
				XUARTPS_IXR_RXOVR);//清除中斷狀態
	}
	//設置發送
	XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,read_data);
}

部分代碼講解

在整體的代碼設計中,代碼思路如下:

  1. 初始化UART控制器
  2. 初始化UART中斷
  3. 編寫中斷服務函數

對于初始化UART部分,在#include "xuartps.h" 頭文件中可以找到很多配置的函數,調用即可對uart的波特率,中斷觸發閾值等參數進行設置。 對于中斷的配置可以類比GPIO的中斷配置函數,先在初始化SGIC,然后進行異常初始化,完成注冊異常并使能,接著需要連接SGIC和UART,最后設置中斷類型并使能完成中斷整體操作配置。 在中斷服務函數中,實現的功能為回環讀寫,所以要在中斷函數中進行檢測中斷類型,當進入相應的中斷時進行數據的讀取,讀取到上位機的發送數據,然后清除中斷標志,最后把讀到的數據進行發送。

Reference

  1. 正點原子視頻教程
  2. UG585
聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關注 15
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧
主站蜘蛛池模板: 18禁美女裸体爆乳无遮挡 | 日本中文字幕一级片 | 一个人免费观看www高清中文 | 在线看成人 | 久久精品国产亚洲AV嫖农村妇女 | 久久免费的精品国产v∧ | 亚洲男人的天堂在线aⅴ视频 | 在线观看国产中文字幕 | 天堂久久一区二区三区 | 亚洲首页一区任你躁XXXXX | 婷婷成人丁香五月综合激情 | 四级黄色毛片 | 欧美视频网 | 插插无码视频大全不卡网站 | 日日碰狠狠躁久久躁蜜桃 | xxxx精品| 亚洲第一成网站 | 无码日韩精品一区二区免费 | 4399午夜理伦免费播放大全 | tube麻豆| 亚洲欧美日韩精品永久在线 | 天天操天天碰视频 | 在线观看91精品国产入口 | 无码熟妇人妻AV在线网站 | 国产精品干| 日本少妇激三级做爰在线 | 高清成人综合网 | 在线观看免费黄色小视频 | 成年人在线免费观看视频网站 | 国产成人AV无码精品天堂 | 欧美高潮喷水HD | 亚洲国产婷婷香蕉久久久久久99 | 色大18成网站www在线观看 | 亚洲精品AⅤ在线国自产拍 美国人泡妞xxxxwww免费看 | 国产精品青青青高清在线 | 欧美金8天国 | 亚洲AV无码A片在线观看 | 日产特黄极日产 | 成人羞羞网站 | 一级做性色a爱片久久毛片欧 | 另类精品 |