The basic flow
1UART initialization
By XUartPs_LookupConfig function, find UART base address ------------>
By XUartPs_CfgInitialize function, initialize UART configuration ------------>
2. Mode Configuration
void XUartPs_SetOperMode(XUartPs *InstancePtr, u8 OperationMode)
Spontaneous self-closing with a local loopback
3. Format reload configuration
Use XUartPs_SetDataFormat function sets the UART data format, including baud rate, data bits, stop bits, and parity. Calling this function should be to ensure that there is no UART transmit and receive data.
cfg in default "8 bit data, 1 stop bit, no parity",
may be used alone XUartPs_SetBaudRate function to set the baud rate.
s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate)
XUartPs_SetDataFormat
s32 XUartPs_SetDataFormat(XUartPs *InstancePtr, XUartPsFormat * FormatPtr)
typedef struct {
u32 BaudRate; /**< In bps, ie 1200 */
u32 DataBits; /**< Number of data bits */
u32 Parity; /**< Parity */
u8 StopBits; /**< Number of stop bits */
} XUartPsFormat;
4. Data transmission
u32 XUartPs_Send(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
The second argument is a pointer pointing to the data buffer to be transmitted; third parameter is the number of bytes sent; return value identifies the number of bytes actually transmitted.
5. Data received
u32 XUartPs_Recv(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes)
The second parameter pointer to the received data to be stored in the buffer; NumBytes third byte count "to" received; return the number of bytes actually received.
The third entry is the use and the return value, to achieve a function of receiving a certain number of data,
Polling Mode 2
initialization
void Uart_init()
{
XUartPs_Config *Config;
Config = XUartPs_LookupConfig(UART_DEVICE_ID);
XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
}
LOCAL_LOOP send and receive
int Uart_send_receive_LOCAL(XUartPs* Uart_Ps, u8 *SendBuffer, u8 *RecvBuffer, int length)
{
//自收自发
XUartPs_SetOperMode(Uart_Ps,XUARTPS_OPER_MODE_LOCAL_LOOP);
u16 SentCount=0;
u16 RecvCount=0;
SentCount=XUartPs_Send(Uart_Ps,SendBuffer,length);
if (SentCount != length)
return XST_FAILURE;
//发送等待
while(XUartPs_IsSending(Uart_Ps));
//接收
while(RecvCount < length) {
RecvCount += XUartPs_Recv(Uart_Ps, &RecvBuffer[RecvCount],
(length - RecvCount));
}
XUartPs_SetOperMode(Uart_Ps,XUARTPS_OPER_MODE_NORMAL);
for (u16 Index = 0; Index < length; Index++) {
if (SendBuffer[Index] != RecvBuffer[Index]) {
xil_printf("UART Polled Mode failed!\r\n");
return XST_FAILURE;
}
}
xil_printf("UART Polled Mode succeeded!\r\n");
return XST_SUCCESS;
}
main.c
#include "sleep.h"
#include "xparameters.h"
#include "xuartps.h"
#include "xil_printf.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define TEST_BUFFER_SIZE 32
XUartPs Uart_PS; /* Instance of the UART Device */
/*
* The following buffers are used in this example to send and receive data
* with the UART.
*/
static u8 SendBuffer[TEST_BUFFER_SIZE]; /* Buffer for Transmitting Data */
static u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
int main(void)
{
Uart_init();
while(1)
{
sleep(3);
for (u16 Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = '0' + Index;
RecvBuffer[Index] = 0;
}
Uart_send_receive_LOCAL(&Uart_PS,SendBuffer,RecvBuffer,TEST_BUFFER_SIZE);
}
return XST_SUCCESS;
}
Normal to send and receive
int Uart_send_receive_Normal(XUartPs* Uart_Ps, u8 *RecvBuffer, int length)
{
//正常模式
XUartPs_SetOperMode(Uart_Ps,XUARTPS_OPER_MODE_NORMAL);
u16 RecvCount=0;
u16 SentCount=0;
//发送等待
while(XUartPs_IsSending(Uart_Ps));
//接收
while(RecvCount < length) {
RecvCount += XUartPs_Recv(Uart_Ps, &RecvBuffer[RecvCount],
(length - RecvCount));
}
SentCount = XUartPs_Send(Uart_Ps, RecvBuffer, length);
if (SentCount != length) {
xil_printf("UART Polled Mode failed!\r\n");
return XST_FAILURE;
}
xil_printf("UART Polled Mode succeeded!\r\n");
return XST_SUCCESS;
}
main.c
int main(void)
{
Uart_init();
while(1)
{
sleep(0.1);
Uart_send_receive_Normal(&Uart_PS,RecvBuffer,TEST_BUFFER_SIZE);
}
return XST_SUCCESS;
}
buffer length 10
Only after we send enough data 10, pending the UART will end.
If the data we send a one-time more than 10, the excess data will remain in RxFIFO until the next poll was only read.
This article describes the UART polling mode. Unless it is particularly simple application, generally do not use the polling mode. If you want to use the polling mode, the program must have a good architecture or implementation mechanism, to avoid the program indefinitely tie.
3 interrupt mode
uart0 59 #
uart0 82 #
By Xil_ExceptionInit function, to avoid compatibility problems with the previous version have ------------>
By XScuGic_LookupConfig function, find common interrupt controller base address ------------>
By XScuGic_CfgInitialize function initializes the general interrupt controller ------------>
By Xil_ExceptionRegisterHandler function, enable exception interrupt handler ------------>
By XScuGic_Connect function, binding UART interrupt handler ------------>
By XScuGic_Enable function, in general interrupt controller enabled in UART interrupt ------------>
By XUartPs_SetInterruptMask function, set the UART interrupt trigger ------------>
By Xil_ExceptionEnableMask function, enabling the interrupt.
1. Trigger
Use trigger XUartPs_SetInterruptMask function sets the serial port interrupt. The second parameter is set RxFIFO trigger an interrupt.
XUartPs_SetInterruptMask(Uart_Ps, XUARTPS_IXR_RXOVR);
2.RxFIFO trigger level setting
Use XUartPs_SetFifoThreshold function to set the trigger level of the UART initialization in RxFIFO. RxFIFO number of bytes exceeds this value, a reception data interruption is generated. When not set to default 8. The
void XUartPs_SetFifoThreshold (XUartPs * InstancePtr, U8 TriggerLevel)
Second parameter value should be 1 to 64, because the maximum RxFIFO only store 64 bytes.
3. The interrupt handler
include define
#include "xparameters.h"
#include "xplatform_info.h"
#include "xuartps.h"
#include "xil_exception.h"
#include "xil_printf.h"
#include "xscugic.h"
#include "sleep.h"
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID XPAR_XUARTPS_1_INTR
#define TEST_BUFFER_SIZE 16
XUartPs Uart_PS ; /* Instance of the UART Device */
XScuGic InterruptController; /* Instance of the Interrupt Controller */
static u8 RecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */
volatile int TotalReceivedCount;
volatile int TotalSentCount;
u8 *RecvBufferPtr;
uart init
void Uart_init()
{
XUartPs_Config *Config;
Config = XUartPs_LookupConfig(UART_DEVICE_ID);
XUartPs_CfgInitialize(&Uart_PS, Config, Config->BaseAddress);
}
interrupt init connect and enable
void inter_init_connect()
{
XScuGic_Config *IntcConfig; /* Config for interrupt controller */
/* Initialize the interrupt controller driver */
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
XScuGic_CfgInitialize(&InterruptController, IntcConfig,
IntcConfig->CpuBaseAddress);
XScuGic_Disable(&InterruptController,59);
XScuGic_SetPriorityTriggerType(&InterruptController,59,16,1);//
//connect and enable
XScuGic_Connect(&InterruptController, 59U,
(Xil_ExceptionHandler) Handler,
&Uart_PS);
XScuGic_Enable(&InterruptController, 59U);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
(void *)&InterruptController);
Xil_ExceptionEnable();
}
uart handler
void Handler(void *CallBackRef)
{
u32 ReceivedCount = 0 ;
u32 IsrStatus;
XUartPs *UartInstancePtr = (XUartPs *) CallBackRef ;
IsrStatus = XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,
XUARTPS_IMR_OFFSET);
IsrStatus &= XUartPs_ReadReg(UartInstancePtr->Config.BaseAddress,
XUARTPS_ISR_OFFSET);//中断类型
if (IsrStatus & (u32)XUARTPS_IXR_RXOVR) /* 检查RxFIFO是否触发 */
{
ReceivedCount = XUartPs_Recv(UartInstancePtr, RecvBuffer, (TEST_BUFFER_SIZE-TotalReceivedCount)) ;
TotalReceivedCount += ReceivedCount ;
RecvBufferPtr += ReceivedCount ;
/* 清除中断标志 */
XUartPs_WriteReg(UartInstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, XUARTPS_IXR_RXOVR) ;
}
xil_printf("UART inter\r\n");
if (TotalReceivedCount >= TEST_BUFFER_SIZE) {
xil_printf("%s", RecvBuffer);
xil_printf("\r\nI have received %d bytes.\r\n", TotalReceivedCount);
RecvBufferPtr = RecvBuffer;
TotalReceivedCount = 0;
}
}
main
int main(void)
{
u32 IntrMask;
Uart_init();
XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);
inter_init_connect();
XUartPs_SetHandler(&Uart_PS, (XUartPs_Handler)Handler, &Uart_PS);
IntrMask =XUARTPS_IXR_RXOVR;
XUartPs_SetFifoThreshold(&Uart_PS,8); //设置RxFIFO的中断触发等级
XUartPs_SetInterruptMask(&Uart_PS, IntrMask);
XScuGic_Enable(&InterruptController, 59);
while(1)
{
sleep(1);
xil_printf("UART 1s in main\r\n");
}
return 0;
}