/** ****************************************************************************** * @file power_meter.c * @author Motor Control SDK Team, Yuwell Software XiangenWang * @brief Voice Recognition Module Initialization Section, including peripheral initialization and message node insertion, etc. * @version 1.0 * @changelog version 1.0 初始版本 2025.12.31 ****************************************************************************** * @attention * *

© Copyright (c) 2025 Yuwell Software Danyang.Jiangsu.China. * All rights reserved.

* * Redistribution and use in source and binary forms, with or without * modification, are permitted, provided that the following conditions are met: * * 1. Redistribution of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of Yuwell Software nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific written permission. * 4. This software, including modifications and/or derivative works of this * software, must execute solely and exclusively on microcontroller or * microprocessor devices manufactured by or for Yuwell Software. * 5. Redistribution and use of this software other than as permitted under * this license is void and will automatically terminate your rights under * this license. * * THIS SOFTWARE IS PROVIDED BY Yuwell Software AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT * SHALL Yuwell Software OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* USER CODE END Header */ #include "power_meter.h" // 提供给外部的采样结果数据 EleC_V_data elec_v_data; // 向对应寄存器写入数据 低位在低位 高位在高位 // 共24bit,不足处用0补齐,低位先行 // 发送数据大小限定为3个字节 static void coulombmeter_write_reg(uint8_t addr, uint8_t* reg_data) { uint8_t check_sum = 0; // 1. 下发命令字节 BL0942_ADDR_W COULOMBMETER_UART_TRANS_BYTE(BL0942_ADDR_W); // 2. 下发需要写寄存器的地址 COULOMBMETER_UART_TRANS_BYTE(addr); // 3. 发送需要往寄存器地址写入的数据 COULOMBMETER_UART_TRANS_BYTE(reg_data[0]); COULOMBMETER_UART_TRANS_BYTE(reg_data[1]); COULOMBMETER_UART_TRANS_BYTE(reg_data[2]); // 4. 发送校验和 check_sum = (BL0942_ADDR_W + addr + reg_data[0] + reg_data[1] + reg_data[2]); check_sum = ~(check_sum & 0xFF); COULOMBMETER_UART_TRANS_BYTE(check_sum); } // 从特定寄存器读取数据 芯片将通过串口接收中断返回 // 芯片收到消息后将在150us内返回数据 // 1s执行一次 数据在接收中断中处理 static void coulombmeter_read_reg(uint8_t addr) { // 1. 下发命令字节 BL0942_ADDR_R COULOMBMETER_UART_TRANS_BYTE(BL0942_ADDR_R); // 2. 下发地址数据 COULOMBMETER_UART_TRANS_BYTE(addr); } void User_PowerMeter_Init(void) { FL_GPIO_InitTypeDef GPIO_InitStruct; // 初始化GPIO GPIO_InitStruct.pin = COULOMBMETER_UART_RX_GPIO_PIN; GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL; GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL; GPIO_InitStruct.pull = FL_DISABLE; GPIO_InitStruct.remapPin = FL_DISABLE; GPIO_InitStruct.analogSwitch = FL_DISABLE; FL_GPIO_Init(COULOMBMETER_UART_RX_GPIO_PORT, &GPIO_InitStruct); GPIO_InitStruct.pin = COULOMBMETER_UART_TX_GPIO_PIN; FL_GPIO_Init(COULOMBMETER_UART_TX_GPIO_PORT, &GPIO_InitStruct); // 初始化串口参数 FL_UART_InitTypeDef UART_InitStruct = {0}; UART_InitStruct.baudRate = 9600; //波特率 UART_InitStruct.dataWidth = FL_UART_DATA_WIDTH_8B; //数据位数 UART_InitStruct.stopBits = FL_UART_STOP_BIT_WIDTH_1B; //停止位 UART_InitStruct.parity = FL_UART_PARITY_NONE; //奇偶校验 UART_InitStruct.transferDirection = FL_UART_DIRECTION_TX_RX; //接收-发送使能 FL_UART_Init(COULOMBMETER_USED_UART_NUM, &UART_InitStruct); NVIC_DisableIRQ(COULOMBMETER_IRQn); NVIC_SetPriority(COULOMBMETER_IRQn,2); //中断优先级配置 NVIC_EnableIRQ(COULOMBMETER_IRQn); // 开启接收中断 FL_UART_ClearFlag_RXBuffFull(COULOMBMETER_USED_UART_NUM); FL_UART_EnableIT_RXBuffFull(COULOMBMETER_USED_UART_NUM); // 清空结果 memset(&elec_v_data, 0, sizeof(elec_v_data)); } // 推荐1s刷新一次 最终数据将存储在全局变量elec_v_data中 void User_Coulombmeter_Data_refresh(void) { static Bus_Mod mod = MOD_CURRENT_METER; if(mod == MOD_VOLTAGE_METER) { mod = MOD_CURRENT_METER; coulombmeter_read_reg(Addr_V_RMS); elec_v_data.bus_com_stm = BUS_COM_STATE_WAITE_VOLTAGE; // 转入等待电压数据状态 elec_v_data.current_index = 0; elec_v_data.voltage_raw = 0; }else{ mod = MOD_VOLTAGE_METER; coulombmeter_read_reg(Addr_I_RMS); elec_v_data.bus_com_stm = BUS_COM_STATE_WAITE_CURRENT; // 转入等待电压数据状态 elec_v_data.current_index = 0; elec_v_data.current_raw = 0; } } void UART5_IRQHandler(void) { // 接收中断处理 if(FL_UART_IsEnabledIT_RXBuffFull(COULOMBMETER_USED_UART_NUM) && FL_UART_IsActiveFlag_RXBuffFull(COULOMBMETER_USED_UART_NUM)) { if(elec_v_data.bus_com_stm == BUS_COM_STATE_WAITE_VOLTAGE) { //接收中断标志可通过读取rxreg寄存器清除 uint8_t tmp_data = 0; tmp_data = FL_UART_ReadRXBuff(COULOMBMETER_USED_UART_NUM); if(elec_v_data.current_index < 3) { elec_v_data.voltage_raw |= (tmp_data<<(elec_v_data.current_index*8)); } elec_v_data.voltage_array[elec_v_data.current_index++] = tmp_data; if(elec_v_data.current_index == 4) { uint8_t checkSum = ~((elec_v_data.voltage_array[0] + elec_v_data.voltage_array[1] + elec_v_data.voltage_array[2] + BL0942_ADDR_R + Addr_V_RMS)&0xFF); if(elec_v_data.voltage_array[3] == checkSum) { // 校验正确对数据进行赋值 elec_v_data.bus_com_stm = BUS_COM_STATE_IDLE; elec_v_data.bus_rms_voltage_V =elec_v_data.voltage_raw / Voltage_K; elec_v_data.voltage_raw = 0; elec_v_data.current_index = 0; } } }else if(elec_v_data.bus_com_stm == BUS_COM_STATE_WAITE_CURRENT) { uint8_t tmp_data = 0; tmp_data = FL_UART_ReadRXBuff(COULOMBMETER_USED_UART_NUM); if(elec_v_data.current_index < 3) { elec_v_data.current_raw |= (tmp_data<<(elec_v_data.current_index*8)); } elec_v_data.current_array[elec_v_data.current_index++] = tmp_data; if(elec_v_data.current_index == 4) { uint8_t checkSum = ~((elec_v_data.current_array[0] + elec_v_data.current_array[1] + elec_v_data.current_array[2] + BL0942_ADDR_R + Addr_I_RMS)&0xFF); if(elec_v_data.current_array[3] == checkSum) { // 校验正确对数据进行赋值 elec_v_data.bus_com_stm = BUS_COM_STATE_IDLE; elec_v_data.bus_rms_current_mA =elec_v_data.current_raw*100 / Current_K; elec_v_data.current_raw = 0; elec_v_data.current_index = 0; } } } FL_UART_ClearFlag_RXBuffFull(COULOMBMETER_USED_UART_NUM); } } /************************ (C) COPYRIGHT YUWELL *****END OF FILE****/