请选择 进入手机版 | 继续访问电脑版
[X]关闭

[米联客-XILINX-H3_CZ08_7100] LINUX驱动篇连载-08 PS UART中断接收实验

文档创建者:LINUX课程
浏览次数:217
最后更新:2024-09-10
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 2_LINUX应用开发
本帖最后由 LINUX课程 于 2024-9-11 10:23 编辑

软件版本:vitis2021.1(vivado2021.1)
操作系统:WIN10 64bit
硬件平台:适用XILINX Z7/ZU系列FPGA
登录“米联客”FPGA社区-www.uisrc.com视频课程、答疑解惑!

1 概述
串口自诞生以来由于其简单可靠的传输方式,被大量使用,对于现在这个充满高速通信设备的时代来说,串口依然不过时。老早以前的台式机和笔记本可都是有串口的,虽然现在很多台式机串口没有了,笔记本也没有串口了,但是串口从来没有被丢弃,只是以另外一种形式存在,这就是USB转串口芯片。串口只需要2根线就可以实现一收一发,使用简单,可靠方便,在低速场合大量使用。比如一些工控的人机界面、我们用的一些单片机的USB下载器都是用USB转串口来实现的。
实验目的:
  • 熟悉UART串口通信协议,包括数据格式、波特率、起始位、停止位、奇偶校验位等
  • 熟悉ZYNQ的UART串口的功能单元以及寄存器功能
  • 实现串口的中断接收,发出
2 系统框图
image.jpg
3 UART串口通信协议介绍
我们先了解串口通信协议。通常串口的一次发送或接收由四个部分组成:起始位S(“一般为逻辑‘0’)、数据位D0~D7(一般为6位~8位之间可变,数据低位在前)、校验位(奇校验、偶检验或不需要校验位)、停止位(通常为1位、1.5位、2位)。停止位必须为逻辑1。在一次串口通信过程中,数据接收与发送双方没有共享时钟,因此,双方必须协商好数据传输波特率。波特率即数据传输速率。根据双方协议好的传输速率,接收端即可对发送端的数据进行采样。常见的波特率标准为300bps,600bps,800bps,9600bps,19200bps,38400bps,115200bps等。当然更块的速度意味着对采样的要求更高,有可能误码率会逐渐提高。
通常对串口进行数据采样,采用更高频的时钟。这样做的目的是采用高频时钟来锁存低频时钟,减少数据的误码率,增加接收模块的自纠错能力。
具体的工作流程为:
        发送端按照预先设定好的波特率,发送起始位(Start)+数据位(data)+奇偶校验位+结束位。其中,起始位为逻辑0,结束位为逻辑1,发送端在空闲状态为1。发送数据包格式如下图所示。
image.jpg
数据的奇偶校验位是可以选择的,如果不使用奇偶,那么就没有这个数据位,我们本课程中没有用到奇偶校验位。
        接收端通过检测电平‘1’到‘0’的跳变来确定一个数据包的开始。确定开始位接收完成之后,依次接收数据,使用更高的采样时钟,完成数据采集。接收完数据位后,继续接收奇偶校验位和停止位。
        ZYNQ的UART控制器可以完成发送数据的编码和接收数据的界面,关于更多UART的硬件知识可以阅读以下ZYNQ UART串口部分介绍。
4 ZYNQ UART串口控制介绍
4.1UART控制器概述
image.jpg
ZYNQ的UART控制器支持全双工异步收发,支持多种可编程波特率和I/O信号格式支持自动奇偶校验和多主机检测模式。
通过配置和模式寄存器控制UART,通过读取FIFO状态寄存器、中断状态寄存器、调制解调状态寄存器、其他功能状态寄存器获取UART的工作状态。
UART的TX和RX路径是异步独立的,TX路径和RX路径各有一个64字节的FIFO。控制寄存器可以对UART中的TX和RX FIFO数据序列化和反序列化,另外还包含一个模式开关可以设置TX到RX的环路设置。
在类似调制解调器的应用中使用UART时,调制解调器控制模块会检测并生成调制解调器握手信号,并根据握手协议控制接收器和发送器路径。
4.2UART控制器特性
  • 具有可编程波特率发生器
  • 具有可配置的接收和发送FIFO,具有字节,两个字节或四个字节的APB访问机制
  • 支持6、7或8个数据位
  • 支持1、1.5或2个停止位
  • 支持奇数,偶数,空格,标记或无奇偶校验
  • 支持奇偶校验,成帧和溢出错误检测
  • 具有断行的生成和检测
  • 支持自动回显,本地环回和远程环回通道模式
  • 支持中断产生
  • 具有调制解调器控制信号:CTS,RTS,DSR,DTR,RI和DCD
  • UART有两个时钟:高级外围总线(APB)的时钟频率高达100 MHz。 uart_ref_clock的范围是1 MHz至100 MHz。
