【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例

这篇具有很好参考价值的文章主要介绍了【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SPI 协议简介

SPI 是串行外设接口(Serial Peripheral Interface)的缩写,是美国摩托罗拉公司(Motorola)最先推出的一种同步串行传输规范,是一种高速、全双工、同步通信总线,可以在同一时间发送和接收数据,SPI没有定义速度限制,通常能达到甚至超过10M/bps。

SPI 有主、从两种模式,通常由一个主模块和一个或多个从模块组成(SPI 不支持多主机),主模块选择一个从模块进行同步通信,从而完成数据的交换。提供时钟的为主设备(Master),接收时钟的设备为从设备(Slave),SPI接口的读写操作,都是由主设备发起,当存在多个从设备时,通过各自的片选信号进行管理。

SPI 接口介绍

  • SCK:串行时钟信号,由主设备产生
  • CS/SS:片选信号,由主设备产生,用来控制从设备
  • MOSI:主设备数据输出,从设备数据输入
  • MISO:主设备数据输入,从设备数据输出

SPI 四种模式

SPI 根据时钟极性和时钟相位的不同可以有 4 种工作模式。

  • 时钟极性(CPOL)指通讯设备处于空闲状态(SPI 开始通讯前、CS 线无效)时 SCK 的状态。
    • CPOL = 0:SCK在空闲时为低电平
    • CPOL = 1:SCK在空闲时为高电平
  • 时钟相位(CPHA)指数据的采样时刻位于 SCK 的偶数边沿采样还是奇数边沿采样。
    • CPHA = 0:在SCK的奇数边沿采样
    • CPHA = 1:在SCK的偶数边沿采样
  • 通过时钟极性和时钟相位的不同组合 SPI 总共可以设置为4种工作模式
    • MODE0 : CPOL = 0 CPHA = 0 SCK空闲为低,SCK的奇数次边沿(上升沿)采样
    • MODE1 : CPOL = 0 CPHA = 1 SCK空闲为低,SCK的偶数次边沿(下降沿)采样
    • MODE2 : CPOL = 1 CPHA = 0 SCK空闲为高,SCK的奇数次边沿(下降沿)采样
    • MODE3 : CPOL = 1 CPHA = 1 SCK空闲为高,SCK的偶数次边沿(上升沿)采样

ZYNQ EMIO

EMIO 是扩展的 MIO,ZYNQ 支持通过配置将 PS 的控制器信号通过 EMIO 输出,即 EMIO 是在 PL 侧连接使用 PS 侧资源的扩展通道接口。可扩展到 PIN 上,也可以扩展到运用上。EMIO 与 MIO 一样归属于 GPIO,即经过扩展 PS 一共可以控制 54(MIO) + 64(EMIO) = 118 个引脚。文章来源地址https://www.toymoban.com/news/detail-465985.html

模拟驱动示例

  • spi_ctrl.c
/**
 * Copyright (c) 2022-2023,HelloAlpha
 *
 * Change Logs:
 * Date           Author       Notes
 */
#include "spi_ctrl.h"

/* CPOL = 0, CPHA = 0, MSB first */
uint8_t SOFT_SPI_RW_MODE0(uint8_t write_dat)
{
    uint8_t i, read_dat;
    for( i = 0; i < 8; i++ )
    {
        if( write_dat & 0x80 )
            MOSI_H();
        else
            MOSI_L();
        write_dat <<= 1;
        SPI_DELAY(1);	
        SCK_H(); 
        read_dat <<= 1;  
        if( MISO() ) 
            read_dat++; 
        SPI_DELAY(1);
        SCK_L(); 
        SPI_DELAY(1);
    }
    return read_dat;
}

/* CPOL=0,CPHA=1, MSB first */
uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat) 
{
    uint8_t i, read_dat;

    for( i = 0; i < 8; i++ )
    {
        SCK_H();
        if( write_dat & 0x80 )
            MOSI_H();
        else
            MOSI_L();
        write_dat <<= 1;
        SPI_DELAY(100);
        SCK_L();
        read_dat <<= 1;
        if(MISO())
            read_dat++;
        SPI_DELAY(100);
	}
    return read_dat;
}
 
/* CPOL=1,CPHA=0, MSB first */
uint8_t SOFT_SPI_RW_MODE2(uint8_t write_dat) 
{
    uint8_t i, read_dat;

    for( i = 0; i < 8; i++ )
    {
        if( write_dat & 0x80 )
            MOSI_H();
        else
            MOSI_L();
        write_dat <<= 1;
        SPI_DELAY(1);
        SCK_L();
        read_dat <<= 1;
        if(MISO())
            read_dat++;
        SPI_DELAY(1);
        SCK_H();
	}
	return read_dat;
}
 
