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. niosii spi 外部_转载:NIOS II spi详解

    NIOS II spi详解 1.说明 本文是依据笔者阅读<Embedded Peripherals (ver 9.0, Mar 2009, 4 MB).pdf>参考文档所作的个人理解,可以 ...

  2. 【学习笔记】线段树详解(全)

    [学习笔记]线段树详解(全) 和三个同学一起搞了接近两个月的线段树,头都要炸了T_T,趁心态尚未凉之前赶快把东西记下来... [目录] [基础]作者:\((Silent\)_\(EAG)\) [懒标记 ...

  3. [原创]Saltstack学习笔记:命令参数详解以及配置文件说明

    很久没有更新saltstack的文章了,今天还是来更新一点,又开始对saltstack复习了一下. 前边写了一点<saltstack入门概述(1)>以及<Saltstack如何安装( ...

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

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

  5. 爬虫笔记:Requests库详解

    什么是Requests 之前讲解了爬虫笔记:Urllib库详解发现确实有不方便的地方,比如加一个代理,cookie,发送post请求比较繁琐. Request库能用几句话实现这些. Requests ...

  6. java 检查bytebuf长度_Java学习笔记16-Netty缓冲区ByteBuf详解

    Java学习笔记16-Netty缓冲区ByteBuf详解 Netty自己的ByteBuf ByteBuf是为解决ByteBuffer的问题和满足网络应用程序开发人员的日常需求而设计的. JDK Byt ...

  7. spring学习笔记03-spring-DI-依赖注入详解(通过xml配置文件来配置依赖注入)

    spring学习笔记03-spring-DI-依赖注入详解 1.概念 2.构造函数注入 3.set方法注入 4.集合的注入 需要被注入的实体对象 package com.itheima.service ...

  8. 范里安中级微观经济学(第9版)分析笔记和课后习题答案解析-完整版 范里安《微观经济学:现代观点》(第9版)笔记和课后习题详解!

    范里安中级微观经济学(第9版)分析笔记和课后习题答案解析-完整版  摘自硕达学习网 范里安<微观经济学:现代观点>(第9版)笔记和课后习题详解! 最新电子书(题库) 范里安微观经济学现代观 ...

  9. Henry前端笔记之 Date对象详解

    Henry前端笔记之 Date对象详解 Date 对象 1 时间格式简介 2 Date.now 与 new Date().getTime() 的区别 3 Date对象详解 普通函数的用法 构造函数的用 ...

  10. 北航数据结构与c语言2017答案,2022年北京航空航天大学991数据结构与C语言程序设计考研资料汇总:参考书目-历年考研真题-模拟题库-笔记和课后习题详解...

    北京航空航天大学软件学院官网网址: 991数据结构与C语言程序设计考研参考书目: 谭浩强<C程序设计>(第4版)笔记和课后习题详解 谭浩强<C程序设计>(第4版)精讲班[教材精 ...

最新文章

  1. AI产品经理的定义和分类
  2. K-Means 及 K-Means++
  3. 大家来说说咱们IT人订阅什么周刊和月刊比较好
  4. dex2oat 加载多次
  5. 「镁客·请讲」快仓杨威:赋予仓库灵魂,让智能仓库系统自我进化和迭代
  6. 移除button点击时的黑边
  7. python comprehension_python list comprehension在一次迭代中产生两个值
  8. MySQL-8.0 | 数据字典最强解读
  9. 多少人受够了机器学习的锤,却连个决策树都说不出!
  10. linux 重启mysql_Grafana+Prometheus 监控 MySql服务
  11. 多智能体强化学习MAPPO源代码解读
  12. testbench实例 vhdl_VHDL TestBench基础(转)
  13. 最优化理论与凸优化到底是干嘛的?
  14. 关于机器学习模型的评估方法
  15. vue项目中如何解决跨域问题
  16. 二进制计算机代码,二进制代码是什么???
  17. SQL数据库的存错过程中output用法
  18. C语言简易程序设计————11、打印楼梯与笑脸
  19. poi-tl导出word复杂表格(单元格合并,生成复杂表格)
  20. 【Apollo 6.0算法解析】Apollo EM Planner

热门文章

  1. 分布式系统中的CAP理论
  2. bat运行Java程序
  3. 数值分析(7):函数逼近
  4. 【Matlab】矩阵
  5. 怎样用计算机算出别人的出生日期,Excel根据出生日期计算年龄的步骤
  6. e的ax次方怎么求导
  7. 7-1 打印倒直角三角形图形 (20 分)
  8. visio画直线箭头
  9. opnelayers 基于ImageCanvas,简单云层图
  10. php网站后台修改主页,织梦网站后台主页页面修改