[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-14 PS SPI扩展GPIO实验

文档创建者:FPGA课程
浏览次数:160
最后更新:2024-09-26
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 1-SDK基础入门方案
本帖最后由 FPGA课程 于 2024-9-26 09:56 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1 概述
前文中我们掌握了 ZYNQ 的 SPI 控制器的使用,本文中通过动态驱动数码管进一步展示 SPI 控制器的使用。本文所用到的 74HC595 是一种常见的串并转换芯片,74HC595 支持级联,可以实现一个 SPI 接口扩展大量 IO。以下的示意图中,ZYNQ 需要提供 SPI 控制器的 MOSI 和 SCK 以及一个 LACH 信号,提供给 74HC595,通过 74HC595扩展了16 个 IO 动态驱动 4 位数码管。
实验目的:
1:阅读 74HC595 数据手册,掌握 74HC595 芯片的串并转换时序
2:熟悉数码管动态显示原理
3:通过 VITIS-SDK 以及 SPI 控制器完成对 74HC595 芯片串并转换,并且动态驱动数码管
2 系统框图
afcb546542d4416c925f2d122b3eab60.jpg

3 使用74HC595驱动数码管
3.1 数码管动态显示原理
770cf11f0da24df7b5619a86cc318118.jpg
如上图所示,为我们 4 位共阳极 7 位数码管的电路原理图,这里的数码管是共阳极驱动,所以当 74HC595 U2
的 QA、QB、QC、QD 控制数码管的阳极,也就是负责选通哪一个数码管点亮;而 74HC595 U1 控制显示具体的数值内容。动态显示的原理就是某一个时刻只显示 1 个数码管,对于我们人眼来说刷新率在 25hz 以上就会感觉所有数码管都是同时点亮的效果。
我们看到数码管的字母 abcdefgdp 代表的是数码意思呢?如下图所示,就是代表了每个 LED,当设置 abcdefgh
种任意位为 0 就是点亮数码管。所以我们可以得出一个表,用于显示相应的数值。
d2984dcb67d942fbb06d186b35a7d923.jpg
ab56da5c21ec41689a016e179e424e07.jpg
3.2 认识74HC595使用
1:74HC595的内部功能单元
fbded0cc4a204b1fb05f3ca9b40ad267.jpg
我们先从 74HC595 内部的原理图看下芯片的功能。可以看到里面最关键功能单元是 8 个 D 触发器用于移位和另外8个D触发器用于数据的输出到功能 PIN 脚上。我们 SPI 接口的数据从 Serial input A 输入,并且通过 SHIFT CLOCK 每个时钟移位进入 74HC595 的触发器中,一个74HC595 支持 8bit IO 扩展,如果需要更多 IO,则可以通过74HC595 的级联输出到下一个 74HC595 芯片的输入。如上面图片所示,我们的为了动态驱动数码管,扩展了16个IO(其中有 4 个本例中没有用到)。比如本文中的例子,我们完成了 16bit 数据的移位,那么需要通过 LATCH CLK把数据从移位寄存器打入输出寄存器。
2:74HC595 驱动真值表
d410362615b24d949564e4a875fc64d8.jpg
以上这张表是来源于 74HC595 的计数手册,笔者红线框出的部分就是我们需要设计的驱动时序要求。从中可
以看到,74HC595 工作需要设置复位管脚为高电平,并且设置 Output Enable 为低电平。第一个红框中数据在每个
shift Clock 的上升沿打入移位寄存器。在第二个红框中 Latch Clock 为上升沿的时候,数据从移位寄存器打入输出寄存器。
3:74HC595 关键的时序要求
另外我们需要了解下驱动时序,数据需要满足建立和保持时间。和我们 FPGA 的课程不一样,FPGA 的课程部分,SPI 控制器是自己设计的,所以需要自己设计时序,而 ZYNQ 的 SPI 控制器是已经做好了,一般只要 SCK 不是频率太高都能满足要求。
以下关于 74HC595 的两张时序表如下:
e3b84465d0f649bc95542ec56f3adfe8.jpg

ec08d0883aa6452cbf6a7411359623a7.jpg
一张图如下:
e18b94b4ab6042fcab417bc949d3d56d.jpg
4 硬件电路分析
注意:FEP 扩展卡有 1.8V 3.3V 之分,默认 MLK-H3_CZ08_7100使用 1.8V 版本 IO 的扩展卡
以下是 74HC595 驱动数码管的硬件原理图
70f8a75ffcec4b1c997cb811ee1e6ed7.jpg
MLK_H3_CZ08-7100功能底板的 FEP 接口定义如下:
4635348ea28c42c0b698c80c447defdb.jpg

5 搭建 SOC 系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建 SOC 工程的,请学习“01Vitis Soc 开发入这篇文章。
5.1SOC 系统工程
ddf9eaf0692640c09afc511079629ec4.jpg
ZYNQ IP 中设置 SPI0
77d7c4ddd55e4671b7a7e257d2db4c44.jpg
设置 SPI 的参考时钟,以及 PL 50M 时钟提供给 ILA 使用
048a6bf13543442f87e04559668a518b.jpg
ILA 设置
3164b621c79c4fc399c95af308ab487d.jpg
5.2 编译并导出平台文件
以下步骤简写,有不清楚的看第一篇文章。
1:单击 Block 文件右键Generate the Output ProductsGlobalGenerate
2:单击 Block 文件右键Create a HDL wrapper(生成HDL 顶层文件)Let vivado manager wrapper and auto-update(自动更新)
3:添加配套工程路径下 uisrc/04_pin/fpga_pin.xdc 约束文件
4:生成 Bit 文件。
5:导出到硬件: FileExport HardwareInclude bitstream
6:导出完成后,对应工程路径的 soc_hw 路径下有硬件平台文件:system_wrapper.xsa 的文件。根据硬件平台文件
system_wrapper.xsa 来创建需要 Platform 平台。
cb0de9b29239414bb991ffa3198bb2a2.jpg
6 搭建 Vitis-sdk 工程 创建 soc_base sdk platform APP 工程的过程不再重复,如果不清楚请参考本章节第一个 demo
6.1 创建 SDK Platform 工程
45256d5de81f49cdb6503de2e6f9e85b.jpg
右击 soc_base 编译,编译的时间可能会有点长
6.2 创建 APP 工程
3423941dde924449bc9391f60ae0eb5f.jpg
7 程序分析
由于对于 SPI 的驱动部分在前面文章中已经做了详细分析,所以我们这里不再重复。这里给出应用程序源码
  1. #include "spips.h"
  2. #include "xgpiops.h"
  3. #define GPIO_DEVICE_ID
  4. XPAR_XGPIOPS_0_DEVICE_ID
  5. #define hc595_lach (54)
  6. extern XSpiPs SpiInstance;
  7. extern u8 *ReadBuf ;
  8. extern u8 *SendBuf ;
  9. XGpioPs Gpio;
  10. //0~9 数码管对应的二进制码
  11. //zero = 0XC0
  12. //one = 0XF9
  13. //two = 0XA4
  14. //three= 0XB0
  15. //four = 0X99
  16. //five = 0X92
  17. //six = 0X82
  18. //seven= 0XF8
  19. //eight= 0X80
  20. //nine = 0X90
  21. u8 dpy_val[10]= {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
  22. void gpio_init()//初始化GPIO
  23. {
  24. XGpioPs_Config *ConfigPtr;
  25. ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
  26. XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);
  27. XGpioPs_SetDirectionPin(&Gpio, hc595_lach, 1);
  28. XGpioPs_SetOutputEnablePin(&Gpio, hc595_lach, 1);
  29. XGpioPs_WritePin(&Gpio, hc595_lach, 0x1);
  30. }
  31. int main(void)
  32. {
  33. int dpy_n = 0;
  34. gpio_init();
  35. SpiPs_Init(&SpiInstance,SPI_DEVICE_ID);
  36. while(1)
  37. {
  38. switch(dpy_n)
  39. {
  40. case 0:
  41. SendBuf[0] = 0x08;//8'b00001000;动态驱动第4位数码管的值
  42. SendBuf[1] = dpy_val[0];
  43. break;
  44. case 1:
  45. SendBuf[0] = 0x04;//8'b00000100; 动态驱动第3位数码管的值
  46. SendBuf[1] = dpy_val[1];
  47. break;
  48. case 2:
  49. SendBuf[0] = 0x02;//8'b00000010; 动态驱动第2位数码管的值
  50. SendBuf[1] = dpy_val[2];
  51. break;
  52. case 3:
  53. SendBuf[0] = 0x01;//8'b00000001; 动态驱动第1位数码管的值
  54. SendBuf[1] = dpy_val[3];
  55. break;
  56. default:
  57. SendBuf[0] = 0x0;
  58. SendBuf[1] = 0x0;
  59. break;
  60. }
  61. XGpioPs_WritePin(&Gpio, hc595_lach, 0x0); //595芯片的lach信号设置低电平
  62. SpiPs_Send(&SpiInstance,SendBuf,2); //SPI发送数据
  63. XGpioPs_WritePin(&Gpio, hc595_lach, 0x1); //595芯片的lach信号设置高电平更新数据到595的IO
  64. if(dpy_n < 3) //完成显示器的动态切换
  65. dpy_n++;
  66. else
  67. dpy_n = 0;
  68. }
  69. return 0;
  70. }
复制代码


以上代码中实现了动态点亮数码管,通过在线逻辑分析仪可以查看我们的 SPI 驱动时序。
c0f9849625b243b48ed218c407f62fb2.jpg
8 实验结果
8.1 硬件准备
本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即ON ON(注意新版本的 MLK_H3_CZ09_7035),支持 JTAG 模式,对于老版本的核心板,JTAG 调试的时候一定要拔掉TF卡,并且设置模式开关为 OFF OFF)
43e5af96779a47efb25c2d9b02426834.jpg
8.2 实验结果
15556dbb939a4a8988a364ce980cde06.jpg
f2922a0fef904d1b980ba885a7264693.jpg

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则