4.3UART控制器功能描述
1:UART控制器框图
image.jpg
2:波特率发生器
image.jpg
UART的sel_clk时钟:
该时钟为UART_REF_CLKk或者UART_REF_CLK/8
波特率采样时钟使能baud_sample:
baud_sample=sel_clk/CD
波特率baud_rate:
baud_rate = baud_sample/ (BDIV + 1)
CD的值范围为1~65535,BDIV的值范围为4~255
以下给出了UG585中常用波特率的计算参数
image.jpg
3:TX发送FIFO
软件需要发送的数据首先会填入到TX的FIFO。
4:TX发送串行发送模块
发送模块从TxFIFO中移除数据,并将其加载到发送器移位寄存器中,以便可以对其进行串行化。发送模块将起始位,数据位,奇偶校验位和停止位移出为串行数据流。在发送波特率时钟使能(baud_tx_rate)的下降沿发送数据,最低有效位在前。
下图中的数据包含了PA奇偶校验位,很多情况下没有这位数据,那么数据就是一共需要10个发送时钟。
image.jpg
5:RX接收FIFO
当RX串行接收模块接收到数据后,数据移入RX接收FIFO。
6:RX串行接收模块
UART使用UART_REF_CLK和时钟使能(baud_sample)连续对UARTx_RxD信号进行过采样。当在中间位置连续监测到3次低电平代表收到RX的起始位。如下所示,采样速度是16倍的波特率。
image.jpg
当检测到有效的起始位时,接收器波特率时钟使能(baud_rx_rate)将重新同步,以便在每个位的理论中点附近对输入的UART RxD信号进行进一步采样。
image.jpg
7:I/O模式切换
模式开关控制控制器内RxD和TxD信号的路由,共有四种工作模式如下图所示,除非只是测试UART软件代码,否则我们都是使用普通模式。
image.jpg
8:UART中断与状态控制器
UART的中断和状态控制器在下面的寄存器介绍中介绍
9:UART调制解调器控制
这部分功能我们不涉及。
4.4UART寄存器概述
XUARTPS_CR寄存器XUARTPS_CR_OFFSET (0x00U)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_CR
31:0
RW
0x0
31~9bit:保留
8bit:暂停并发送停止位(STOPBRK)
1-当传输一个字节后,设置该位产生停止位,输出12bit的高电平。
0-无影响
7bit:暂停并发送起始位(STARTBRK)
    1-当FIFO中已经填入需要发送的数据,并且TX发送移位寄存器已经传输完毕,启动发送起始位。必须在STOPBRK=0的情况下有效。
0-无影响
6bit:重启接收超时计数器(TORST)
1-使能接收超时计数
0-无影响
5bit:禁止发送(TX_DIS)
1-禁止发送
    0-使能
4bit:使能发送(TX_EN)
1-使能发送,需要确保TX_DIS=0
    0-禁止发送
3bit:禁止接收(RX_DIS)
1-禁止接收,不管RXEN的值
    0-使能
2bit:使能接收(RX_EN)
1-使能接收,RX_DIS=0有效
    0-禁止接收
1bit:软件复位(TXRST)
1-复位发送逻辑,复位完成后自动清零
    0-无影响
0bit:软件复位(RXRST)
1-复位接收逻辑,复位完成后自动清零
    0-无影响
