SDK程序設計
Vivado中配置Zynq時啟用開發板提供的UART接口。SDK中user_uart.h文件代碼如下:
#ifndef SRC_USER_UART_H_
#define SRC_USER_UART_H_
#include "xparameters.h"
#include "xuartps.h"
#include "xil_printf.h"
#include "sleep.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length);
int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId);
#endif /* SRC_USER_UART_H_ */
user_uart.c文件的代碼如下:
#include "user_uart.h"
// UART格式
XUartPsFormat uart_format =
{
9600,
//XUARTPS_DFT_BAUDRATE, //默認波特率 115200
XUARTPS_FORMAT_8_BITS,
XUARTPS_FORMAT_NO_PARITY,
XUARTPS_FORMAT_1_STOP_BIT,
};
//--------------------------------------------------------------
// UART初始化函數
//--------------------------------------------------------------
int Uart_Init(XUartPs* Uart_Ps, u16 DeviceId)
{
int Status;
XUartPs_Config *Config;
/* 初始化UART設備 */
Config = XUartPs_LookupConfig(DeviceId);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XUartPs_CfgInitialize(Uart_Ps, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* UART設備自檢 */
Status = XUartPs_SelfTest(Uart_Ps);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* 設置UART模式與參數 */
XUartPs_SetOperMode(Uart_Ps, XUARTPS_OPER_MODE_NORMAL); //正常模式
XUartPs_SetDataFormat(Uart_Ps, &uart_format); //設置UART格式
return XST_SUCCESS;
}
//--------------------------------------------------------------
// UART數據發送函數
//--------------------------------------------------------------
int Uart_Send(XUartPs* Uart_Ps, u8 *sendbuf, int length)
{
int SentCount = 0;
while (SentCount < length) {
SentCount += XUartPs_Send(Uart_Ps, &sendbuf[SentCount], 1);
}
return SentCount;
}
main.c文件的代碼如下:
#include "user_uart.h"
XUartPs Uart_Ps; /* The instance of the UART Driver */
int main(void)
{
int Status;
u8 sendbuf[] = "Hello World! ";
/* 串口初始化 */
Status = Uart_Init(&Uart_Ps, UART_DEVICE_ID);
if (Status == XST_FAILURE) {
xil_printf("Uartps Failed ");
return XST_FAILURE;
}
while (1)
{
sleep(1);
Uart_Send(&Uart_Ps, sendbuf, 14);
}
return Status;
}
SDK Terminal中添加串口,波特率設置為程序制定的9600,運行程序,將看到每隔1s打印一次“Hello World!”。
相關API函數
1.UART初始化
對UART設備初始化操作和前面GPIO設備、中斷設備、定時器設備、XADC設備的初始化過程一樣,不再贅述。接著使用XUartPs_SelfTest函數對UART設備自檢。
s32 XUartPs_SelfTest(XUartPs *InstancePtr)
1
這個函數執行一次本地回環,驗證可以正常發送和接受數據。返回XST_UART_TEST_FAIL表示測試失敗;XST_SUCCESS表示測試成功。我們可以用這個函數檢查硬件工作是否正常。
2.模式配置
初始化函數中還用XUartPs_SetOperMode函數設置了UART的工作模式。工作模式在xuartps.h文件中宏定義。
void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode)
1
四種工作模式的作用請參考第24篇。下表給出每種模式的宏定義:
宏定義 實際值 工作模式
XUARTPS_OPER_MODE_NORMAL 0x00U 正常模式
XUARTPS_OPER_MODE_AUTO_ECHO 0x01U 自動echo模式
XUARTPS_OPER_MODE_LOCAL_LOOP 0x02U 本地回環模式
XUARTPS_OPER_MODE_REMOTE_LOOP 0x03U 遠程回環模式
3.格式配置
接下來使用XUartPs_SetDataFormat函數設置UART的數據格式,包括波特率、數據位數、停止位數和奇偶校驗。調用此函數時應確保UART沒有收發數據。
s32 XUartPs_SetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr)
1
如果設置成功則返回XST_SUCCESS;如果該波特率在當前參考時鐘頻率下無法實現,則返回XST_UART_BAUD_ERROR表示無法設置波特率;函數的任意一個輸入參數無效時返回XST_INVALI_PARAM。
我們絕大多數情況下都會使用“8位數據、1位停止、無奇偶校驗”,因此如果想進一步提高程序效率,可以僅使用XUartPs_SetBaudRate函數來設置波特率。
s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate)
1
使用該函數也會檢查輸入的波特率值是否有效。檢查的依據是xuartps.c中下面這個宏定義,即最大允許的波特率錯誤率:
#define XUARTPS_MAX_BAUD_ERROR_RATE 3U /* max % error allowed */
1
其實質上是波特率生成器產生的實際波特率與設置的波特率之間的差值。如果不滿足這個條件,便會返回XST_UART_BAUD_ERROR,保持原有波特率不變。
4.數據格式
上面的函數中使用了XuartPsFormat類型的結構體來設置UART格式。該結構體原型如下:
typedef struct {
u32 BaudRate; /**< In bps, ie 1200 */
u32 DataBits; /**< Number of data bits */
u32 Parity; /**< Parity */
u8 StopBits; /**< Number of stop bits */
} XUartPsFormat;
下表總結了與數據格式相關的宏定義,使用時要將其填到結構體變量的對應位置。一般波特率可以寫成數字形式,其余三個成員都要用宏定義的形式。
宏定義 實際值 工作模式
數據位
XUARTPS_FORMAT_8_BITS 0U 8-bits數據位
XUARTPS_FORMAT_7_BITS 2U 7-bits數據位
XUARTPS_FORMAT_6_BITS 3U 6-bits數據位
奇偶校驗
XUARTPS_FORMAT_NO_PARITY 4U 無奇偶校驗
XUARTPS_FORMAT_MARK_PARITY 3U 校驗位始終為1
XUARTPS_FORMAT_SPACE_PARITY 2U 校驗位時鐘為0
XUARTPS_FORMAT_ODD_PARITY 1U 奇校驗
XUARTPS_FORMAT_EVEN_PARITY 0U 偶校驗
停止位
XUARTPS_FORMAT_2_STOP_BIT 2U 2-bits停止位
XUARTPS_FORMAT_1_5_STOP_BIT 1U 1.5-bits停止位
XUARTPS_FORMAT_1_STOP_BIT 0U 1-bit停止位
波特率
XUARTPS_MAX_RATE 921600U 最大波特率
XUARTPS_MIN_RATE 110U 最小波特率
XUARTPS_DFT_BAUDRATE 115200U 默認波特率
5.數據發送
程序中使用XUartPs_Send函數發送數據。這個函數是非阻塞的,輪詢模式和中斷驅動模式下都可以使用。它會盡可能地想TxFIFO填充數據,并返回發送的字節數;如果無法填充,會返回0表示發送了0字節,便于用戶處理。
中斷模式下,該函數會發送指定的緩沖區(Buffer)中的內容,中斷處理程序負責將所有數據全部發送完。此時會調用綁定的回調函數,標識發送完成。關于中斷的用法在后面文章中專門介紹。
u32 XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
1
第二個參數是指向要發送的數據緩沖區的指針;第三個參數是發送的字節數;返回值標識實際發送的字節數。本例程序中就是利用返回值確保所有數據都依次發送(雖然本例的數量不大,但要學習這個用法)。
這個函數還有個特殊用法,如果將第三個參數設為0,則會停止正在進行的發送操作,并將已經在TxFIFO中的所有數據都發送出去??梢杂眠@個用法實現某些特殊功能。