/**
******************************************************************************
* @file coulombmeter.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 "coulombmeter.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);
}
//
uint8_t data[32];
void User_Coulombmeter_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);
// 开启发送完毕中断(由于需要发送的字节较少 此处不使用)
// FL_UART_ClearFlag_TXShiftBuffEmpty(COULOMBMETER_USED_UART_NUM);
// FL_UART_EnableIT_TXShiftBuffEmpty(COULOMBMETER_USED_UART_NUM);
// 清空结果
memset(&elec_v_data, 0, sizeof(elec_v_data));
memset(data, 0, sizeof(data));
}
//
// 推荐1s刷新一次 最终数据将存储在全局变量elec_v_data中
void User_Coulombmeter_Data_refresh(void)
{
static uint8_t mod = 0;
if(mod == 0)
{
mod = 1;
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 = 0;
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;
}
}
uint8_t i = 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);
elec_v_data.voltage_raw |= (tmp_data<<(elec_v_data.current_index*8));
elec_v_data.current_index++;
if(elec_v_data.current_index == 3)
{
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);
elec_v_data.current_raw |= (tmp_data<<(elec_v_data.current_index*8));
elec_v_data.current_index++;
if(elec_v_data.current_index == 3)
{
elec_v_data.bus_com_stm = BUS_COM_STATE_IDLE;
elec_v_data.bus_rms_current_mA =elec_v_data.current_raw / Current_K;
// elec_v_data.current_raw = 0;
elec_v_data.current_index = 0;
}
}
}
// 发送中断处理
if(FL_UART_IsEnabledIT_TXShiftBuffEmpty(COULOMBMETER_USED_UART_NUM) &&
FL_UART_IsActiveFlag_TXShiftBuffEmpty(COULOMBMETER_USED_UART_NUM))
{
FL_UART_ClearFlag_TXShiftBuffEmpty(COULOMBMETER_USED_UART_NUM); //清除发送中断标志
}
}
/************************ (C) COPYRIGHT YUWELL *****END OF FILE****/