nios自带spi核如何编程
想用魏坤的第二版示波器做一个SPI读写SD卡用MICROCHIP GUI显示(MICROCHIP GUI已经好了),但是NIOS的SPI核,一直用不上,找了很多的资料(包括NIOS的软件文档)一直用不上,哪位朋友有写过SPI的程序吗?发出来参考一下 同问,我也想知道答案 先定义一个结构体typedef struct{
volatile unsigned long int RXDATA;
volatile unsigned long int TXDATA;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int ROE :1;
volatile unsigned long int TOE :1;
volatile unsigned long int TMT :1;
volatile unsigned long int TRDY :1;
volatile unsigned long int RRDY :1;
volatile unsigned long int E :1;
volatile unsigned long int NC1 :23;
}BITS;
volatile unsigned long int WORD;
}STATUS;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int IROE :1;
volatile unsigned long int ITOE :1;
volatile unsigned long int NC1 :1;
volatile unsigned long int ITRDY :1;
volatile unsigned long int IRRDY :1;
volatile unsigned long int IE :1;
volatile unsigned long int NC2 :1;
volatile unsigned long int SSO :21;
}BITS;
volatile unsigned long int CONTROL;
}CONTROL;
unsigned long int RESERVED0;
unsigned long int SLAVE_SELECT;
}SPI_ADC_T;
#define SPI_ADC ((SPI_ADC_T *) SPI_ADC_BASE)//SPI_ADC_BASE是在system.h里产生的地址
这个就是利用nios的spi接口的adc,下面是例程
unsigned int read_adc(void)
{
SPI_ADC->TXDATA=0;
while(!(SPI_LAN->STATUS.BITS.TMT));
return SPI_ADC->RXDATA;
}
很简单吧 回复【2楼】avic
-----------------------------------------------------------------------
楼上的位域用的出神入化。学习了。
个人感觉,有时候需要多看看手册。手册上讲得很清楚。
点击此处下载 ourdev_538101.pdf(文件大小:1.01M) (原文件名:SPI CORE.pdf) 回复【3楼】tear086 .COM缺氧
-----------------------------------------------------------------------
说的有道理,更重要的是能够利用手册来实现程序的编写,好像是废话啊,呵呵 mark 回复【3楼】tear086.COM缺氧
-----------------------------------------------------------------------
不是没看过手册,看了之后没感觉,而且到网找了很多的资料, 就是出不来。可能是NIOS的操作还不太会吧 回复【6楼】ep1c3
-----------------------------------------------------------------------
借ZLG的代码花献佛。
/********************************************************************
* 文 件 名:spi_test.c
* 功 能:用alt_avalon_spi_command()函数来发送数据。
* 说 明:用LA1032逻辑分析仪测试数据。
********************************************************************/
#include "system.h" //system.h文件中提供了基本的硬件信息
#include "altera_avalon_spi_regs.h"//定义了SPI寄存器的基本信息
#include "altera_avalon_spi.h" //提供了访问SPI的函数声明
#include "alt_types.h" //Altera自定义的一些数据类型
#define BUFFER_SIZE255
int main()
{
alt_u8 Writebuf;
alt_u8 ReadBuf;
int i;
int cnt = 500;
for (i=0; i<BUFFER_SIZE; i++)
{
Writebuf = (alt_u8)i+1;//初始化准备发送的数据
}
while(1)
{
alt_avalon_spi_command(SPI_BASE, 0,
100, Writebuf,
0, ReadBuf,
0);
while(cnt--);
cnt = 500;
}
return 0;
}
点击此处下载 ourdev_538229.pdf(文件大小:442K) (原文件名:SPI操作及逻辑分析仪实验.pdf) 回复【6楼】ep1c3
-----------------------------------------------------------------------
其实NIOS的操作跟单片机,arm是一样的,都是对地址进行操作,不同之处就是,单片机,arm的地址寄存器都在头文件给出了 ,而NIOS的地址是通过system.h给出的,并且只给出了没个功能的首地址,这样就需要我们自己写一个结构体,将所有的寄存器地址展示出来,例如SPI的寄存器结构体就是下面这样的
typedef struct{
volatile unsigned long int RXDATA;
volatile unsigned long int TXDATA;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int ROE :1;
volatile unsigned long int TOE :1;
volatile unsigned long int TMT :1;
volatile unsigned long int TRDY :1;
volatile unsigned long int RRDY :1;
volatile unsigned long int E :1;
volatile unsigned long int NC1 :23;
}BITS;
volatile unsigned long int WORD;
}STATUS;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int IROE :1;
volatile unsigned long int ITOE :1;
volatile unsigned long int NC1 :1;
volatile unsigned long int ITRDY :1;
volatile unsigned long int IRRDY :1;
volatile unsigned long int IE :1;
volatile unsigned long int NC2 :1;
volatile unsigned long int SSO :21;
}BITS;
volatile unsigned long int CONTROL;
}CONTROL;
unsigned long int RESERVED0;
unsigned long int SLAVE_SELECT;
}SPI;
而这个结构体的写法就是根据手册上的寄存器地址顺序写的。
不建议大家用Nios自己带的库函数,那样的效率不但不高,也找不到像单片机那样的编程方式,简洁明了。
更重要一点就是不灵活,不能按照自己的想法来处理函数。 回复【2楼】avic
先定义一个结构体
typedef struct{
volatile unsigned long int RXDATA;
volatile unsigned long int TXDATA;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int ROE :1;
volatile unsigned long int TOE :1;
volatile unsigned long int TMT :1;
volatile unsigned long int TRDY :1; ......
-----------------------------------------------------------------------
这是很常用的寄存器分配方式,一般在头文件中很常见 回复【10楼】avic
-----------------------------------------------------------------------
学习了。我对NIOS里面的地址对齐方式还没有深入研究,不敢不用Altera给的api呀。 回复【11楼】tear086 .COM缺氧
回复【10楼】avic
-----------------------------------------------------------------------
学习了。我对NIOS里面的地址对齐方式还没有深入研究,不敢不用Altera给的api呀。
-----------------------------------------------------------------------
大家可以一起交流,共同进步啊,在论坛里面就是这个目的,真的非常感谢阿莫给我们提供这么好的一个平台,谢谢ourdev,呵呵 MARK mark, thanks everyone 谢谢 tear086 .COM缺氧avic,弄一下SD卡+显示 回复【2楼】avic
-----------------------------------------------------------------------
这个程序可以用吗?
用你提供的结构体,写了个测试程序,在MODELSIM里,MOSI和CLK变换一直为低
测试程序如下:
int alt_main()
{
int i;
ALTERA_AVALON_SPI_INIT(SPI_BASE, 0);
while (1)
{
SPI_SD->TXDATA = i;
while(!(SPI_SD->STATUS.BITS.TMT));
i++;
}
}
http://cache.amobbs.com/bbs_upload782111/files_27/ourdev_538675.JPG
(原文件名:未命名.JPG) 回复【2楼】avic
-----------------------------------------------------------------------
一看了不起,再看很佩服。 回复【16楼】ep1c3
-----------------------------------------------------------------------
程序一定好用的,我在板子上测试过的。我没有仿真过这个程序,我也不知道是怎么回事啊 回复【楼主位】ep1c3
-----------------------------------------------------------------------
请问 能吧NIOS读SD卡的 程序发出来参考一下么
///////////////////////////////////////////////////
// SPI 测试
///////////////////////////////////////////////////
#include "system.h"
#include "altera_avalon_spi_regs.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
int main(void) __attribute__ ((weak, alias("alt_main")));
int alt_main(void)
{
alt_u16 data=0x1234;
alt_u16 i;
// ss_1 为片选
IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(spi_BASE, 1);
// spi 主模式
IOWR_ALTERA_AVALON_SPI_CONTROL(spi_BASE, 0x0400); //控制寄存器
while (1)
{
IOWR_ALTERA_AVALON_SPI_TXDATA(spi_base , data);
while (!(IORD_ALTERA_AVALON_SPI_STATUS(spi_BASE) & ALTERA_AVALON_SPI_STATUS_TRDY_MSK));
for (i=0;i<60000;i++);
}
}
这是 一位师兄 编的SPI 二楼的做法很值得大家借鉴啊,其实使用一个指针完成地址映射(从软件指针一一映射到硬件寄存器),这样可以通过SPI_ADC ((SPI_ADC_T *) SPI_ADC_BASE操作每一位硬件寄存器,。不过这样有一个问题,当真正使用的寄存器不多时,所有的寄存器都得写上,因为寄存器是顺序排列的,只要少一个,就会出大麻烦,所以在小型工程中不建议这样使用。使用系统提供的API有助于减小代码的规模,所以在小工程中API是不错的选择。当然大工程中为了排查的需要映射寄存器的做法是非常值得借鉴的。就是这样 mark 其实在一定规模的项目上 按顺序多排几个 寄存器映射也没什么,还可以防止出错 回复【2楼】avic
-----------------------------------------------------------------------
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "altera_avalon_spi_regs.h"//定义了SPI寄存器的基本信息
#include "altera_avalon_spi.h" //提供了访问SPI的函数声明
#include "alt_types.h" //Altera自定义的一些数据类型
#include "stdio.h"
//#include "altera_avalon_pio_regs.h"
#include "unistd.h"
typedef struct{
volatile unsigned long int RXDATA;
volatile unsigned long int TXDATA;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int ROE :1;
volatile unsigned long int TOE :1;
volatile unsigned long int TMT :1;
volatile unsigned long int TRDY :1;
volatile unsigned long int RRDY :1;
volatile unsigned long int E :1;
volatile unsigned long int NC1 :23;
}BITS;
volatile unsigned long int WORD;
}STATUS;
union{
struct{
volatile unsigned long int NC :3;
volatile unsigned long int IROE :1;
volatile unsigned long int ITOE :1;
volatile unsigned long int NC1 :1;
volatile unsigned long int ITRDY :1;
volatile unsigned long int IRRDY :1;
volatile unsigned long int IE :1;
volatile unsigned long int NC2 :1;
volatile unsigned long int SSO :21;
}BITS;
volatile unsigned long int CONTROL;
}CONTROL;
unsigned long int RESERVED0;
unsigned long int SLAVE_SELECT;
}SPI_ADC_T;
#define SPI_ADC ((SPI_ADC_T *) SPI_0_BASE)//SPI_ADC_BASE是在system.h里产生的地址
int main (void)
{
//alt_u8 led = 0x2;
//alt_u8 dir = 0;
unsigned int i=0;
/*
* Infinitly shift a variable with one bit set back and forth, and write
* it to the LED PIO.Software loop provides delay element.
*/
while (1)
{
SPI_ADC->TXDATA=i;
while(!(SPI_ADC->STATUS.BITS.TMT));
i=i+1;
if(i>0xfff) i=0;
}
return 0;
}
我也试了下,跟16楼一样,没结果啊!这是为什么? mark 回复【1楼】wuyongqing1960
-----------------------------------------------------------------------
支持顶 自带的不是很好用,但很完整,如果要求高速的话,就要自己写一个。 tear086 发表于 2010-3-14 07:11 static/image/common/back.gif
回复【6楼】ep1c3
-----------------------------------------------------------------------
太好了我也在写SPI 的程序 求交流QQ:1520168691 lov9210 发表于 2012-6-5 22:22 static/image/common/back.gif
太好了我也在写SPI 的程序 求交流QQ:1520168691
想问下您有关SPI的事,可加不成你的QQ。。 麻烦问下你成功了吗? avic 发表于 2010-3-12 22:44 static/image/common/back.gif
先定义一个结构体
typedef struct{
我也是那样子弄得不行啊
wuliaoswz 发表于 2013-3-12 18:17 static/image/common/back.gif
想问下您有关SPI的事,可加不成你的QQ。。
不好意思啊!你的QQ是多少呢? 我是用xilinx的Microblaze控制做的,是用的IO模拟spi的时序。现在我想把flash挂在总线上,但是也只是给了一个首地址。那flash的信号线(地址线,数据线,信号线)要用结构体自己定义么? 水印。。。
页:
[1]