OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8037|回复: 25

求助,拿到一个新芯片,SPI通信的,一直配置不对,请问需要注意什么?SPI地址没有理解

[复制链接]

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
发表于 2019-2-15 08:38:34 | 显示全部楼层 |阅读模式
1金钱
手里买了个新的通信芯片,是SPI接口的。以前用过的SPI只有flash,便参照了一下。
有几个问题:
1、新芯片手册里有几个寄存器,寄存器地址为2个字节,我像写flash一样,“发写指令”、“发flash地址”、“发写入的内容”、“读flash数据”,这一套下来可以正常对寄存器进行读写。。。但例如写数据、读模块状态、配置模块频段等指令,但没有对应的寄存器地址,而是给了一个字节的opcode,与前面所说的 “发写指令” 所用的也是opcode。那也就是说这些配置指令都没有“地址”是吗?没有寄存器地址它是如何写入配置的呢?
2、假设就是没有地址,那只需要发一个opcode给芯片,比如gainstatu的操作码是0x81,我将它直接发给芯片后,再想去取它返回的状态值,并没法取到。现在所有取寄存器(有地址)的操作我都已经成功了,所有配置和读配置(只有opcode,没有地址)的操作我都没成功,获取不到想要的数据。请问都有什么原因呢?

3、下面是两段代码,请问后面一段为啥无法进行配置呢?那不带地址又该怎么码这代码呢?说说思路就行
这段是有地址的写数据:(这段代码可以正常写入寄存器,已测试过)
SPI_FLASH_CS_LOW();       
hw_flash_read_write_byte(0x0D);         /* 写命令的opcode        */                                          
hw_flash_read_write_byte((((Dst+i) & 0xFFFF) >> 8));   /* 2个字节的寄存器地址 */
hw_flash_read_write_byte((Dst+i) & 0xFF);
hw_flash_read_write_byte(SndbufPt[i]);        /* ·写入寄存器的内容        */                       
SPI_FLASH_CS_HIGH();       


这段是没有地址,只有opcode的写数据:(这段代码无法成功配置,已测试过)
SPI_FLASH_CS_LOW();       
hw_flash_read_write_byte(0x8F);         /* 配置缓存区        */                                          
hw_flash_read_write_byte(01);   /* 配置缓存区发指针 */
hw_flash_read_write_byte(01);        /* 配置缓存区收指针  */       
hw_flash_read_write_byte(10);        /* 配置缓存区大小  */       
SPI_FLASH_CS_HIGH();       





最佳答案

