OpenEdv-开源电子网

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

ATT7022EU SPI读取到的数据都是00,而且写不进数据!!!!!急急急!!跪求大神,

[复制链接]

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
发表于 2016-5-11 11:57:41 | 显示全部楼层 |阅读模式
5金钱
本帖最后由 黄洪文 于 2016-5-12 11:22 编辑

看 #include <stm32f10x.h>
#include "ATT7022.h"
#include "delay.h"
/******************
测量的数据:
交流切入状态
1路A/B/C/相电压、   
1路A/B/C/相频率、
1路A/B/C/相电流、
1路A/B/C/相视在功率、
1路A/B/C/相有功功率、
1路A/B/C/相无功功率、
2路A/B/C/相电压、
2路A/B/C/相频率、
2路A/B/C/相电流、
2路A/B/C/相视在功率、
2路A/B/C/相有功功率、
2路A/B/C/相无功功率、
*******************/
void CD4053_Choose0(void);//C/B/A均为0,2(VB2)、3(VC1)、13(VA1)输出
void CD4053_Choose7(void);//C/B/A均为1,1(VB1)、5(VC2)、12(VA2)输出
u8 AC_Cut_State(void);//交流切入状态
void SPI2_WriteByte(u8 TxData);//TxData:要写入的字节
void SPI_Write(u8 Reg_Adrr,u32 Data);//ATT7022_SPI写操作
// void Read_ATT_AData(void);        //读取A相寄存器数据
// void Read_ATT_BData(void);        //读取B相寄存器数据
// void Read_ATT_CData(void);        //读取C相寄存器数据
// float Read_Freq(u8 Freq_addr);//读取线频率
// u8 Read_StateFlag(u8 EMUState_addr);//读取状态标志
#define r_Pa 0x01                 //有功功率寄存器地址
#define r_Pb 0x02
#define r_Pc 0x03
#define r_Qa 0x05                        //无功功率寄存器地址
#define r_Qb 0x06
#define r_Qc 0x07
#define r_Sa 0x09                        //视在功率地址
#define r_Sb 0x0A
#define r_Sc 0x0B
#define r_UaRms 0x29        //电压有效寄存器地址
#define r_UbRms 0x48
#define r_UcRms 0x49
#define r_IaRms 0x4A        //电流有效寄存器地址
#define r_IbRms 0x4B
#define r_IcRms 0x4C
#define r_Freq 0x1C         //线频率寄存器地址
#define r_EMUState 0x2C//状态标志寄存器地址
#define ATT7022_CS_EN GPIOC->BRR=1<<6   //拉低
#define ATT7022_CS_DIS GPIOC->BSRR=1<<6   //拉高

u16 AC_unit_Data[37];//交流数据寄存器
/*硬件连接:
        PC6---------------SPI_CS---->CS1
        PB15/SPI2_MOSI---SPI_DIN---->D_DIN
        PB14/SPI2_MISO---SPI_OUT---->D_OUT1
        PB13/SPI2_CLK-----SPI_CLK--->CLK1        
************************************************************************/


void ATT7022_SPI_Init(void)//
{
        GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef SPI_InitStructure;
        
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         //PB时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //PC时钟使能
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);         //SPI2时钟使能
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               
        GPIO_Init(GPIOB, &GPIO_InitStructure);                        
               
//         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
//   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
//   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;//PB14/SPI2_MISO---ATT_SPI_OUT
//   GPIO_Init(GPIOB,&GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽        
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIOC->BSRR=1<<6;//PC6--CS-默认拉高
        
        SPI_Cmd(SPI2, DISABLE);             //先禁能,再改变MODE
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置 SPI 全双工   
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;          //设置 SPI 工作模式:设置为主 SPI   
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;         // 8 位帧结构   
        
        //上升沿放数据,下降沿取数据。SCLK上升沿时将ATT7022E寄存器中的数据放置于DOUT上输出,
        //SCLK下降沿时将DIN上的数据采样到ATT7022E中,MSB在前, LSB在后。
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low ;            //选择了串行时钟的稳态:低   
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;            //数据捕获于第2个时钟沿   
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS 信号由软件管理   
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //预分频 256   
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;         //数据传输从 MSB 位开始   
        SPI_InitStructure.SPI_CRCPolynomial = 7;                   //CRC 值计算的多项式   
        SPI_Init(SPI2, &SPI_InitStructure);  
        SPI_Cmd(SPI2, ENABLE); //使能 SPI 外设
        SPI2_WriteByte(0xff);//启动传输
