NIOS II spi详解

1、说明

本文是依据笔者阅读《Embedded Peripherals (ver 9.0, Mar 2009, 4 MB).pdf》参考文档所作的个人理解,可以看做是笔记吧。

本文只讲NIOS II嵌入式外设SPI的原理与使用,关于IP-CORE的使用,请读者参考《SPI Slave JTAG to Avalon Master.pdf》。

在下一篇文章中将用实例说明如何用SPI驱动ADS1256。

2、功能描述

Spi通讯包括两条数据线(进、出)、一条同步时钟线和一条控制线。

(1)Master Out Slave In (mosi)—主设备输入数据到从设备的数据线。

(2)Master In Slave Out (miso)—从设备输出数据到主设备的数据线。

(3)Serial Clock (sclk)—主设备驱动从设备的同步时钟。

(4)Slave Select (ss_n)—主设备驱动,用于选择从设备。置低时有效。最多可以设置32个从设备。

Sclk与Avalon—MM是同步的。当配置为主设备,spi-core将Avalon—MM的时钟分频得到sclk。若配置为从设备,接收逻辑是与sclk的输入同步的。

3、发送逻辑

发送逻辑包含发送保持寄存器(txdata)和发送移位寄存器,各有n位宽度,可配置1~32位。当某主外设写txdata,值会自动被复制到移位寄存器,并在下个操作开始时传输。

Txdata和移位寄存器提供两个存储空间。当有数据在移位寄存器传输时,可以往txdata中写入数据,并且在移位寄存器处理完当前数据时会自动加载txdata中数据,并发送。

在主设备模式传输移位寄存器直接驱动mosi,在从设备模式,传输移位寄存器直接驱动miso。

数据传输时,LSB或者MSB在前,由配置时用户指定。指定之后,不可软件更改。

4、接收逻辑

接收逻辑包含接收保持寄存器(rxdata)和接收移位寄存器,各有n位宽度,可配置1~16位。在接收移位寄存器捕获满n位数据后,主外设可以从rxdata中读取接收到的数据。

同发送逻辑类似,接收逻辑同样具有提供两个存储空间的功能。Rxdata可以保持前一个接收到的数据,同时接收移位寄存器亦在接收数据。当一个传输完毕时,接收逻辑自动将接收移位寄存器的数据更新至rxdata。

在主设备模数时,接收移位寄存器直接受miso驱动。在从设备模式 ,受mosi驱动。同样,数据传输时,LSB或者MSB在前,由配置时用户指定。指定之后,不可软件更改。

5、在SOPC中安装SPI-CORE

5.1 主从设置

用户可以选择主设备模式或者从设备模式。当选择主设备模式时,下面的选择是有效的:Number of select (SS_n) signals、SPI clock rate、 和 Specify delay.

(1)Number of Select (SS_n) Signals

设置从设备的个数。取值范围是1~32。该选择会在生成NIOS II时产生n个SS_n引脚,用于片选。

(2)SPI Clock (sclk) Rate

该时钟是有Avalon-MM分频产生,其数学关系是:

/ [2, 4, 6, 8, ...]

在SOPC设置时,可以输入所需要的时钟,软件会自动选择一个低于或者等于所输入时钟的最近符合值。

时钟的设置注意结合从设备的要求。

(3)Specify Delay

该延时是指片选信号有效(置低)之后,需要多长的时间才能对从设备发起操作。

5.2 数据寄存器设置

该设置影响数据寄存器的大小和行为特性。

(1)Width—设置txdata、rxdata、发送移位寄存器、接收移位寄存器的大小,可设置为1~32位。

(2)Shift direction—指定数据传输时LSB或者MSB在前。用户需了解从设备所需的模式。

5.3 时序设定

该设定涉及ss_n,sclk,mosi 和 miso 信号的设置。共有两处设定,可设定4种模式。

(1)Clock polarity—设置为0时,sclk空闲时为低;设置为1时,sclk空闲时为高。

(2)Clock phase—设置为0时,数据在sclk的上升沿锁存;设置为1时,数据在sclk的下降沿锁存。

具体见如下时序图:

1.Clock Polarity = 0, Clock Phase = 0

2.Clock Polarity = 0, Clock Phase = 1

3.Clock Polarity = 1, Clock Phase = 0

4.Clock Polarity = 1, Clock Phase = 1

