久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

ZYNQ-UART串口中斷讀寫測試

學(xué)習(xí)內(nèi)容

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

開發(fā)環(huán)境

vivado 18.3&SDK,PYNQ-Z2開發(fā)板。

UART控制器

簡介

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

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

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

系統(tǒng)框圖

UART控制器的系統(tǒng)框圖如下圖所示:

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

內(nèi)部框圖

UART控制器內(nèi)部框圖如下圖所示。

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

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

Transmit FIFO

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

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

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

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

Receiver FIFO

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

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

I / O模式切換

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

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

正常模式( Normal Mode) :用于標(biāo)準(zhǔn)UART操作,就是發(fā)送接收功能。

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

本地環(huán)回模式( Local Loopback Mode) :本地環(huán)回模式不連接到RxD或TxD引腳,而是直接把PS發(fā)送的數(shù)據(jù)傳輸?shù)絇S的接收端。

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

UART啟動順序

UART 的啟動順序如下:

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

配置控制器功能步驟

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

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

發(fā)送數(shù)據(jù)步驟

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

使用輪詢方式發(fā)送數(shù)據(jù)順序

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

使用中斷方法發(fā)送數(shù)據(jù)的順序

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

接收數(shù)據(jù)步驟

使用輪詢方式發(fā)送數(shù)據(jù)順序

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

使用中斷方法發(fā)送數(shù)據(jù)順序

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

系統(tǒng)框圖

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

硬件平臺搭建

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

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

硬件系統(tǒng)構(gòu)建完成如下:

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

SDK軟件部分

打開SDK后,新建application project。 在system.mss中可以打開相關(guān)參考文檔輔助設(shè)計。

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

這里導(dǎo)入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初試化函數(shù)
	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;
	}
	//設(shè)置波特率
	XUartPs_SetBaudRate(&Uart_Inst,115200);
	//設(shè)置RXFIFO觸發(fā)閾值
	XUartPs_SetFifoThreshold(&Uart_Inst,1);
	//設(shè)置操作模式
	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();
	//為中斷設(shè)置中斷處理函數(shù)
	XScuGic_Connect(intr, UART_INT_IRQ_ID,
					  (Xil_ExceptionHandler) UartIntr_Handler,
					  (void *) uart);
	//設(shè)置觸發(fā)類型
	XUartPs_SetInterruptMask(uart, XUARTPS_IXR_RXOVR);
	//使能中斷
	XScuGic_Enable(intr, UART_INT_IRQ_ID);

}
//中斷處理函數(shù)
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);//讀取狀態(tài)
	if(intr_status & (u32)XUARTPS_IXR_RXOVR){
		read_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);//接收發(fā)送的字節(jié)
		XUartPs_WriteReg(uartinst->Config.BaseAddress,XUARTPS_ISR_OFFSET,
				XUARTPS_IXR_RXOVR);//清除中斷狀態(tài)
	}
	//設(shè)置發(fā)送
	XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,read_data);
}

部分代碼講解

在整體的代碼設(shè)計中,代碼思路如下:

  1. 初始化UART控制器
  2. 初始化UART中斷
  3. 編寫中斷服務(wù)函數(shù)

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

Reference

  1. 正點原子視頻教程
  2. UG585
聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關(guān)注 15
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