使用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);

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;
	}	
}
### Windows 11 中大小核调度优化方法及性能提升策略 #### 调整大小核调度的方法 在 Windows 11 系统下,可以通过任务管理器来调整 CPU 的大小核调度策略。这种方法允许用户手动干预系统的默认行为,从而更高效地利用硬件资源[^1]。 具体操作如下: 打开任务管理器,在“详细信息”选项卡中找到目标进程,右键点击并选择“设置关联性”。在这里可以指定某个特定的任务仅运行于高性能的核心上,或是分配到效率核心以节省电力消耗。 #### 设置 CPU 性能模式 除了通过任务管理器进行精细控制外,还可以全局更改处理器的工作状态至更高效能的状态。类似于 Linux 下使用 `cpufreq-set` 命令设定为 performance 模式的方式[^2],虽然 Windows 并未提供如此直接的命令行工具,但是能够借助电源计划达到相似效果: 进入系统设置 -> 电源和电池 -> 高效模式 或者 创建自定义高级电源计划 ,将各个子项都配置成最大化性能取向 。 这样做有助于确保无论何时何地都需要计算能力的时候都能得到充分支持 。 另外需要注意的是 , 关闭一些不必要的后台活动和服务也可以间接改善整体响应速度 . 如同 Win10 提升技巧里提到过的停止诊断追踪以及搜索引擎索引等功能 [^3], 对减少干扰因素很有帮助 . 最后考虑网络层面的影响也不可忽视, 当前很多应用依赖互联网连接完成其主要功能; 因此按照之前分享过关于网路效能改进措施同样适用于这里 [^4]. ```powershell # PowerShell 示例脚本用于查看当前电源方案详情 Get-WmiObject -Class win32_powerplan -Namespace root\cimv2\power | Format-Table ElementName, IsActive ``` 以上就是针对 Windows 11 用户如何有效实施大小核调度优化及其带来的潜在好处介绍.
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值