OpenEdv-开源电子网

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

我要使用SPI接口从ATT7022E中读取指定的寄存器,为什么总会延迟四个字节?

[复制链接]

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
发表于 2015-5-21 21:25:00 | 显示全部楼层 |阅读模式
5金钱

买了原子的F4的开发板,照着原子哥的例程写了个SPI通讯程序驱动ATT7022E,SPI初始化和端口设置应该是正常的,但现在问题是每次读寄存值,总是在下一次操作是才能读到上一次要的结果,这个程序该怎么写才正确?

ATT7022E是先发送1个8位的操作数,等2US左右再读写24位数据,问题是:SPI是全双工的,在发送的同时就接收数据,我如果先发8位指令,再接收,结果就会丢失高8位,如下面程序

u32 SPI_ATT_Read(u8 data)
 {
  u32 temp=0;
 ATT7022E_CS=0;

 SPI1_ReadWriteByte(data);

 delay_us(5);

 temp=SPI1_ReadWriteByte(data);
 temp<<=8;
 temp|=SPI1_ReadWriteByte(data);
 temp<<=8;
 temp|=SPI1_ReadWriteByte(data);
 ATT7022E_CS=1;
 return (temp);
  }
如果发送同时接收,可以正常收到24位返回值,但是问题是每次发的指令,该指令对应的返回值要在下一次读的时候才能正确读出来,如下面的程序

u32 SPI_ATT_Read(u8 data)
 {
  u32 temp=0;
 ATT7022E_CS=0;

 temp=SPI1_ReadWriteByte(data);
 temp<<=8;
 temp|=SPI1_ReadWriteByte(data);
 temp<<=8;
 temp|=SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(data); 

ATT7022E_CS=1;
 return (temp);
  }
我才学ARM不久,有点糊了,按ATT7022E的手册应该第一个程序是对的,但实际运行结果是高8位丢失,后面的程序是,每个读操作要第二次读才能读出上次发的操作数对应的结果。这个问题搞了两天了,没搞定,请各位高手帮帮我。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2015-5-21 22:36:19 | 显示全部楼层
这个挺正常的吧,你发指令以后,肯定要等待一段时间,才能读出指令的返回值。
难不成你一边发指令,还能一边收指令的返回值?
除非对方提前知道你要发送的指令,否则怎么可能一边接受指令,一边给你指令的应答?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
 楼主| 发表于 2015-5-21 23:00:15 | 显示全部楼层
谢谢原子哥,这么快就有回复,我也是这样理解的,发指令后等一段时间就应该能读出指令的返回值,但实际上,如果延时一段时间读返回值就会把返回值(共24位)的最前面8位丢失(如第一个程序所示)。
我后来把读程序改成下面的,就是先发四次读指令,再读返回值,发现这样每次都可以正确的读出返回值,但写数据程序不知道怎么改才行。
u32 SPI_ATT_Read(u8 data)
 {
  u32 temp=0;
 ATT7022E_CS=0;
SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(data);
 //    delay_us(10);
temp=SPI1_ReadWriteByte(data);
temp<<=8;
temp|=SPI1_ReadWriteByte(data);
temp<<=8;
temp|=SPI1_ReadWriteByte(data);
SPI1_ReadWriteByte(data);
ATT7022E_CS=1;
return (temp);
 
 }
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
 楼主| 发表于 2015-5-21 23:04:28 | 显示全部楼层
这个ATT7022E的时序真的好麻烦,为读一个寄存器都搞了两天了,到现在还是不能写校表寄存器,不知道问题出哪儿。

void SPI_ATT_Write(u8 com_add,u32 data2)
 {
   u8 data_h,data_m,data_l;
ATT7022E_CS=0;
data_l=data2&0xff;
data_m=(data2>>8)&0xff;
data_h=(data2>>16)&0xff;
SPI1_ReadWriteByte(com_add);
SPI1_ReadWriteByte(data_h);
SPI1_ReadWriteByte(data_m);
SPI1_ReadWriteByte(data_l);
 ATT7022E_CS=1;
 }

按手册理解,程序应该没有问题,可就是写不进去数据。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2015-5-21 23:34:11 | 显示全部楼层
回复【4楼】chenrj:
---------------------------------
看数据手册吧,上面应该有时序
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
 楼主| 发表于 2015-5-22 08:33:27 | 显示全部楼层

今天为排除UCOSII可能造成的影响,单独写了一个裸机程序,结果和上面的测试一样,证明问题不是由UCOS引起的,原子哥说看数据手册,关键是手册都不知道看了多少遍了,按手册上的例程,用IO摸拟SPI,结果更离奇,每次读的值都不一样。

回复

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4471
金钱
4471
注册时间
2013-4-22
在线时间
335 小时
发表于 2015-5-22 09:26:44 | 显示全部楼层
有酬劳的话,我可以帮你全部搞定!!
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
 楼主| 发表于 2015-5-22 10:07:13 | 显示全部楼层
差不多找到问题所在了,今天用示波器看信号,发现没有片选信号,因为程序中把片选PA4和SPI管脚同时初始化为复用功能,后来把片选管脚单独初始化为输出,片选信号即正常了,这时第一个程序可以读出返回数,但返回值缺最后一位,示波器看信号,发现MISO信号的最后一个边缘非常缓,看来要检查硬件了。
但我还是有点奇怪,没有片选信号,居然也可以读出SPI信号的返回值?也就是ATT7022E不给片选,只要先连发4个读指令,第5个读指令后也可以返回正确的值,这是什么道理?
回复

使用道具 举报