XUARTPS_MR寄存器XUARTPS_MR_OFFSET (0x04U)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_MR
31:0
RW
0x0
31~12bit:保留(只读)
11~10bit:保留(可以读写,但是不要修改)
9~8bit:通道模式(CHMODE)
00-正常模式
01-echo模式
10-本地环路
11-远程环回
7~6bit:停止位(NBSTOP)
00-1bit停止位
01-1.5bit停止位
10-2个停止位
11-保留
5~3bit:奇偶校验位(PAR)
000-偶校验
001-奇校验
010-奇偶校验强制为0
011-奇偶校验强制为1
1xx-无校验
2~1bit:字符长度(CHRL)
11-6bits
10-7bits
0x-8bits
0-时钟源选择(CLKSEL)
0-uart_ref_clk
1-uart_ref_clk/8
XUARTPS_IER寄存器XUARTPS_IER_OFFSET (0x08U)
中断使能寄存器,设置1使能相关中断
Field Name
Bits
Type
Reset Value
Description
XUARTPS_IER
31:0
WO
0x0
31~13bit:保留(只读)
12bit:FIFO溢出中断使能(TOVR)
11bit:FIFO将满中断使能(TNFUL)
10bit:FIFO发送器FIFO出发中断使能(TTRIG)
9bit:Delta调制解调器状态指示器中断使能(IXR_DMS)
8bit:接收超时错误中断使能(IXR_TOUT)
7bit:接收奇偶校验错误中断使能(IXR_PARITY)
6bit:接收帧错误中断使能(IXR_FRAMING)
5bit:接收溢出中断使能(IXR_OVER)
4bit:发送FIFO满中断使能(IXR_TXFULL)
3bit:发送FIFO空中断使能(IXR_TXEMPTY)
2bit:接收FIFO满中断使能(IXR_RXFULL)
1bit:接收FIFO空中断使能(IXR_RXEMPTY)
0bit:接收FIFO中断触发使能(IXR_RXOVR)
XUARTPS_IDR寄存器XUARTPS_IDR_OFFSET (0x0CU)
中断禁用寄存器,设置1禁用相关中断
Field Name
Bits
Type
Reset Value
Description
XUARTPS_IDR
31:0
WO
0x0
31~13bit:保留(只读)
12bit:FIFO溢出中断禁用(TOVR)
11bit:FIFO将满中断禁用(TNFUL)
10bit:FIFO发送器FIFO出发中断禁用(TTRIG)
9bit:Delta调制解调器状态指示器中断禁用(IXR_DMS)
8bit:接收超时错误中断禁用(IXR_TOUT)
7bit:接收奇偶校验错误中断禁用(IXR_PARITY)
6bit:接收帧错误中断禁用(IXR_FRAMING)
5bit:接收溢出中断禁用(IXR_OVER)
4bit:发送FIFO满中断禁用(IXR_TXFULL)
3bit:发送FIFO空中断禁用(IXR_TXEMPTY)
2bit:接收FIFO满中断禁用(IXR_RXFULL)
1bit:接收FIFO空中断禁用(IXR_RXEMPTY)
0bit:接收FIFO中断触发禁用(IXR_RXOVR)
XUARTPS_IMR寄存器XUARTPS_IMR_OFFSET (0x10U)
中断掩码寄存器,是只读寄存器1代表相关中断使能,0代表相关中断禁用
Field Name
Bits
Type
Reset Value
Description
XUARTPS_IMR
31:0
WO
0x0
31~13bit:保留(只读)
12bit:FIFO溢出中断掩码(TOVR)
11bit:FIFO将满中断掩码(TNFUL)
10bit:FIFO发送器FIFO出发中断掩码(TTRIG)
9bit:Delta调制解调器状态指示器中断掩码(IXR_DMS)
8bit:接收超时错误中断掩码(IXR_TOUT)
7bit:接收奇偶校验错误中断掩码(IXR_PARITY)
6bit:接收帧错误中断掩码(IXR_FRAMING)
5bit:接收溢出中断掩码(IXR_OVER)
4bit:发送FIFO满中断掩码(IXR_TXFULL)
3bit:发送FIFO空中断掩码(IXR_TXEMPTY)
2bit:接收FIFO满中断掩码(IXR_RXFULL)
1bit:接收FIFO空中断掩码(IXR_RXEMPTY)
0bit:接收FIFO中断触发掩码(IXR_RXOVR)
XUARTPS_ISR寄存器XUARTPS_ISR_OFFSET (0x14U)
中断状态寄存器,1代表相关中断产生,读该位会清除中断状态
Field Name
Bits
Type
Reset Value
Description
XUARTPS_ISR
31:0
WTC
0x0
31~13bit:保留(只读)
12bit:FIFO溢出中断状态(TOVR)
11bit:FIFO将满中断状态(TNFUL)
10bit:FIFO发送器FIFO出发中断状态(TTRIG)
9bit:Delta调制解调器状态指示器中断状态(IXR_DMS)
8bit:接收超时错误中断状态(IXR_TOUT)
7bit:接收奇偶校验错误中断状态(IXR_PARITY)
6bit:接收帧错误中断状态(IXR_FRAMING)
5bit:接收溢出中断状态(IXR_OVER)
4bit:发送FIFO满中断状态(IXR_TXFULL)
3bit:发送FIFO空中断状态(IXR_TXEMPTY)
2bit:接收FIFO满中断状态(IXR_RXFULL)
1bit:接收FIFO空中断状态(IXR_RXEMPTY)
0bit:接收FIFO中断触发状态(IXR_RXOVR)
XUARTPS_BAUDGEN寄存器XUARTPS_BAUDGEN_OFFSET (0x18U)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_BAUDGEN
31:0
WR
0x28
31~16bit:保留(只读)
15~0bit:波特率分频器
0-禁止波特率采样
1-Bypass (baud_sample = sel_clk)
2-2~65535分频
XUARTPS_RXTOUT寄存器XUARTPS_RXTOUT_OFFSET (0x1CU)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_RXTOUT
31:0
WR
0x0
31~8bit:保留(只读)
7~0bit:接收超时寄存器
0-禁用接收超时
1~255个baud_sample 时钟周期作为超时检测
XUARTPS_RXWM寄存器XUARTPS_RXTOUT_OFFSET (0x20U)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_RXWM
31:0
WR
0x20
31~6bit:保留(只读)
5~0bit:接收FIFO触发值
0-禁用触发
1~63 FIFO当FIFO已经有了相应数据产生接收触发中断
XUARTPS_MODEMCR寄存器XUARTPS_MODEMCR_OFFSET (0x24U)
Modem控制寄存器该寄存器本实验不涉及不介绍
XUARTPS_MODEMSR寄存器XUARTPS_MODEMSR_OFFSET (0x28U)
Modem状态寄存器该寄存器本实验不涉及不介绍
XUARTPS_SR寄存器XUARTPS_SR_OFFSET (0x2CU)
只读通道状态寄存器,可以对 UART设计的原始未屏蔽状态信息的持续监控。
Field Name
Bits
Type
Reset Value
Description
XUARTPS_SR
31:0
RO
0x00
31~15bit:保留(只读)
14bit:发送FIFO满连续状态(TNFUL)
1-TX FIFO未使用的空间大于1
0-TX FIFO就剩1个未使用空间
13bit:发送FIFO触发连续状态(TTRIG)
1-TX FIFO的数据量大于或等于触发值
0-TX FIFO的数据量小于触发值
12bit:接收流延迟触发连续状态(FLOWDEL)
1-RX FIFO的数据量大于或者等于FDEL
0-RX FIFO的数据量小于FDEL
11bit:发送状态机激活(TACTIVE)
1-激活
0-未激活
10bit:接收状态机激活(RACTIVE)
1-激活
0-未激活
9~5bit:保留(只读)
4bit:发送FIFO满连续状态(TXFULL)
1-TX FIFO满
0-TX FIFO未满
3bit:发送FIFO空连续状态(TXEMPTY)
1-TX FIFO空
0-TX FIFO非空
2bit:接收FIFO满连续状态(RXFULL)
1-RX FIFO满
0-RX FIFO未满
1bit:接收FIFO空连续状态(RXEMPTY)
1-RX FIFO空
0-RX FIFO非空
0bit:接收FIFO触发连续状态(RXOVR)
1-RX FIFO的数据量大于或等于触发值
0-RX FIFO的数据量小于触发值
XUARTPS_FIFO寄存器XUARTPS_FIFO_OFFSET (0x30U)
Field Name
Bits
Type
Reset Value
Description
XUARTPS_FIFO
31:0
WR
0x20
31~8bit:保留(只读)
7~0bit:发送或者接收FIFO
Baud_rate_divider_reg0寄存器Baud_rate_divider_reg0 (0x34U)
baud_sample被分频成多少产生波特率
Field Name
Bits
Type
Reset Value
Description
BDIV
31:0
WR
0x20
31~8bit:保留(只读)
7~0bit:
     0~3:保留
     4~255:用于波特率分频