//         ATT7022_Adjust();//校表函数
}

/*底层接口发送接收函数*/
void SPI2_WriteByte(u8 TxData)//TxData:要写入的字节
{  
         u16 retry=0;     //防止SPI出现故障通讯卡死
         while((SPI2->SR&1<<1)==0)//等待发送区空
         {
                        retry++;
                        if(retry>0XFFFE)return;//超时退出
         }     
         SPI2->DR=TxData;     //发送一个byte        
}

u8 SPI2_ReadByte(void)//返回值:读取到的字节
{  
         u16 retry=0;               SPI2_WriteByte(0XFF);
                while((SPI2->SR&1<<0)==0) //等待接收完一个byte  
         {
                        retry++;
                        if(retry>0XFFFE)return 0;//超时退出
         }            
         return SPI2->DR;          //返回收到的数据        
}

/*对SPI_ATT7022的上层读写操作函数*/
u32 SPI_Read(u8 Reg_Adrr)//ATT7022_SPI读操作
{
         u32 rtemp;
         u8 i,a[3];
         ATT7022_CS_EN; //使能ATT7022EU
         delay_us(3);
         for(i=0;i<3;i++)
         {
                a=SPI2_ReadByte();  
         }               
         rtemp=a[0];
         rtemp=(rtemp<<8)+a[1];
         rtemp=(rtemp<<8)+a[2];
         ATT7022_CS_DIS;
         return rtemp;
}

void SPI_Write(u8 Reg_Adrr,u32 Data)//ATT7022_SPI写操作
{
         u8 i;
         u8 b[3];
         ATT7022_CS_EN;
         b[0]=Data>>16;
         b[1]=Data>>8;
         b[2]=Data;
         for(i=0;i<3;i++)
         {
                 SPI2_WriteByte(b);
         }
         ATT7022_CS_DIS;   
}

u8 Read_7022E(u8 Reg_Adrr)//对ATT7022E通讯数据备份寄存器的值进行比较
{
        u32 Temp;
        u32 Val;
        Val = SPI_Read(Reg_Adrr);
        Temp = SPI_Read(0x2D);
        if(Temp == Val)return 1;
        else                                                        return 0;
}
u8 Write_7022E(u8 Reg_Adrr, u32 data)
{
        u32 Temp;
        SPI_Write(Reg_Adrr,data);
        delay_us(3);
        Temp = SPI_Read(0x2D);
        if(Temp == data)return 1;
        else                                                return 0;
}



直接调用测试 SPI_Read(u8 Reg_Adrr)//ATT7022_SPI读操作,返回值没有,数据也写不进去,,怎么办??
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 11:57:42 | 显示全部楼层
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 12:25:02 | 显示全部楼层
大体看了下,读寄存器的时候需要先写地址然后读数据,在写地址和读数据之间不要操作片选信号,你貌似是写完地址取消片选,然后再片选后读数据
我有故事,你有酒吗
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 13:16:03 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 12:25
大体看了下,读寄存器的时候需要先写地址然后读数据,在写地址和读数据之间不要操作片选信号,你貌似是写完 ...

/*对SPI_ATT7022的上层读写操作函数*/
u32 SPI_Read(u8 Reg_Adrr)//ATT7022_SPI读操作
{
         u32 rtemp;
         u8 i,a[3];
         ATT7022_CS_EN; //使能ATT7022EU
         delay_us(3);
         SPI2_WriteByte(Reg_Adrr);
         for(i=0;i<3;i++)
         {
                a=SPI2_ReadByte(0xFF);  
         }               
         rtemp=a[0];
         rtemp=(rtemp<<8)+a[1];
         rtemp=(rtemp<<8)+a[2];
         ATT7022_CS_DIS;
         return rtemp;
}

