首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

请教NiosII中 SPI的问题

请教NiosII中 SPI的问题

请问各位有没有做过NiosII CPU中的SPI测试程序,我在Nios里配置了一个8位的主SPI,另外有一个VerilogHDL写的从SPI接口的控制模块,控制模块从AD采集数据,然后通过SPI传给Nios。接口部分经过验证是没有问题的。写了如下测试程序,但是写进去和读出来的不一样,是不是我这程序写得有问题。麻烦指点,谢谢!

#include "alt_types.h"
#include "altera_avalon_spi_regs.h"
#include "altera_avalon_pio_regs.h"
#include "system.h"

alt_u8 tx_buf1[6]={0x40,0x0d,0x08,0x08,0x08,0x08};

//tx_buf1前两个字节0x400d组成地址,实际有效的只有0~10位,第14位为1则标志是写寄存器,接下来发送的0x08080808写进内部寄存器。调用alt_avalon_spi_command()函数时将0x08080808写进地址为0xd的内部寄存器(32位的)。

alt_u8 tx_buf2[2]={0x00,0x0d};

//tx_buf2前两个字节0x000d组成地址,从SPI接收到后根据第14位为0判断为读操作,把地址为0xd的内部寄存器的值输出,调用第2个alt_avalon_spi_command()函数时讲值读出并存入rx_buf。


unsigned char rx_buf[4];//接收数组
int main()
{

const alt_u8 *wdata=tx_buf1;
alt_u8 * read_data;
read_data=rx_buf;
alt_avalon_spi_command(SPI_MASTER8_BASE,0,6,wdata,0,read_data,0x0);
wdata=tx_buf2;
alt_avalon_spi_command(SPI_MASTER8_BASE,0,2,wdata,4,read_data,0x0);
if(rx_buf[0]==0x8) //判断读出来的跟写进去的是否一致
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0x1);
else
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0x2);
return 0;
}

spi在nios上我没有使用过,但是spi我还是比较熟悉的。

楼主可以看看这种在alvaon总线上的spi控制器的地址分配情况,楼主可以看看nios中的spi的控制器说明。当然如果哪位网友有实践应验当然更好了。

这个版主不太冷 =========================== 我的中电网博客:http://blog.chinaecnet.com/u/20/index.htm

谢谢斑竹。
控制模块中的从SPI的接口Verilog代码我看过了,就是在时钟的上升沿从SDI(跟NiosII中的MOSI连接)读入数据,在时钟的下降沿从SDO(与MISO连接)输出数据,而根据接收到的前2个字节判断是写还是读。Nios中关于SPI核的讲解也就是一些关于数据寄存器,status,control,slaveselect寄存器的说明。也试过通过读写控制寄存器来操作,但是感觉也不好控制。所以就用了Altera提供的子程序alt_avalon_spi_command(),它里面是对寄存器的操作,采用查询status寄存器的方式。有些东西也没看明白。比如最后一个参数 flags是干吗的?


我试试用类似串口的接收发送中断来做,做了再来汇报。
多谢指点!

下面是我中断方式做的

#include "system.h"
#include "altera_avalon_spi_regs.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "stdio.h"

alt_u8 tx_buf[8]={0x40,0x0d,0x08,0x08,0x08,0x08,0x40,0x00};
//alt_u8 tx_buf2[2]={0x00,0x0d};
alt_u8 rx_buf[4];

alt_u8 tx_index=0;
alt_u8 rx_index=0;
alt_u8 end_flag=0;
void spi_init();
void handle_spi_interrupt();
int main()
{
spi_init();
while(1)
{
if(end_flag==0x1)
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE,0x3);
else
IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE,0x0);
}
return 0;
}
void spi_init()
{
alt_irq_register(SPI_MASTER8_IRQ,NULL,handle_spi_interrupt);
IOWR_ALTERA_AVALON_SPI_SLAVE_SEL(SPI_MASTER8_BASE,0x1);
IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_MASTER8_BASE,0xc0);
IOWR_ALTERA_AVALON_SPI_STATUS(SPI_MASTER8_BASE,0x0);
}
void handle_spi_interrupt(void *context,unsigned long id)
{
alt_u16 status,control;
status=IORD_ALTERA_AVALON_SPI_STATUS(SPI_MASTER8_BASE);
control=IORD_ALTERA_AVALON_SPI_CONTROL(SPI_MASTER8_BASE);

if(status&0x0040!=0)
{
IOWR_ALTERA_AVALON_SPI_TXDATA(SPI_MASTER8_BASE,tx_buf[tx_index++]);
if(tx_index>=8)
IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_MASTER8_BASE,control&0xffbf);
}

if(status&0x0080!=0)
{
control=IORD_ALTERA_AVALON_SPI_CONTROL(SPI_MASTER8_BASE);
rx_buf[rx_index]=IORD_ALTERA_AVALON_SPI_RXDATA(SPI_MASTER8_BASE);
if(rx_index>=4)
IOWR_ALTERA_AVALON_SPI_CONTROL(SPI_MASTER8_BASE,control&0xff7f);
}

if((tx_index>=8)&&(rx_index>=4))
end_flag=0x1;
}

直接编译运行结果表明tx_index和rx_index都没增加到期望的8和4,明天去调试看看。。

呵呵,做一下实验调一下就知道了,楼主也可以用逻辑分析仪打一下nios的spi控制器时序有没有和设计的一致。
这个版主不太冷 =========================== 我的中电网博客:http://blog.chinaecnet.com/u/20/index.htm

为什么会这样,我用逻辑分析仪抓出的Nios中的SPI核的时钟输出居然一直是0,采样时钟是系统时钟50M,SPI的时钟配置成128K,按道理是50M/128k~=391个点就有一次反相啊,但是STP文件运行后的波形显示一直是0。没有示波器,郁闷

难道真的是IP有问题,反复测试发现时钟还是没信号。

我觉得ip有问题的可能性比较小,有可能是对其控制器的配置问题,比如还需用对某个寄存器作初始化等等,楼主可以到www.opencores.org上下一个spi的ip,上面的ip好像是基于wisebone总线的,也有ahb总线的,对于测试你的ip有帮助。
这个版主不太冷 =========================== 我的中电网博客:http://blog.chinaecnet.com/u/20/index.htm

谢谢caopengly斑竹,如果说时钟也需要启动的话那只可能是从设备选择信号,但是写slaveselect寄存器也没反映,输出信号一直为高。RXDATA,TXDATA,status,control寄存器跟时钟一点关系都没有啊

sclk和ss_n只是在将移位寄存器中的数据移出的时候才有效

返回列表