Flow_delay_reg0寄存器Flow_delay_reg0 (0x38U)本实验用不到该寄存器只有在调制解调器控制寄存器的 FCM 字段中启用了自动流控制模式时,才使用流控制延迟寄存器。 当使能自动流控制模式时,该寄存器指定EMIOUARTxRTSN输出被取消置位的接收器FIFO级别。 EMIOUARTxRTSN 输出仅在填充水平降至低于 FDEL 4 倍以下时才会再次置位。
Tx_FIFO_trigger_level0寄存器Tx_FIFO_trigger_level0 (0x3CU)
baud_sample被分频成多少产生波特率
Field Name
Bits
Type
Reset Value
Description
TTRIG
31:0
WR
0x20
31~6bit:保留(只读)
5~0bit:
     0:禁用FIFO触发功能
     1~63:设置FIFO触发的数据量
5 搭建SOC系统工程
本实验无须搭建新工程,可运行于任意系统之上。若无可运行系统请参考“[米联客-XILINX-H3_CZ08_7100] LINUX基础篇连载-05 恢复出厂及固化至eMMC内系统,重新制作系统。
6 程序分析
在Linux系统中,串口可以作为字符驱动调用,此处不再赘述字符驱动,若不熟悉请看第一章内容。
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <fcntl.h>
  4. #include <termios.h>

  5. int main(int argc, char **argv)
  6. {
  7.     int fd = open("/dev/tty", O_RDWR | O_NOCTTY);
  8.     if (fd < 0)
  9.     {
  10.         //打开串口失败,退出
  11.         printf("open failed\n");
  12.         return -1;
  13.     }

  14.     while (1)
  15.     {
  16.         unsigned char buffer[1024] = {0};
  17.         int ret = read(fd, buffer, sizeof(buffer));
  18.         if (ret > 0)
  19.         {
  20.             printf("Printf: %s", buffer);

  21.             int n = write(fd, buffer, ret);
  22.             if (n != ret)
  23.                 printf("send failed\n");

  24.             if (buffer[0] == 81 || buffer[0] == 113)
  25.                 break;
  26.         }
  27.         else
  28.             usleep(1000 * 50);
  29.     }

  30.     close(fd);
  31.     return 0;
  32. }