6、NIOS II软件驱动模块

有两种方式:

1.使用有Altera提供的alt_avalon_spi_command()函数,使用非常简单。具体可见笔者下一篇驱动实例。

2.读者自己编写。

这里先将读者自己DIY的驱动编写方法。

6.1 驱动方式一

必须包含:

#include "altera_avalon_spi.h"

#include "altera_avalon_pio_regs.h"

这两个头文件。

文件中包含有寄存器地址与API函数。

IOWR_ALTERA_AVALON_SPI_SLAVE_SEL();//从设备选择

IOWR_ALTERA_AVALON_SPI_CONTROL(base, data); //控制寄存器

IORD_ALTERA_AVALON_SPI_RXDATA(base);//读接收寄存器

IOWR_ALTERA_AVALON_SPI_TXDATA(base, data);//写发送寄存器

IORD_ALTERA_AVALON_SPI_STATUS(base);//读状态寄存器

为了准确实现方式,首先列出SPI寄存器映射图

(1)若rxdata和txdata少于16位,则[31:16]位无效;

(2)写status会清除ROE、TOE和E位;

(3)ss0只在作为主设备时有效;用来启动发送或者接受数据。例如:

//Force SS_n active:na_spi_0->np_spicontrol|=np_spicontrol_sso_mask;for(i=0; i<3;++i)

{//Transmit a byte:while(!(na_spi_0->np_spistatus&np_spistatus_trdy_mask));

na_spi_0->np_spitxdata=data[i];//Read and throw away the received data:while(!(na_spi_0->np_spistatus&np_spistatus_rrdy_mask));

na_spi_0->np_spirxdata;

}//Wait until the last byte is transmitted:while(!(na_spi_0->np_spistatus&np_spistatus_tmt_mask));//Release SS_n:na_spi_0->np_spicontrol&=~np_spicontrol_sso_mask;

(4)rxdata:

(a)当接收寄存器接收到所设置的n位且将数据移入rxdata后,status中的RRDY设为1;软件可设查询此位来判断是否有新数据接收。如:

while(IORD_ALTERA_AVALON_SPI_STATUS(base) & ALTERA_AVALON_SPI_STATUS_RRDY_MSK == 1);

(b)读rxdata会自动清除RRDY位;

(c)新数据总是不断读入rxdata,若RRDY=1; rxdata的数据未读出时,有新的数据传入rxdata,则ROE=1;此时,rxdata存储的数据未定义。

(5)txdata:

(a)当TRDY=1时,表示发送寄存器准备好接受下一个发送数据。如:

while(IORD_ALTERA_AVALON_SPI_STATUS(base) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK == 1);

(b)写入rxdata使TRDY=0;

(c)当txdata中的数据传入发送寄存器时,TRDY=1;

(d)若TRDY=0时写入数据至txdata会导致TOE=1;此时新数据被忽略。

6.2驱动方式二

该方式使用官方的函数:(下篇文章使用的是该方式。)

int alt_avalon_spi_command(alt_u32 base, alt_u32 slave,

alt_u32 write_length,

const alt_u8* wdata,

alt_u32 read_length,

alt_u8* read_data,

alt_u32 flags)

该函数不支持8位或者8位以上的传输。但是,可以调用多次实现高于8位的传输。该函数源码位于“/altera/81/ip/altera/sopc_builder_ip/altera_avalon_spi/HAL/src”。

alt_u32 base, alt_u32 slave,//选择从设备

alt_u32 write_length, //设置写入长度。8位为一个长度。

const alt_u8* wdata,//将要写入数据的数组地址。该函数自动将数组中的数据依次发出直到发出所设定的write_length长度。

alt_u32 read_length,//设置读出长度。8位为一个长度

alt_u8* read_data,//将读出的数据存储到数组中,直到存满所设定的read_length长度

alt_u32 flags,//如果flag=ALT_AVALON_SPI_COMMAND_MERGE,则访问完从设备之后不会释放从设备,一般用于需多次访问的情况。如果flag=0,则每次访问完从设备都会释放从设备,即当读取read_length个字节数,或者写完write_length个字节数,会释放从设备。

7、总结

笔者测试使用环境均为8.1版本。

使用器件为CYCLONE II EP2C8Q208C8N

