当前位置:   article > 正文

使用BL0942 计量芯片获取计量数据

bl0942

概述

BL0942 是一颗内置时钟免校准电能计量芯片。
BL0942 能够测量电流、电压有效值、有功功率、有功电能量等参数。

主要特点

  1. 两路独立的 Sigma-Delta ADC,一路电流和一路电压
  2. 电流有效值范围(10mA~30A)@1mohm
  3. 有功电能(1w~6600w)@1mohm@220V
  4. 可输出电流、电压有效值,快速电流有效值,有功功率
  5. 批次出厂增益误差小于 1%,外围元件满足一定条件下可以免校准
  6. SPI(最快速率支持 900KHz)/UART(4800-38400bps)通信方式(TSSOP14L 封装支持最多 4 片级联
    Uart 通信)
  7. 电源掉电监测,低于 2.7V 时,芯片进入复位状态
  8. 内置 1.218V 参考电压源
  9. 芯片单工作电源 3.3V,低功耗 10mW(典型值)

系统框图

在这里插入图片描述

封装与管脚描述

在这里插入图片描述
在这里插入图片描述

大致寄存器说明

在这里插入图片描述
在这里插入图片描述

硬件实现和计量数据转换公式

在这里插入图片描述

在这里插入图片描述

通讯接口-SPI

  1. 工作在从模式
  2. 半双工通讯,通讯率可配,最大通讯速率 900Khz
  3. 固定一种时钟极性/相位(CPOL=0,CPHA=1)
  4. 帧结构:
    在通信模式下,先发送 8bit 识别字节(0x58) 或(0xA8),(0x58)是读操作识别字节,(0xA8)是写操作
    识别字节,然后再发送寄存器地址字节,决定访问寄存器的地址(请参见 BL0942 寄存器列表)。
    下图分别示出读出和写入操作的数据传送顺序。一帧数据传送完成,BL0942 重新进入通信模式。每次读/写操作所需的 SCLK 的脉冲个数均为 48 位。
    在这里插入图片描述

代码实现

1.SPI通信–HAL库发送接收接口
SPI 使用硬件SPI软控制CS

//延时函数,一个计数1US
void Bl09_Delay(u8 count);
//发送:
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
//接收:
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.

#define R_I_RMS			0x03		//电流有效值寄存器,无符号
#define R_V_RMS			0x04		//电压有效值寄存器,无符号  
#define R_WATT			0x06 		//有功功率寄存器,有符号
#define R_CF_CNT		0x07		//有功电能脉冲计数寄存器,无符号
#define R_MODE			0x19		//用户模式选择寄存器 
#define R_SOFT_RESET	0x1c		//写入 0x5A5A5A 时,用户区寄存器复位
#define R_USR_WRPROT	0x1D 		//用户写保护设置寄存器

volatile float Meter_Rece_Voltage = 0;
volatile float Meter_Rece_Current = 0;
volatile float Meter_Rece_Elec = 0;

/*******************************************************************************
功能描述:对BL0942的寄存器写
输入参数:	addr:寄存器地址
			temp:寄存器值
*******************************************************************************/
void BL09_Write_Reg(uint8 addr, uint32 temp)
{
	u8 sendData[6] = {0};
	
	sendData[0] = 0XA8;			//写操作识别字节
	sendData[1] = addr;			//地址
	
  	sendData[2] = (u8)((temp&0x00ff0000)>>16);
	sendData[3] = (u8)((temp&0x0000ff00)>>8);
	sendData[4] = (u8)((temp&0x000000ff));
	//检验和数据
	sendData[5] = ((sendData[0]+sendData[1]+sendData[2]+sendData[3]+sendData[4]) & 0xff);
	sendData[5] = ~sendData[5];
	
	//拉高CS
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
	Bl09_Delay(10);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
	Bl09_Delay(5);
	HAL_SPI_Transmit(&hspi2, sendData, 6 ,1000);
	Bl09_Delay(5);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);	
}

/*******************************************************************************
功能描述:对BL0942的寄存器读
输入参数:	addr:寄存器地址
			data:
返回值:  	0:读取失败
			1:读取成功
*******************************************************************************/
uint8 BL09_Read_Reg(uint8 addr, uint32 *data)
{
	u8 sendData[6] = {0};
	u8 recvData[6] = {0};
	u8 checkSum;

	sendData[0] = 0x58;			//读操作识别字节
	sendData[1] = addr;			//寄存器地址
	
	//拉高CS
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
	Bl09_Delay(10);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
	Bl09_Delay(5);
	HAL_SPI_TransmitReceive(&hspi2,  sendData, recvData, 6, 1000);
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
	
	//校验和计算
	checkSum = (sendData[0]+sendData[1]+recvData[2]+recvData[3]+recvData[4]) & 0xff;
	checkSum = ~checkSum;

	if(checkSum != recvData[5])
		return 0;

	*data = (recvData[2]<<16) + (recvData[3]<<8) + recvData[4];
	
	return 1;
}
//BL0942初始化
void BL09_Init(void)
{
	u32 writeData = 0;
	u32 readData = 0;
	OS_ERR err;

	writeData = 0x5a5a5a;		//用户去寄存器复位,使用
	BL09_Write_Reg(R_SOFT_RESET, writeData);		
	Bl09_Delay(250);Bl09_Delay(250);

	while(1)
	{
		writeData = 0x55;			//关闭写保护
		BL09_Write_Reg(R_USR_WRPROT, writeData);
		
		writeData = 0;
		if(BL09_Read_Reg(R_MODE, &readData))
		{
			writeData = (readData|(0x01<<6));
			BL09_Write_Reg(R_MODE, writeData);
		}
		if(BL09_Read_Reg(R_MODE, &readData))
		{
			if(readData == writeData)
				break;
		}
		OSTimeDly  ((OS_TICK		 )100,
		(OS_OPT 		 )OS_OPT_TIME_DLY,
		(OS_ERR 		*)&err);		
	}	
	writeData = 0xaa;			//开启写保护
	BL09_Write_Reg(R_USR_WRPROT, writeData);	
}

//BLO942电表数据采集
//这里用的是CT1=1000的电流互感器
void BL09_Meter_Scan(void)
{
	float tampElec = 0;	
		
	if(BL09_Read_Reg(R_V_RMS, &regData))
		Meter_Rece_Voltage = regData*6.612/100000;
	if(BL09_Read_Reg(R_I_RMS, &regData))
		Meter_Rece_Current = regData*1.206/1000000;			
	if(BL09_Read_Reg(R_CF_CNT, &regData))
	{
		tampElec = regData*5.947/100000;					
		Meter_Rece_Elec += tampElec;
	}	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/668886
推荐阅读
相关标签
  

闽ICP备14008679号