关于钜泉光电ATT7053C计量芯片使用的若干经验

大家好!第一次写东西,完全是当作自己的一个笔记来写的,笔法不成熟,有些凌乱。如果对一些小伙伴有所帮助的话是我的荣幸,也欢迎各位小伙伴指出其中的问题。        

首先说一下,使用这款芯片呢是因为一个项目需求,之前一直使用的是ADE9078这款,但为了节约成本,而且项目需求是单相电就行,所以选取了ATT7053C这款芯片。一开始的时候,和钜泉光电那边的技术人员也沟通过,提供过一些demo程序,当对于我的开发项目没有太大的帮助。言归正传。

该项目使用的单片机是GD32系列的,没有选取ST是因为成本高、其次是供货不稳定。

说明:图示代码可能会有部分宏缺失,主要是做一个经验记录,如有需求,欢迎评论区交流。

管脚分配图:

PB12SPI1_NSS计量芯片ATT7053C SPI通讯输出SPI片选信号
PB13SPI1_SCK输出SPI片时钟信号
PB14SPI1_MISO输入SPI主输入从输出
PB15SPI1_MOSI输出SPI主输出从输入

1、配置好基本驱动

参照GD32技术手册,配置好SPI以及GPIO口的基本驱动。

void Ade_SPI_Config_Init(void)
{
	spi_parameter_struct spi_init_struct ;

	/* SPI 初始化定义 */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;//双线全双工
    spi_init_struct.device_mode          = SPI_MASTER;				//SPI工作在主机模式
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;		//数据帧大小8bit
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;	//CKPL=1,CKPH=1
    spi_init_struct.nss                  = SPI_NSS_SOFT;			//软件控制片选信号nss
    spi_init_struct.prescale             = SPI_PSC_128;		        //分频
    spi_init_struct.endian               = SPI_ENDIAN_MSB;	        //数据传输从 MSB 位开始,高位在前
    spi_init(PORT_ATT7053_SPI, &spi_init_struct);
	
    spi_enable(PORT_ATT7053_SPI);

}


void Ade_SPI_Pin_GPIO_Init(void)
{
	rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_SPI1);
	rcu_periph_clock_enable(RCU_AF);
	
gpio_init(PORT_ATT7053_SPIDIN, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PIN_ATT7053_SPI_DIN);
gpio_init(PORT_ATT7053_SPICLK, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PIN_ATT7053_SPI_CLK);
gpio_init(PORT_ATT7053_SPIDOUT,GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, PIN_ATT7053_SPI_DOUT);
gpio_init(PORT_ATT7053_SPICS,  GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ, PIN_ATT7053_SPI_CS);

}

2、编写SPI数据传输函数,此部分请阅读多理解SPI传输时序图。 

2.1 ATT7053C的SPI接口说明

SPI/UART:选择引脚通讯模式。0:选择UART功能 ;1:选择SPI功能。芯片内部上拉默认为SPI通信方式。

(1)SPIDI:ATT7053C的串行数据接收引脚。

(2)SPIDO:ATT7053C 的串行数据发送引脚。

(3)SPICLK:ATT7053C 的串行时钟引脚,决定数据移出或者移入SPI口的传输速度,上升沿放数据,下降沿取数据。SCLK上升沿时将ATT7053C 寄存器中的数据放置于DOUT上输出,SCLK下降沿时将DIN上的数据采样到ATT7053C中。

(4)SPICS:作为ATT7053C 的片选信号,低电平有效,用户可以通过SPICS引脚的高低来启动 / 终止一次SPI传输。对于三线SPI通讯模式,需要将SPICS一直拉低,按照固定的8bit通讯地址,24bit通讯数据这样的通讯帧方式来读/写ATT7053C 的计量寄存器。

2.2 ATT7053C的SPI通讯定义

(1)固定长度的数据传输(一共4个字节),即每次数据通讯都是1个字节命令和3个字节的数据。

(2)通讯中从机输出是以SCK上升沿输出数据,从机输入是从SCK下降沿采样数据,MSB在前,LSB在后。

(3)命令寄存器的接收会清0内部的SPI数据传输的数据寄存器。

(4)SPI通讯的帧结构:

命令寄存器:读写位+7位要访问的寄存器地址(接收主机的命令)

数据寄存器:3字节(24bit)(接收主机送来的数据)

 2.3 ATT7053C的SPI 通讯波形

CS:片选(INPUT),允许访问控制线,CS发生下降沿跳变时表示SPI操作开始,CS发生上升沿跳变时表示SPI操作结束。

DIN:串行数据输入(INPUT),用于把数据传输到ATT7053C中。

DOUT:串行数据输出(OUTPUT),用于从ATT7053C 寄存器中读出数据。

SCLK:串行时钟(INPUT),控制数据移出或移入串行口的传输率。上升沿放数据,下降沿取数据。SCLK上升沿时将ATT7053C 寄存器中的数据放置于DOUT上输出,SCLK下降沿时将DIN上的数据采样到ATT7053C 中。

 2.4 SPI传输函数代码