3

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
78
金钱
78
注册时间
2015-5-21
在线时间
14 小时
 楼主| 发表于 2015-5-22 10:10:52 | 显示全部楼层
谢谢6楼兄弟,这个项目是一个合作项目,我只负责硬件设计,软件另有其人,因为要测试硬件有无问题,才自己写程序读写SPI的,发现问题并解决问题的过程是一个学习的过程,我自己应该能搞定这个问题。
回复

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
81
金钱
81
注册时间
2015-3-9
在线时间
1 小时
发表于 2015-6-12 17:21:03 | 显示全部楼层
回复【9楼】chenrj:
---------------------------------
我是新手,临时学spi。楼主 可以把你的测试测试程序发给我研究下吗 最近我也在学spi去读att7026e,先在这谢谢了。我的邮箱1343114655@qq.com
学无止境
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2014-10-6
在线时间
0 小时
发表于 2015-10-30 18:15:15 | 显示全部楼层
你好,我现在用7026E,每次读寄存器都是0。不知道什么问题。请问你有这个初始化程序么?7022e的也行,做参考。不甚感激。
回复

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
45
金钱
45
注册时间
2015-8-3
在线时间
4 小时
发表于 2015-12-10 11:50:03 | 显示全部楼层
回复【11楼】masosam:
---------------------------------
我也遇到同样的问题 请问你解决没有 QQ595055967
回复

使用道具 举报

20

主题

297

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1830
金钱
1830
注册时间
2013-7-29
在线时间
276 小时
发表于 2015-12-10 23:15:32 | 显示全部楼层
我在一次的回帖里把我程序都给出来了,你们可以搜下。
回复

使用道具 举报

2

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2014-8-13
在线时间
13 小时
发表于 2016-4-12 15:10:42 | 显示全部楼层
xuyan021 发表于 2015-12-10 23:15
我在一次的回帖里把我程序都给出来了,你们可以搜下。

我也遇到读出来的值是0的情况,可以商讨一下么。
回复

使用道具 举报

20

主题

297

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1830
金钱
1830
注册时间
2013-7-29
在线时间
276 小时
发表于 2016-4-13 08:50:26 | 显示全部楼层
可以。你先看下我程序再说吧,其实没有什么,就是在保证硬件电路正确的情况下再确保软件设置正确。
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3765
金钱
3765
注册时间
2015-4-26
在线时间
762 小时
发表于 2016-4-13 17:48:29 来自手机 | 显示全部楼层
标记
回复

使用道具 举报

4

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2015-11-14
在线时间
42 小时
发表于 2016-4-25 15:06:48 | 显示全部楼层
夜神荣 发表于 2016-4-12 15:10
我也遇到读出来的值是0的情况,可以商讨一下么。

请问14楼,你的电压、电流数据读出来没有?
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
发表于 2016-5-12 14:07:03 | 显示全部楼层
[mw_shl_code=applescript,true]您好,程序能给我参考参考吗?1179083830@qq.com[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
发表于 2016-5-12 17:02:18 | 显示全部楼层
chenrj 发表于 2015-5-22 08:33
今天为排除UCOSII可能造成的影响,单独写了一个裸机程序,结果和上面的测试一样,证明问题不是由UCOS引 ...
  1. 大哥,我做ATT7022的项目也遇到很多问题了,希望大哥能教一下我,,QQ:1179083830,我弄了一周了,也没有什么进展,现在连跟ATT7022芯片还没有通讯上,谢谢啦,,
复制代码
回复

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
60
金钱
60
注册时间
2012-10-22
在线时间
18 小时
发表于 2016-6-20 09:35:47 | 显示全部楼层
楼主问题解决没 ,我现在也在用ATT7022EU做项目。mcu用的是VBT6,现在SPI通讯正常,我怀疑是你SPI的极性设置的问题。SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                //串行同步时钟的空闲状态为低电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        //串行同步时钟的第二个跳变沿(上升或下降)数据被采样unsigned long  ATT7022read(u8 addres)
   {

                 unsigned long temp,temp1,temp2,temp3;
         ATT7022E_CS=1;
         delay_us(2);
             ATT7022E_CS=0;
             SPI1_ReadWriteByte( addres);
             delay_us(2);
             temp1=SPI1_ReadWriteByte( 0xff);
             temp2=SPI1_ReadWriteByte( 0xff);
         temp3=SPI1_ReadWriteByte( 0xff);
         temp=(temp1<<16)|(temp2<<8)|temp3;
             ATT7022E_CS=1;          
             return temp;
   }

void   ATT7022write(u8 addres,unsigned long data)
   {
          
          
             u8  temp1,temp2,temp3;
         ATT7022E_CS=1;
         delay_us(2);
             ATT7022E_CS=0;
             SPI1_ReadWriteByte( addres);
             delay_us(2);
             temp1=(u8)(data>>16);
             temp2=(u8)(data>>8);
             temp3=(u8)(data);
             SPI1_ReadWriteByte( temp1);
             SPI1_ReadWriteByte(temp2);
         SPI1_ReadWriteByte( temp3);      
             ATT7022E_CS=1;  
       
               }
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2016-7-14
在线时间
2 小时
发表于 2016-7-18 22:06:52 | 显示全部楼层
gb8931156 发表于 2016-6-20 09:35
楼主问题解决没 ,我现在也在用ATT7022EU做项目。mcu用的是VBT6,现在SPI通讯正常,我怀疑是你SPI的极性设置 ...

给位大哥,帮帮忙啊,谁能提供一份校表C程序做参考呀,ADC-offset,有效值offset,有效值增益,功率,功率因数,等等,一个也没整出来。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-27 21:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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