/* CPOL = 1, CPHA = 1, MSB first */
uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat )
{
    uint8_t i, read_dat;
    for( i = 0; i < 8; i++ )
    {
        SCK_L(); 
        if( write_dat & 0x80 )
            MOSI_H();  
        else                    
            MOSI_L();  
        write_dat <<= 1;
        SPI_DELAY(1);	
        SCK_H(); 
        read_dat <<= 1;  
        if( MISO() ) 
            read_dat++; 
        SPI_DELAY(1);
    }
    return read_dat;
}

  • spi_ctrl.h
/**
 * Copyright (c) 2022-2023,HelloAlpha
 *
 * Change Logs:
 * Date           Author       Notes
 */
#ifndef __SPI_CTRL_H__
#define __SPI_CTRL_H__

#include "spi_io.h"

#include "sleep.h"

#define SPI_DELAY(...)	usleep(__VA_ARGS__)

#define SPI_START_COMMUNICATION     NSS_L()
#define SPI_STOP_COMMUNICATION      NSS_H()

/**
 * CPOL 配置 SPI 总线的极性
 * CPHA 配置 SPI 总线的相位
 * 
 * 模式0:CPOL=0,CPHA =0  MSB first
 *      SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)
 * 模式1:CPOL=0,CPHA =1  MSB first
 *      SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)
 * 模式2:CPOL=1,CPHA =0  MSB first
 *      SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)
 * 模式3:CPOL=1,CPHA =1  MSB first
 *      SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)
 */

/* CPOL = 0, CPHA = 0,  MSB first*/
uint8_t SOFT_SPI_RW_MODE0(uint8_t write_dat);
/* CPOL=0,CPHA=1, MSB first */
uint8_t SOFT_SPI_RW_MODE1(uint8_t write_dat);
/* CPOL=1,CPHA=0, MSB first */
uint8_t SOFT_SPI_RW_MODE2(uint8_t write_dat);
/* CPOL = 1, CPHA = 1, MSB first */
uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat );

#endif
  • spi_io.c
/**
 * Copyright (c) 2022-2023,HelloAlpha
 * 
 * Change Logs:
 * Date           Author       Notes
 */
#include "spi_io.h"

extern XGpioPs GpioPs;

static void SET_PIN_OUT(uint32_t PIN)
{
    XGpioPs_SetDirectionPin(&GpioPs, PIN, GPIO_MODEL_OUTPUT);
	XGpioPs_SetOutputEnablePin(&GpioPs, PIN, GPIO_OUTPUT_ENABLE);
}

void MOSI_H(void)
{
    SET_PIN_OUT(SPI_MOSI_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_MOSI_PIN, GPIO_SET);
}
 
void MOSI_L(void)
{
    SET_PIN_OUT(SPI_MOSI_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_MOSI_PIN, GPIO_RESET);
}
void SCK_H(void)
{
    SET_PIN_OUT(SPI_SCK_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_SCK_PIN, GPIO_SET);
}
void SCK_L(void)
{
    SET_PIN_OUT(SPI_SCK_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_SCK_PIN, GPIO_RESET);
}
uint32_t MISO(void)
{
    XGpioPs_SetDirectionPin(&GpioPs, SPI_MISO_PIN, GPIO_MODEL_INPUT);
    return XGpioPs_ReadPin(&GpioPs, SPI_MISO_PIN);
}
void NSS_H(void)
{
    SET_PIN_OUT(SPI_NSS_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_NSS_PIN, GPIO_SET);
}
void NSS_L(void)
{
    SET_PIN_OUT(SPI_NSS_PIN);
    XGpioPs_WritePin(&GpioPs, SPI_NSS_PIN, GPIO_RESET);
}
  • spi_io.h
/**
 * Copyright (c) 2022-2023,HelloAlpha
 *
 * Change Logs:
 * Date           Author       Notes
 */
#ifndef __SPI_IO_H__
#define __SPI_IO_H__

#include "xgpiops.h"

#define SPI_SCK_PIN             54
#define SPI_MOSI_PIN            55
#define SPI_MISO_PIN            56
#define SPI_NSS_PIN             57

#define GPIO_MODEL_INPUT        0
#define GPIO_MODEL_OUTPUT       1

#define GPIO_OUTPUT_DISABLE     0
#define GPIO_OUTPUT_ENABLE      1

#define GPIO_RESET              0
#define GPIO_SET                1

void MOSI_H(void);
void MOSI_L(void);
void SCK_H(void);
void SCK_L(void);
uint32_t MISO(void);
void NSS_H(void);
void NSS_L(void);

#endif