void SPI_Write(u8 Reg_Adrr,u32 Data)//ATT7022_SPI写操作
{
         u8 i;
         u8 b[3];
         ATT7022_CS_EN;
         b[0]=Data>>16;
         b[1]=Data>>8;
         b[2]=Data;
         SPI2_WriteByte(Reg_Adrr);
         for(i=0;i<3;i++)
         {
                 SPI2_WriteByte(b);
         }
         ATT7022_CS_DIS;   
}
我这样改了还是一样,,,,“你貌似是写完地址取消片选,然后再片选后读数据”这句不懂
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 15:32:00 | 显示全部楼层
哦,看错了 太乱了。看论坛回帖的那个对话框,有个<>这种标志 那是专门写代码的。那样看起来会清晰一些。
你在读的时候貌似是在强行读取,没有启动spi的时钟吧。应该是这么回事,在你spi读字节的函数之前加个发送函数,发送内容就填0xff
我有故事,你有酒吗
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 15:33:11 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 15:32
哦,看错了 太乱了。看论坛回帖的那个对话框,有个这种标志 那是专门写代码的。那样看起来会清晰一些。
你 ...

我是说sclk上的时钟,不是spi的时钟
我有故事,你有酒吗
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 15:35:53 | 显示全部楼层
另外我想问一下你用着这块片子怎么样?校表那块究竟说的是啥,感觉说明书写的乱七八糟。
我有故事,你有酒吗
回复

使用道具 举报

4

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2015-11-14
在线时间
42 小时
发表于 2016-5-11 15:41:42 | 显示全部楼层
我也刚用过ATT7022EU芯片,但是我是模拟SPI口时序来实现的,没有像你这种使用硬件固有SPI口读数据。
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 16:06:40 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 15:32
哦,看错了 太乱了。看论坛回帖的那个对话框,有个这种标志 那是专门写代码的。那样看起来会清晰一些。
你 ...

[mw_shl_code=applescript,true]SPI2时钟使能了啊,还有我在前面ATT7022_SPI_Init()那里我也有发送“ SPI2_WriteByte(0xff);//启动传输”,,好烦哦,是不是我的SPI的读写函数错了啊?[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 16:09:49 | 显示全部楼层
只是那个明 发表于 2016-5-11 15:41
我也刚用过ATT7022EU芯片,但是我是模拟SPI口时序来实现的,没有像你这种使用硬件固有SPI口读数据。

