ZYNQ学习之SPI的使用

本文主要介绍使用ZYNQ硬核通过编程实现SPI通信,为控制外设提供参考!

软件:Vivado2018.2

硬件:PYNQ-Z2(理论上来说,只要含Zynq-7000 SoC的开发板都可以)

理论:熟悉SPI通信协议与时序

硬件回环连接,由MOSI发,MISO接收,数据暂存在FIFO模块中!

第一部分

PL部分,新建Vivado工程,新建Block Design,添加zynq7 Processing System,点击自动连线。完成后如图所示

双击ZYNQ7,添加SPI_0接口,本次只用到SPI_0。如图所示

手动连线,将SPI_0的四个管脚引出,其中MISO为Input,其余三个为Output。完成后如图所示

下面Creat HDL  Wrapper,然后进行Run Synthesis,综合完成后在弹出的窗口里选择中间选项。如图所示

接下来要对四个引出的管脚进行约束,先点击Schematic,然后点击I/O Ports,扩大下面的窗口,找到我们连接的四个管脚,如图

参考你所用的开发板的Schematic,找到对应的管脚编号,并在表中对应填写,电平标准都选择LVCOM18即可。如图,填写完成后保存,自动生成XDC约束文件。

上述完成后,点击Generate Bitstream,时间较长,等待完成。完成后导出hdf文件,然后Launch SDK。如图所示

第二部分

PS部分,进入SDK后,新建工程。如图所示

在helloworld.c文件中原代码删除,替换为如下代码,保存。

#include "xparameters.h"
#include "xspips.h"
#include "xil_printf.h"
#include "sleep.h"
XSpiPs Spi0, Spi1;
 
#define SpiPs_RecvByte(BaseAddress) \
		(u8)XSpiPs_In32((BaseAddress) + XSPIPS_RXD_OFFSET)
 
#define SpiPs_SendByte(BaseAddress, Data) \
		XSpiPs_Out32((BaseAddress) + XSPIPS_TXD_OFFSET, (Data))
 
int spi0_init();
void spi0_one_write();
void SpiRead(int ByteCount);
void SpiWrite(u8 *Sendbuffer, int ByteCount);
 
unsigned char ReadBuffer[1024];
unsigned char WriteBuffer[1024]={1,2,3,4,5,6,7,8,9,0};
int main(void) {
	int Status;
	int i,j;
	int value;
	xil_printf("SPI Selftest Example \r\n");
 
	Status = spi0_init();
	if (Status != XST_SUCCESS) {
		xil_printf("SPI Selftest Example Failed\r\n");
		return XST_FAILURE;
	}
 
 
	for (i = 0; i < 6; i++)
	{
		SpiWrite(WriteBuffer,10);
		SpiRead(10);
		//xil_printf("read back \n");
		for (j = 0; j < 10; j++ )
		{
			xil_printf("%d,",ReadBuffer[j]);
		}
		xil_printf("\n");
		memset(ReadBuffer, 0x00, 1024);
		sleep(1);
	}
	xil_printf("Successfully ran SPI Selftest Example\r\n");
	return XST_SUCCESS;
}
 
void SpiRead(int ByteCount)
{
	int Count;
	u32 StatusReg;
 
	StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
					XSPIPS_SR_OFFSET);
 
	/*
	 * Polling the Rx Buffer for Data
	 */
	do{
		StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
					XSPIPS_SR_OFFSET);
	}while(!(StatusReg & XSPIPS_IXR_RXNEMPTY_MASK));
 
	/*
	 * Reading the Rx Buffer
	 */
	for(Count = 0; Count < ByteCount; Count++){
		ReadBuffer[Count] = SpiPs_RecvByte(
				Spi0.Config.BaseAddress);
	}
 
}
 
void SpiWrite(u8 *Sendbuffer, int ByteCount)
{
	u32 StatusReg;
	int TransCount = 0;
 
	StatusReg = XSpiPs_ReadReg(Spi0.Config.BaseAddress,
				XSPIPS_SR_OFFSET);
 
	while ((ByteCount > 0) &&
		(TransCount < XSPIPS_FIFO_DEPTH)) {
		SpiPs_SendByte(Spi0.Config.BaseAddress,
				*Sendbuffer);
		Sendbuffer++;
		++TransCount;
		ByteCount--;
	}
 
	/*
	 * Wait for the transfer to finish by polling Tx fifo status.
	 */
	do {
		StatusReg = XSpiPs_ReadReg(
				Spi0.Config.BaseAddress,
					XSPIPS_SR_OFFSET);
	} while ((StatusReg & XSPIPS_IXR_TXOW_MASK) == 0);
 
}
 