niosii spi 外部_转载:NIOS II spi详解相关推荐

  1. 数学建模_随机森林分类模型详解Python代码

    数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...

  2. Python中下划线 _ 的最全用法详解

    Python中下划线 _ 的最全用法详解 '_'是什么? _在python中可以作为一个标识符,用于定义变量和方法唯一名称.同时它也是Python中的一个软关键字,指在某些特定上下文中保留的关键字.截 ...

  3. [转载] C++文件读写详解(ofstream,ifstream,fstream)

    [转载] C++文件读写详解(ofstream,ifstream,fstream) 注:转载文章,侵删 来源:C++文件读写详解(ofstream,ifstream,fstream) 作者:CSDN博 ...

  4. niosii spi 外部_基于Nios_II的DMA传输总结

    最近练了一段时间的DMA传输,现做如下的总结,分享自己获得心得以及遇到的一些问题. 在系统运行时,当需要传输大量数据时,可以采用DMA的方式进行传输,以解脱出CPU来处理其他命令. Nios II中的 ...

  5. NIOS II spi详解

    1.说明 本文是依据笔者阅读<Embedded Peripherals (ver 9.0, Mar 2009, 4 MB).pdf>参考文档所作的个人理解,可以看做是笔记吧. 本文只讲NI ...

  6. 18. SPI协议,spi转can,MCP2515裸机驱动详解

    更多信息请关注公众号:一口Linux 十八.SPI.MCP2515 一.SPI概述 Serial Peripheral interface 通用串行外围设备接口 是Motorola首先在其MC68HC ...

  7. spi总线 上层调用_spi总线驱动详解

    spi总线驱动详解 spi总线驱动详解 Spi总线在实际应用得比较多,所以这篇为文章讲解以实际应用为主,bus总线类型细节不做讲解,感兴趣的读者可以分析源码,研究内核源码我觉得是一件非常有趣的事情,同 ...

  8. [转载]VirtualBox网络配置详解

    标题: [原创]VirtualBox网络配置详解 来自 http://www.linuxsir.org/bbs/showthread.php?p=1800679#post1800679 欢迎转载, 转 ...

  9. sgd 参数 详解_代码笔记--PC-DARTS代码详解

    DARTS是可微分网络架构搜搜索,PC-DARTS是DARTS的拓展,通过部分通道连接的方法在网络搜索过程中减少计算时间的内存占用.接下来将会结合论文和开源代码来详细介绍PC-DARTS. 1 总体框 ...

最新文章

  1. Robot framework 二次开发笔记
  2. 两个tplink路由器有线桥接_tplink和腾达路由器有线桥接设置图解
  3. xml中的Document和Attribute
  4. 人类长非编码RNA表达数据库,整合9种重要生物学场景(发育、癌症、病毒侵染等)...
  5. Mac截图高端操作,这些技巧你绝对不知道!
  6. Dart 2-Day
  7. 学习TeXworks编辑器(一)自定义快捷键详解
  8. FireEye 红队失窃工具大揭秘之:分析复现 Confluence路径穿越漏洞 (CVE-2019-3398)
  9. Tizen已经够烂了 但份额还是超过了黑莓
  10. US1MF-ASEMI贴片薄体封装二极管US1M
  11. mysql中如何复制数据表_MySQL中快速复制数据表方法汇总
  12. file对象转换为Muti文件对象工具类
  13. 大航海懒神辅助工具全部更新完毕,祝大家航海愉快!
  14. Gson int类型被转换成double问题解决(完美解决)
  15. JSON.stringify()和JSON.parse()
  16. Apollo二次规划的应用之PWJ
  17. Win11怎么查看计算机历史记录?
  18. 正确率,精确率,召回率.
  19. Ubuntu永久修改USB设备操作权限
  20. driver failed programming external connectivity on endpoint

热门文章

  1. Java HashSet和Java HashMap
  2. JavaScript Date getTime() 方法
  3. 【算法设计与分析】将数字分解为n个数字之和
  4. 【数据结构系列】单链表
  5. JDK中文API帮助文档【沈东良】
  6. Python使用FTP上传文件
  7. edg击败we视频_2019德杯淘汰赛:EDG让二追三击败WE
  8. RC4原理以及Python实现
  9. 深圳市智汇机器人科技有限公司环宇智行
  10. 模拟web访问有登录且有验证码的登录后抓取数据