赞
踩
BL0942 是一颗内置时钟免校准电能计量芯片。
BL0942 能够测量电流、电压有效值、有功功率、有功电能量等参数。
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, ®Data)) Meter_Rece_Voltage = regData*6.612/100000; if(BL09_Read_Reg(R_I_RMS, ®Data)) Meter_Rece_Current = regData*1.206/1000000; if(BL09_Read_Reg(R_CF_CNT, ®Data)) { tampElec = regData*5.947/100000; Meter_Rece_Elec += tampElec; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。