int spi0_init() {
	int Status;
	XSpiPs_Config *SpiConfig;
 
	/*
	 * Initialize the SPI device.
	 */
	SpiConfig = XSpiPs_LookupConfig(XPAR_XSPIPS_0_DEVICE_ID);
	if (NULL == SpiConfig) {
		return XST_FAILURE;
	}
 
	Status = XSpiPs_CfgInitialize(&Spi0, SpiConfig, SpiConfig->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
 
	/*
	 * Perform a self-test to check hardware build.
	 */
	Status = XSpiPs_SelfTest(&Spi0);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	xil_printf("%s self test succ\r\n", __func__);
 
	Status = XSpiPs_SetOptions(&Spi0, XSPIPS_MASTER_OPTION);
	if (Status != XST_SUCCESS) {
		xil_printf("%s XSpiPs_SetOptions fail\n", __func__);
		return XST_FAILURE;
	}
	Status = XSpiPs_SetClkPrescaler(&Spi0, XSPIPS_CLK_PRESCALE_64);
	if (Status != XST_SUCCESS) {
		xil_printf("%s XSpiPs_SetClkPrescaler fail\n", __func__);
		return XST_FAILURE;
	}
	XSpiPs_Enable(&Spi0);
	xil_printf("spi 0 config finish\n");
	return XST_SUCCESS;
}

下面板上测试,回环连接后,开发板上电,通过SDK自带串口,与开发板进行连接。如图所示

串口连接成功后,首先Program FPGA,然后Run As--->Launch On Hardware。如图所示

然后在窗口中就能看到串口打印的数据了,至此,例程结束。


本文是在参考前辈的文章基础上,亲自验证可行,对没有详细说明的地方贴了图,感谢分享,也希望可以帮到更多人!

前辈文章链接:ZYNQ SPI测试

  • 24
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
### 回答1: 《领航者Zynq嵌入式开发指南PDF》是一本介绍嵌入式开发的指南,旨在帮助开发人员更好地利用领航者(Zynq)芯片进行开发。 该指南首先介绍了领航者芯片的概述和特点,包括芯片的内部结构、功能模块和性能等方面。然后详细介绍了使用Xilinx公司提供的开发工具进行开发的过程。其中包括使用Vivado工具进行设计、使用SDK进行软件开发和调试,并讲解如何将硬件和软件集成在一起进行验证和调试。 指南中还介绍了一些常用的开发技术,如嵌入式Linux系统的构建、外设驱动程序的编写、裸机程序的编写和硬件加速等。这些内容涉及的知识比较广泛,需要读者有一定的基础。 总体来说,该指南是一本比较全面的嵌入式开发入门指南,既适合初学者快速入门,也适合有一定经验的开发人员深入学习。但是需要注意的是,由于领航者芯片的性能和复杂度比较高,需要有一定的硬件和软件开发基础才能更好地理解和应用。 ### 回答2: 《领航者 Zynq嵌入式开发指南 PDF》是一本针对Xilinx公司的领航者Zynq系列芯片进行嵌入式开发的详细指南,主要面向嵌入式开发工程师、软件开发人员和电子工程师等专业人士。这本指南中包含了许多有用的信息,可以帮助读者更快、更便捷地熟悉和掌握领航者Zynq系列芯片的基本架构和开发环境。 在本指南中,读者可以学习到如何使用Vivado软件进行FPGA设计,以及如何使用SDK软件进行嵌入式软件开发和调试。此外,本指南还介绍了如何将硬件与软件共同进行设计和实现,以及如何将嵌入式系统移植到领航者Zynq系列芯片上。 笔者认为,这本指南的最大特点是它针对的是具体的芯片系列,因此非常实用。此外,本指南提供了许多实际的案例和实验,可以让读者更好地了解和掌握领航者Zynq的开发流程和技巧,使得读者能够尽快地掌握这种芯片的嵌入式开发技术,进而开发出更具有竞争力的产品和方案。 综上所述,读者如果想了解领航者Zynq系列芯片的嵌入式开发技术,这本《领航者 Zynq嵌入式开发指南 PDF》是非常值得推荐的一本参考书。 ### 回答3: 领航者 zynq嵌入式开发指南是一本介绍如何使用Xilinx公司的zynq芯片进行嵌入式系统开发的指南。Zynq芯片是一种将FPGA和ARM Cortex-A9处理器集成在一起的芯片,因此既具备了FPGA的高度可编程性,又具备了ARM Cortex-A9处理器的高性能和低功耗。 在这本指南中,作者先介绍了zynq芯片的基本架构和特点,以及开发环境的配置和使用。接着,详细讲解了如何使用zynq芯片进行硬件系统设计和软件系统开发,包括如何将FPGA逻辑设计与处理器软件进行协同设计,如何使用Vivado HLS进行高层次综合,如何编写驱动程序和应用程序等等。 此外,这本指南还介绍了一些常用的外设的接口和驱动程序的编写方法,比如GPIO、UART、I2C、SPI等等。还介绍了如何使用Linux操作系统来进行嵌入式系统开发,并给出了一些实际应用案例的示例程序,帮助读者更好地理解和应用所学内容。 总体来说,这本指南对于想要使用zynq芯片进行嵌入式系统开发的工程师和学生来说,是一本非常实用和有价值的指南。通过学习这本指南,读者能够将FPGA逻辑设计和处理器软件开发相结合,实现高性能和高可编程性的嵌入式系统设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值