[mw_shl_code=applescript,true]我就郁闷了,网上的程序怎么都用模拟SPI,模拟SPI不是容易出错吗?您的程序都没有问题吗?[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 16:12:48 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 15:33
我是说sclk上的时钟,不是spi的时钟

[mw_shl_code=applescript,true]u8 SPI2_ReadByte(void)//返回值:读取到的字节
{  
         u16 retry=0;   
         SPI2_WriteByte(0xff);//
         while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
         {
                        retry++;
                        if(retry>0XFFFE)
                        return 0;//超时退出
         }            
         return SPI2->DR;          //返回收到的数据        
}
是这样子吗?大哥[/mw_shl_code]
回复

使用道具 举报

4

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2015-11-14
在线时间
42 小时
发表于 2016-5-11 16:16:19 | 显示全部楼层
黄洪文 发表于 2016-5-11 16:09
[mw_shl_code=applescript,true]我就郁闷了,网上的程序怎么都用模拟SPI,模拟SPI不是容易出错吗?您的程 ...

因为硬件SPI口不能确定一定没有问题。。。而模拟SPI口我们完全可以控制。。模拟SPI口最重要的是时序,。我的也是调了好长时间的。
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 16:32:02 | 显示全部楼层
黄洪文 发表于 2016-5-11 16:12
[mw_shl_code=applescript,true]u8 SPI2_ReadByte(void)//返回值:读取到的字节
{  
         u16 retry=0;     ...

这样子如果不行,那我就不知道了。我在用att7022e,通讯就差不多那样写的没有问题。对了,spi的波形你配置的对吗  上升沿放出数据,下降沿读取数据
我有故事,你有酒吗
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-11 16:37:42 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 16:32
这样子如果不行,那我就不知道了。我在用att7022e,通讯就差不多那样写的没有问题。对了,spi的波形你配 ...

大哥,好人一生平安,,这东西烦了我4天了,还是没有什么进展,能给我参考下您的程序吗?1179083830@qq.com  ,谢谢啦
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-11 22:09:31 | 显示全部楼层
黄洪文 发表于 2016-5-11 16:37
大哥,好人一生平安,,这东西烦了我4天了,还是没有什么进展,能给我参考下您的程序吗?  ,谢谢啦

我用的avr你要看吗 程序在公司
我有故事,你有酒吗
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-12 08:34:22 | 显示全部楼层
来俩不甜的 发表于 2016-5-11 22:09
我用的avr你要看吗 程序在公司

[mw_shl_code=applescript,true]我想请教下为什么SPI读函数之前要发个0xff,其他数字可以吗?然后这就能给读函数提供主机的时钟了吗?[/mw_shl_code]
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-12 08:42:54 | 显示全部楼层
黄洪文 发表于 2016-5-12 08:34
[mw_shl_code=applescript,true]我想请教下为什么SPI读函数之前要发个0xff,其他数字可以吗?然后这就能 ...

不知道,0xff发送的时候 mosi线上的电平不会改变吧可能。  看原子哥的书啊,都有啊 你要问的问题
我有故事,你有酒吗
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-12 08:53:18 | 显示全部楼层
来俩不甜的 发表于 2016-5-12 08:42
不知道,0xff发送的时候 mosi线上的电平不会改变吧可能。  看原子哥的书啊,都有啊 你要问的问题

[mw_shl_code=applescript,true]我不知道哪里有得看,,还望指引...求网址[/mw_shl_code]
回复

使用道具 举报

69

主题

978

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3772
金钱
3772
注册时间
2015-4-26
在线时间
765 小时
发表于 2016-5-12 09:13:31 | 显示全部楼层

置顶帖的 那个光盘资料 从里边的链接下载  资料特别多 都是开源的   每个外设都有源码
我有故事,你有酒吗
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-12 10:38:20 | 显示全部楼层
只是那个明 发表于 2016-5-11 15:41
我也刚用过ATT7022EU芯片,但是我是模拟SPI口时序来实现的,没有像你这种使用硬件固有SPI口读数据。

[mw_shl_code=applescript,true]您好,可以加QQ交流一下吗?1179083830[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-12 14:09:42 | 显示全部楼层
只是那个明 发表于 2016-5-11 15:41
我也刚用过ATT7022EU芯片,但是我是模拟SPI口时序来实现的,没有像你这种使用硬件固有SPI口读数据。

[mw_shl_code=applescript,true]大哥,能把模拟的程序给我参考一下吗?我也打算模拟实现了,,1179083830@qq.com,谢谢啦[/mw_shl_code]
回复

使用道具 举报

4

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
304
金钱
304
注册时间
2015-11-14
在线时间
42 小时
发表于 2016-5-12 14:45:42 | 显示全部楼层
黄洪文 发表于 2016-5-12 14:09
[mw_shl_code=applescript,true]大哥,能把模拟的程序给我参考一下吗?我也打算模拟实现了,,,谢谢啦[/ ...

QQ交流吧。。
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-13 08:51:08 | 显示全部楼层

[mw_shl_code=applescript,true]我发现了我的硬件电路上没有焊ATT7022EU的晶振?请问这芯片是不是需要晶振才能工作的?那要一般要多大的晶振?[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-5-13 08:51:37 | 显示全部楼层
来俩不甜的 发表于 2016-5-12 09:13
置顶帖的 那个光盘资料 从里边的链接下载  资料特别多 都是开源的   每个外设都有源码

[mw_shl_code=applescript,true]我发现了我的硬件电路上没有焊ATT7022EU的晶振?请问这芯片是不是需要晶振才能工作的?那要一般要多大的晶振?[/mw_shl_code]
回复

使用道具 举报

12

主题

59

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
303
金钱
303
注册时间
2016-5-9
在线时间
70 小时
 楼主| 发表于 2016-6-13 10:40:25 | 显示全部楼层
已解决
回复

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2016-9-8
在线时间
6 小时
发表于 2016-9-8 16:49:36 | 显示全部楼层
黄洪文 发表于 2016-5-11 16:37
大哥,好人一生平安,,这东西烦了我4天了,还是没有什么进展,能给我参考下您的程序吗?  ,谢谢啦

大神,我也是最近弄了几天没点反应啊,求解救啊,能把您的程序发我参考一下吗?谢谢
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 18:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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