void Att_SPI_Transfer_Block(UINT8 *tx_p, UINT8 *rx_p, UINT8 Trans_number)
{
    UINT8 i;

    ENABLE_ATT7053_SPI_CS;//片选拉低
    for(i=0;i<Trans_number;i++)
    {
	  *rx_p=Att_SPI_TransferByte(*tx_p);
        tx_p++;
        rx_p++;       
    }
    DISABLE_ATT7053_SPI_CS;//片选拉高
}

UINT8 Att_SPI_TransferByte(UINT8 TxData)
{
    while(spi_i2s_flag_get(PORT_ATT7053_SPI, SPI_FLAG_TBE) == RESET);
    /* 发送一个字节 */
    spi_i2s_data_transmit(PORT_ATT7053_SPI, TxData);    
    /* 等待数据接收完毕 */
    while(spi_i2s_flag_get(PORT_ATT7053_SPI, SPI_FLAG_RBNE) == RESET);

    return spi_i2s_data_receive(PORT_ATT7053_SPI); 
}

2.5 读寄存器接口函数代码

int ATT7053_Get( UINT8 addr, UINT8 *data, WORD len )
{
		UINT8 byloop=0;
		UINT8 byTxBuff[4], byRxBuff[4],*ptTxBuff=0,byTransNum=0;
		if(len>4)
		{
			return -1;
		}
		byTxBuff[0] = addr | Att7053_readflag; //readflag为0,参考技术手册
		ptTxBuff = &byTxBuff[1];
		for(byloop=0;byloop<len;byloop++)
		{
			ptTxBuff[byloop] = 0;
		}
		byTransNum = sizeof(addr)+len;
		Att_SPI_Transfer_Block(byTxBuff,byRxBuff,byTransNum);
	
		ptTxBuff = &byRxBuff[1];
		for(byloop=0;byloop<len;byloop++)
		{
			data[byloop] = ptTxBuff[byloop];
		}
	
		return 0;
	}
	

2.6写寄存器接口函数代码

int ATT7053_Set( UINT8 addr, UINT8 *data, WORD len )
{
	UINT8 byloop=0;
	UINT8 byTxBuff[4], byRxBuff[4],*ptTxBuff=0,byTransNum=0;
	
	if(len>4)
	{
		return -1;
	}
	byTxBuff[0] = addr | Att7053_writeflag;
	ptTxBuff = &byTxBuff[1];
	for(byloop=0;byloop<len;byloop++)
	{
		ptTxBuff[byloop] = data[byloop];//需要写入寄存器的数据  
	}
	byTransNum = sizeof(addr)+len;
	Att_SPI_Transfer_Block(byTxBuff,byRxBuff,byTransNum);
	
	return 0;
}

2.7 ATT7053初始化

对其初始化时,可以去读取芯片的固有ID,来确认通讯是否OK。

地址      名称         字节长度         内容描述

1BH     ChipID         3                    ChipID,默认值为7053B0

1CH     DeviceID     3                    DeviceID,默认值为705321

void ATT7053_Init(void)
{
	UINT8				data24[3];
	UINT32				buf24,buf24BAK;

    memset((void *)data24,0,sizeof(data24));
	delay_ms(100);
	//读芯片固有参数ChipID
	ATT7053_Get(ADDR_ChipID, data24,sizeof( data24 ));
	ArrayConvertToData24(&buf24, data24, sizeof(data24));//将数组data[3]中的3个字节的数据转换成24位的数据,
	if(buf24 != ChipID)//如果读取错误,对芯片重启
	{
		printf("ATT7053 Read ChipID Error,True ID:%x",ChipID);
		ATT7053_Rst();//重启
	}
	//读芯片固有参数DeviceID
	ATT7053_Get(ADDR_DeviceID, data24,sizeof( data24 ));
	ArrayConvertToData24(&buf24, data24, sizeof(data24));
	if(buf24 != DeviceID)//如果读取错误,对芯片重启
	{
		printf("ATT7053 Read DeviceID Error,True ID:%x",DeviceID);
		ATT7053_Rst();//重启
	}
}

如果可以读到正确的参数,说明单片机与ATT7053的通讯时没有问题的。其次就是一些其他应用了,比如说读电压电流,如何将读数转换为需要显示的电压值,这时候需要去计算一个转换系数。再比如读取缓存波形,计算谐波等!

3、总结

以上是自己使用ATT7053的一些经验,可能是一些很浅显的知识,但也是自己摸索写出来的。在网上也找过一些相应的资料,但帮助比较少,并且大都是需要收费的。在此想感谢钜泉光电的技术人员,对问题有问必答。如果需要对这块计量芯片进行深入开发,可以和厂家的技术人员深度沟通。

说明:如需转载,请注明出处!

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值