到了这里,关于【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动画图解常见串行通讯协议:SPI、I²C、UART、红外分析

    一、 SPI传输                                                          图1:SPI 数据传输                                                      图1.2:SPI数据传输(2) ​                                                 图1.3: SPI时序信号 二、 I²C传输 图

    2024年02月03日
    浏览(29)
  • 基于ZYNQ PS-SPI的Flash驱动开发

                    本文使用PS-SPI实现Flash读写,PS-SPI的基础资料参考Xilinx UG1085的文档说明,其 基础使用方法 是,配置SPI模式,控制TXFIFO/RXFIFO,ZYNQ的IP自动完成发送TXFIFO数据,接收数据到RXFIFO,FIFO深度为128Byte。本文介绍了使用PS-SPI的Flash开发。 硬件平台:Xilinx ZYNQ Flash芯片

    2024年03月23日
    浏览(28)
  • Zynq(2):MIO,EMIO点灯之路

    由于个人原因,最近一直在对基础知识的复习,所以ZYNQ的后续学习记录,一直没有更新。 FLAG:新年新气象,争取2022年春节之前将所有关于ZYNQ中ARM裸机部分内容更新完毕,主要是ARM外设。 ZYNQ 分为 PS 和 PL 两部分,那么器件的引脚(Pin)资源同样也分成了两部分。ZYNQ PS 中的

    2024年02月13日
    浏览(35)
  • FPGA - ZYNQ 基于EMIO的PS和PL交互

    Xilinx ZYNQ 系列的芯片,GPIO分为 MIO 、 EMIO 、 AXI_GPIO 三种方式。 MIO    :固定管脚,属于PS端,也就是ARM端。 EMIO   :通过PL扩展,使用时需要分配 PL ( FPGA ) 管脚,消耗PL端资源。 AXI_GPIO :封装好的IP核,PS通过M_AXI总线可以控制PL的IO接口,使用时,消耗管脚资源和逻辑资源。

    2024年04月26日
    浏览(32)
  • zynq+LWIP 裸机双网口实现(MIO+EMIO)+程序下载

    一、 简介 : 为实现 Zynq 裸机双网口通信功能,其中 ENET0 连接 PS 端网口,ENET1 通过 EMIO 扩展连接 PL 端网口 二、环境介绍 芯片型号: ZYNQ: XC7Z010clg400 开发软件:Vivado2022 + Xilinx Vitis 2022 网卡芯片:RTL8211FDI LWIP库 :lwip官方下载地址:http://savannah.nongnu.org/projects/lwip/(需要根据网

    2024年02月09日
    浏览(66)
  • PCAP01介绍和STM32模拟SPI驱动

    Pcap01是德国acam公司设计的一款革命性的电容测量芯片。该芯片 内部有DSP计算单元,可以直接将电容元件接到Pcap01芯片,然后芯片计算出容值大小,通过SPI总线将电容容值数据传送给CPU,电容测量完全数字化。 PCAP测量的原理是基于电容的充放电时间比。 PCAP01有8个通道,每一

    2024年02月12日
    浏览(37)
  • 【STM32篇】SPI时序驱动W25Q64(硬件SPI和模拟SPI)

            由于MCU的FLASH空间有限,在特殊使用场所中会存在FLASH存储不够使用的情况。例如上篇中驱动LCD屏,需要将一个中文字库保存到MCU的FLASH中是不太现实的(STM32F103ZET6内部FLASH大小512KB),为此可使用外部FLASH作为拓展。         W25Q64(64Mbit)是为系统提供一个最小的空

    2024年02月08日
    浏览(39)
  • 【接口协议】FPGA实现SPI协议基于ADC128S022进行模拟信号采集

    使用vivado联合modelsim实现SPI协议基于ADC128S022进行模拟信号连续采集。 SPI是串行外设接口,是一种同步/全双工/主从式接口。通常由四根信号线构成: CS_N :片选信号,主从式接口,可以有多个从机,用片选信号进行从机选择; SCLK :串行时钟线,由主机提供给从机; MISO :主机

    2024年02月07日
    浏览(37)
  • 【正点原子STM32】RS485串行通信标准(串口基础协议 和 MODBUS协议、总线连接、通信电路、通信波形图、RS485相关HAL库驱动、RS485配置步骤、)

    一、RS485介绍 二、RS485相关HAL库驱动介绍 三、RS485配置步骤 四、编程实战 五、总结 串口、UART、TTL、RS232、RS422和RS485之间的关系可以如此理解: 串口 :是一个广义术语,通常指的是采用串行通信协议的接口,它可以包括多种具体的物理接口标准和逻辑电平标准。 UART (通用

    2024年04月13日
    浏览(47)
  • 1.8寸TFT LCD128X160 ST7735S SPI串口屏驱动示例

    🌼1.8寸TFT LCD128X160 ST7735S SPI串口屏 📚屏幕驱动资料1 以下是由中景园提供的,里面包含了: 由于购买的是合宙的1.8寸TFT LCD128X160 ST7735S SPI串口屏随同ESP32C3一起购买的,价格是9.9RMB,比起中景园的相同规格的屏幕是16.5RMB,性价比还是很高的。 🛠汉字取模方式和软件 🔧 PCto

    2024年01月22日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包