复制代码
行8,打开串口设备。
行16,使用while反复检测是否有输入。
行19,使用read函数读取串口数据。
行22,使用printf打印出收到的数据。
行24,使用串口输出收到的串口数据。
7 演示结果
将与资料对应的demo拷贝至sd卡文件系统的/home/uisrc/内。
1725930475712.jpg
弹出sd卡插入开发板。
SD2.0 启动 01 而模式开关为 ON OFF(7100 需要先将系统烧录进qspi,然后才能从qspi启动sd卡,“[米联客-XILINX-H3_CZ08_7100] LINUX基础篇连载-04 从vitis移植Ubuntu实现二次开发”)
2f5038eb9880afd532753935815b079.jpg
将 PS 端串口线连接电脑,如果要使用 ssh 登录,将网口线同样连接至电脑,最后给开发板通电。每次重新上电,需要重新插拔 PS 串口,否则会登录失败。
image.jpg
登录板卡后,cd至demo的位置:
image.jpg
运行sudo ./psuart查看结果,root的密码为root:
image.jpg
输入一些字符测试,输入完毕按回车。这里输入了test作为测试,test输出了两遍,第一遍为printf输出,第二遍为串口输出。输入Q、q或者ctrl+c可退出程序。
若想自己编译,可使用gcc命令:
image.jpg
可以看到编译完多了一个文件,gcc编译的默认输出名称为a.out。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则