集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 201|回复: 0

ZYNQ的UART

[复制链接]
dameihuaxia 发表于 2022-10-10 16:34:01 | 显示全部楼层 |阅读模式
ZYNQ的UART

1 UART的特点
ZYNQ的串口模块是一个全双工的异步接收和发送器,支持宽范围广的软件可编程模块,支持编程配置波特率和数据格式,同时提供自动的奇偶校验和错误检测方案,此外,还为APU提供了接收和发送FIFO。

ZYNQ有两个UART器件,具有以下特性:

可编程波特率发送器;
64个字节接收和发送FIFO;
数据位6,7或者8个比特位;
奇,偶,空格,标记或者没有校验;
1,1.5或者2个停止位;
支持校验,帧和超限错误检测;
支持自动回应,本地环路和远程环路通道模式;
支持产生中断;
在EMIO上,可以使用调制解调器控制信号CTS,RTS,DSR,DTR,RI和DCD;
其结构框如图1所示:



图1 UART的结构体系

APB接口:

通过APB接口,PS可以对UART控制器内部寄存器进行读写操作;

Tx FIFO

Tx FIFO用于保存来自APB接口的写数据,直到发送器模块将其取出并送到发送移位寄存器中,Tx FIFO通过满和空标志来控制流量,此外,还可以设置Tx FIFO的触发等级;

Rx FIFO:

Rx FIFO用于保存来自接收移位寄存器的数据,Rx FIFO的满空标志用于接收数据流量控制,此外,还可以设置Rx FIFO的触发等级;

发送器:

发送器取出发送FIFO中的数据,并将其加载到发送移位寄存器中,将并行数据串行化处理;

接收器:

UART连续采样ua_rxd信号,当检测到低的电平变化时,表示接收数据的开始;

控制和状态模块:

控制寄存器用于使能,禁止和发布软件复位给接收器和发送器模块,还可以配置接收超时和发送断开等特性;模式寄存器通过波特率生成器选择时钟,它也负责选择发送和所接收数据的位的长度,奇偶校验位和停止位,还可以选择UART的工作模式,包含自动回应,本地环路以及远程环路等;

中断控制:

通过通道中断状态寄存器和通道状态寄存器,以及中断控制模块检测来自其他UART模块的事件;通过使用中断使能寄存器和中断禁止寄存器,使能或禁用中断,中断使能或者禁用的状态反映在中断屏蔽寄存器当中;

波特率发生器:

图2给出了波特率发生器的原理,图中CD是波特率发生器的一个位域,用于生成采样率时钟band_sample。



图2 波特率发送器

波特率最后生成主要包括以下3个步骤:

UART的时钟选择,可以直接是UART Ref clock,也可以通过旁路进行8分频,该设置在uart.mode_reg0[0]中进行;
对UART时钟进行分频,产生band_sample的频率计算公式如下:
baud_sample = sel_clk/CD

对baud_sample进行再次分频,产生Rx和Tx波特率,该步骤是通过设置BDIV值完成,也就是对uart.Baud_rate_Divider_reg0[7:0]进行设置,波特率计算公式如下:
baud_rate = sel_clk/(CD*(BDIV + 1))

             UART Ref clock,CD和BDIV的值决定了UART的波特率,如果UART_Ref_Clk=50MHz,Uart_ref_clk/8=6.25MHz。图3表示典型的波特率对应的CD和eBDIV值;



图3 CD和eBDIV对应波特率

2 UART使用实例
实例内容:配置好ZYNQ的UART中断,实现中断服务函数,在接收中断中将接收到的数据通过UART发送出来;

配置UART的步骤如下:

通过UART的外设ID找到对应的外设信息;
填充UART外设寄存器基地址和一些相关信息;
配置UART的的GIC中断;
配置UART的中断触发方式(接收或者发送中断);
设置UART的FIFO触发等级;
使能UART外设;
配置UART的GIC中断步骤如下:

连接到硬件,把对应中断映射到GIC中断请求上;
找到GIC中断,填充GIC中断寄存器基地址和一些相关信息;
找到UART中断源,填充定时器中断寄存器基地址和一些相关信息;
将UART中断映射到定时器中断的中断服务函数上;
使能GIC中断;
使能中断向量表和中断向量表的映射;
程序源码:

//UART的GIC初始化

void Init_Gic_Uart(void)

{

    XScuGic_Config *IntcConfig;

    //connect hardware

    Xil_ExceptionInit();

    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,

                        (Xil_ExceptionHandler)XScuGic_InterruptHandler,

                        (void *)&Intc);

    //find XScuGic device

    IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

    //config XScuGic data

    XScuGic_CfgInitialize(&Intc,IntcConfig,IntcConfig->CpuBaseAddress);

    //GIC Connect to handler function

  XScuGic_Connect(&Intc,UART_IRPT_INTR,(Xil_InterruptHandler)UartIntrHandler, (void *)&Uart);

    //enable XScuGic

    XScuGic_Enable(&Intc,UART_IRPT_INTR);

    //enable exception

    Xil_ExceptionEnable();

    Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);

}



//UART初始化

void Init_Uart(void)

{

    XUartPs_Config * UartConfigPtr;

    //fined uart device

    UartConfigPtr = XUartPs_LookupConfig(UART_DEVICE_ID);

    //config XUartPs data

    XUartPs_CfgInitialize(&Uart,UartConfigPtr,UartConfigPtr->BaseAddress);

    //set uart mask

    XUartPs_SetInterruptMask(&Uart,XUARTPS_IXR_RXOVR);

    XUartPs_SetFifoThreshold(&Uart,10);

    //enable uart

    XUartPs_EnableUart(&Uart);

}



//UART中断服务函数

void UartIntrHandler(void *CallBackRef)

{

    XUartPs *InstancePrt = (XUartPs *)CallBackRef;

    u32 IsrStatus;

    u32 ReceivedCount = 0;

    u32 CsrRegister;

    IsrStatus = XUartPs_ReadReg(InstancePrt->Config.BaseAddress,XUARTPS_IMR_OFFSET);

    IsrStatus &= XUartPs_ReadReg(InstancePrt->Config.BaseAddress,XUARTPS_ISR_OFFSET);



    if((IsrStatus & ((u32)XUARTPS_IXR_RXOVR | (u32)XUARTPS_IXR_RXEMPTY | (u32)XUARTPS_IXR_RXFULL)) != (u32)0)

    {

        CsrRegister = XUartPs_ReadReg(InstancePrt->Config.BaseAddress,XUARTPS_SR_OFFSET);

        while((CsrRegister & XUARTPS_SR_RXEMPTY) == (u32)0)

        {

XUartPs_WriteReg(InstancePrt->Config.BaseAddress,XUARTPS_FIFO_OFFSET,XUartPs_ReadReg(InstancePrt->Config.BaseAddress,XUARTPS_FIFO_OFFSET));

            ReceivedCount++;

            CsrRegister = XUartPs_ReadReg(InstancePrt->Config.BaseAddress,XUARTPS_SR_OFFSET);

        }

    }

//  printf("thistimeReceivedCount=%d\r\n",ReceivedCount);

XUartPs_WriteReg(InstancePrt->Config.BaseAddress,XUARTPS_ISR_OFFSET,IsrStatus);

}
————————————————
版权声明:本文为CSDN博主「youbin2013」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youbin2013/article/details/89252618
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-6-17 03:06 , Processed in 0.062974 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表