查看完整内容[请看2#楼]

手册上如果没有明确注明,那应该就是直接写opcode就可以了,我用的一个SPI模块也是分寄存器配置跟直接命令控制,寄存器配置的时候也是先写地址,直接命令时候就是直接写进去命令码。
自在随心
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 08:38:35 | 显示全部楼层
手册上如果没有明确注明,那应该就是直接写opcode就可以了,我用的一个SPI模块也是分寄存器配置跟直接命令控制,寄存器配置的时候也是先写地址,直接命令时候就是直接写进去命令码。
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 08:46:03 | 显示全部楼层
不是第一次使用SPI,但是这个片子没有例程,英文手册能看懂,但是肯定细节上没整对,我自己也不太懂SPI的原理。现在这问题不知从何下手,求帮解释解释SPI咋工作的,为啥可以没有地址,为啥我发了数据得不到返回值
另外,补充一下上面的。
读返回值Temp1是这么写的,同样是有地址的就可以成功,没地址的就读出来个a2,不知道a2是啥,手册里也没有解释,读到的所有数据都是a2,所以估计是个错误数据
        SPI_FLASH_CS_LOW();
        hw_flash_read_write_byte(0x13);
        for(i = 0;i < 2;i++)
        {
                Temp1[i]|=hw_flash_read_write_byte(0xFF);
        }
        SPI_FLASH_CS_HIGH();
自在随心
回复

使用道具 举报

41

主题

242

帖子

0

精华

高级会员

Rank: 4

积分
523
金钱
523
注册时间
2016-1-11
在线时间
132 小时
发表于 2019-2-15 08:50:57 | 显示全部楼层
你确定硬件没问题? SPI需要上拉电阻的。
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 09:00:00 | 显示全部楼层
沧海 发表于 2019-2-15 08:50
你确定硬件没问题? SPI需要上拉电阻的。

硬件上没问题,毕竟有寄存器地址的指令我都成功了,只是有些配置没有这种地址,我不知道为啥它同样是配置指令,一部分有地址,一部分没地址
自在随心
回复

使用道具 举报

33

主题

159

帖子

0

精华

高级会员

Rank: 4

积分
527
金钱
527
注册时间
2017-1-21
在线时间
192 小时
发表于 2019-2-15 09:20:57 | 显示全部楼层
SPI这个东西嘛,就是主机出一个时钟,然后在上或下沿发送或读取数据。然后这个地址是怎么回事呢,就是这个SPI的从机,他不可能只有一个寄存器,假设是8bit的数据,比如有3个嗷,地址分别是0x01,0x02,0x03,里面的数据分别是0xaa,0xbb,0xcc。
比如我要读取0x02里面的数据,往往需要分两步,(CS我就不说了),第一步主机发送0x02,告诉从机我要读0x02,这时候主机也会收到数据,因为SPI是用一个时钟全双工的,但是数据是没有意义的,可能是随意的数据。第二步,主机再发出至少8个时钟信号,这时候就能读到0x02里面的数据0xbb,为了发出时钟信号,往往就是选在主机随便发一个数据就好。
总体来说操作逻辑就是上面的,但是具体要看从机芯片的手册介绍。而且看起来上述的逻辑效率低下,但实际上就是有效数据滞后一次,读取多个寄存器时,可以做好相关的设计,其实不影响效率。
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 09:40:13 | 显示全部楼层
oyixi001 发表于 2019-2-15 09:20
SPI这个东西嘛,就是主机出一个时钟,然后在上或下沿发送或读取数据。然后这个地址是怎么回事呢,就是这个S ...

这个芯片里确实有十来个寄存器有地址,每个地址是2字节。比如读取模块IP地址号。这个已经按你上面说的读写成功了。时序我抓了一下,是对的了。

但是比如获取设备通信状态、配置和获取设备缓存区指令等,这一部分指令并没有寄存器地址。而是单单给了1个字节的opcode。
以前用W25Q25 flash芯片时, 有一个配置4字节地址模式的指令,就是单独向SPI里写一个字节,也是没有“地址”。所以我照着它,也向模块写了一个字节,但是并不能获取到返回数据,就算我确实获取到了aa  a2  等数据,但是我并不知道这个数据是个啥玩意,手册里也没有说,实际的数据应该也不是aa  a2
自在随心
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 10:09:37 | 显示全部楼层
15937417823 发表于 2019-2-15 10:01
手册上如果没有明确注明,那应该就是直接写opcode就可以了,我用的一个SPI模块也是分寄存器配置跟直接命令 ...

这样奥,我有个问题,它手册上有一条是这样的:
命令名:SetBufferBaseAddress     指令码:0x8F    参数:TxbaseAddr, RxbaseAddr
意思是这个一个设置缓存区基地址的指令,指令码是8F,其中有两个配置参数,一个是发送基地址,另一个是接收基地址。
这样的话我应该怎么写呢?(假设基地址都写0x02)


是这样吗?
SPI_FLASH_CS_LOW();   
hw_flash_read_write_byte(0x8F);
hw_flash_read_write_byte(0x02);
hw_flash_read_write_byte(0x02);
SPI_FLASH_CS_HIGH();   
自在随心
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 10:24:37 | 显示全部楼层
15937417823 发表于 2019-2-15 10:01
手册上如果没有明确注明,那应该就是直接写opcode就可以了,我用的一个SPI模块也是分寄存器配置跟直接命令 ...

兄弟,我上面写的帮我看一下呗
自在随心
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 10:36:26 | 显示全部楼层
yuzeyuan1 发表于 2019-2-15 10:09
这样奥,我有个问题,它手册上有一条是这样的:
命令名:SetBufferBaseAddress     指令码:0x8F    参 ...

我那个是直接命令,不需要在设置参数。你这样试一下
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 10:37:30 | 显示全部楼层
void  AS3993_IO_SPIWrite(const u8 *pBuff,  u8 Adress, u8 nBytes,  unsigned char  IsCmd)
{
        int i=0;
        //片选信号有效
        AS3993_SPI_SELECT;
        udelay(1);

        //输出地址
        if(IsCmd==false)
        {
                UCB1TXBUF=Adress | 0x00;
                while ((UCB1STAT & UCBUSY));
        }

        //输出数据或命令
        for(i=0; i<nBytes; i++)
        {
                UCB1TXBUF=pBuff[i];
                while ((UCB1STAT & UCBUSY));
        }

        //片选信号无效
        AS3993_SPI_DESELECT;
}
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 10:38:15 | 显示全部楼层
这个是我的写函数,命令的话给cmd false 下边写命令码就可以了
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 10:38:39 | 显示全部楼层
你可以把手册那一部分截一下发上来看下
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 10:44:36 | 显示全部楼层
这个
1.png
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 10:45:02 | 显示全部楼层
15937417823 发表于 2019-2-15 10:38
你可以把手册那一部分截一下发上来看下

看楼上
自在随心
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 10:50:01 | 显示全部楼层

后边的解释说把你设置的TX.RX基地址存到register of selected protocol modem,是不是有一个寄存器专门用来放这两个参数的,需要发完这个指令之后,然后再写寄存器地址,然后写这俩基地址啊
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 13:58:04 | 显示全部楼层
请问这个NOP是什么呢?空字节就是发任意字节吗?
2.png
自在随心
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 13:58:33 | 显示全部楼层
15937417823 发表于 2019-2-15 10:50
后边的解释说把你设置的TX.RX基地址存到register of selected protocol modem,是不是有一个寄存器专门用 ...

您再看看楼上那个呗,我不会发图片同时圈人。。
自在随心
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 14:40:24 | 显示全部楼层
yuzeyuan1 发表于 2019-2-15 13:58
您再看看楼上那个呗,我不会发图片同时圈人。。

之前说的那个可以了吗?你试一下就发一个13,不行就跟三个00,我也不是很清楚
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-15 14:58:14 | 显示全部楼层
15937417823 发表于 2019-2-15 14:40
之前说的那个可以了吗?你试一下就发一个13,不行就跟三个00,我也不是很清楚

我自己又试了几个不带参数的,已经成功了。就是直接发一个字节的指令码,再发一个字节的数据。
之前说那个就是这种带参数的,暂时不行,虽然有数据,但是我还是不知道它的数据是啥意思,现在感觉是我的指令有问题,我再试试。
自在随心
回复

使用道具 举报

8

主题

182

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2017-3-8
在线时间
114 小时
发表于 2019-2-15 15:27:15 | 显示全部楼层
yuzeyuan1 发表于 2019-2-15 14:58
我自己又试了几个不带参数的,已经成功了。就是直接发一个字节的指令码,再发一个字节的数据。
之前说那 ...

对着文档多试几次
回复

使用道具 举报

1

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1183
金钱
1183
注册时间
2015-5-28
在线时间
149 小时
发表于 2019-2-15 16:47:53 | 显示全部楼层
难道芯片厂家的SDK里面没有example project吗?。。
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-18 08:13:29 | 显示全部楼层
小陀螺爱炒蛋 发表于 2019-2-15 16:47
难道芯片厂家的SDK里面没有example project吗?。。

就是没有额。。。,周末有点儿忙没整,这两天再试试,已经有眉目了
自在随心
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-2-18 08:30:35 | 显示全部楼层
SPI有四个不同的Mode(比如写是上升沿还是下降沿触发), 在时序图里能找到, 先确定这一点吧
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2778
金钱
2778
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2019-2-20 14:43:04 | 显示全部楼层
搞定了,不带地址的指令都是直接写命令码,再直接接配置参数的。
自在随心
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2020-6-9
在线时间
4 小时
发表于 2020-11-15 15:29:23 | 显示全部楼层
yuzeyuan1 发表于 2019-2-20 14:43
搞定了,不带地址的指令都是直接写命令码,再直接接配置参数的。

你好,我也在调试这个,能请教下吗?opcode 后面带参数的函数是怎么写的?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 13:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表