BMS STM32 V4.0.0.0

This commit is contained in:
2026-08-25 17:30:40 +08:00
commit 3ae7bcb054
313 changed files with 115734 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
/**
******************************************************************************
* @file tim.c
* @author Jerry
* @version V2.1
* @date 19-April-2022
* @brief tim program body.
******************************************************************************
* @attention
*
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "global.h"
#define CAN_MON_CNT 1000 //1000*10ms = 10s
CanTxMsg TxMessage[20];
CanRxMsg RxMessage;
uint8_t TxMailBox[20];
uint8_t CAN_SendCount;
uint16_t CAN_MoniCount;
CAN_MEMORY canMem[AddrMax+2];
//HSE --> PLL倍频到72M --> APB1 2分频到36M
void uf_CAN1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
//Config CAN pin : RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//Config CAN pin : TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//NVIC
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //CAN通信 优先级:1,0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//彻底复位CAN外设:先禁用,再重新使能,确保完全复位
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
delay_ms(1);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
//控制器配置
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE; //时间触发通信模式
CAN_InitStructure.CAN_ABOM = DISABLE; //自动离线管理
CAN_InitStructure.CAN_AWUM = DISABLE; //自动唤醒
CAN_InitStructure.CAN_NART = ENABLE; //自动重传 改启用
CAN_InitStructure.CAN_RFLM = DISABLE; //FIFO锁定
CAN_InitStructure.CAN_TXFP = DISABLE; //发送FIFO优先级
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //普通模式
//波特率配置
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
if(protocol == 7) //MUST协议的波特率是100k
{
CAN_InitStructure.CAN_Prescaler = 40; //36MHz/40/(1+6+2)=100kbs
}
else //其他协议是500k
{
CAN_InitStructure.CAN_Prescaler = 8; //36MHz/8/(1+6+2)=500kbs
}
CAN_Init(CAN1, &CAN_InitStructure);
//过滤器配置
CAN_FilterInitStructure.CAN_FilterNumber = 0; //选择过滤器0
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; //标识符屏蔽模式
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; //过滤器位宽32位
CAN_FilterInitStructure.CAN_FilterIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
//中断配置
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //FIFO0中有消息允许中断
//清除所有可能的错误标志
CAN1->ESR = 0; // 清除错误状态寄存器
CAN1->MSR &= ~(CAN_MSR_ERRI); // 清除错误中断标志
//更新倒计时数
CAN_MoniCount = CAN_MON_CNT;
}
void USB_LP_CAN1_RX0_IRQHandler(void)
{
//处理接收中断
if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
{
//接收报文
CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);
if(RxMessage.StdId == 0x305)
{
RxMessage.StdId = 0;
CAN_MoniCount = CAN_MON_CNT;
if(sleep_flag == 1)
{
//CAN网口收到数据,退出休眠且更新计时起点
sleep_flag = 0;
SLEEP_Refresh();
SLEEP2_Refresh();
}
}
}
}
void CAN_TIM_Moni(void)
{
CAN_MoniCount--;
if(CAN_MoniCount == 0)
{
uf_CAN1_Init();
}
}
/*
1."Sol-Ark", 2."GoodWe", 30."Megarevo", 12."Pylon",
11."Deye", 7."MUST", 37."solis", 3."Growatt",
4."Aiswei", 35."Afore", 27."Victron", 6."Sorotec",
5."SMA", 39."Sunways", 23."Luxpower", 24."Schneider",
40."AlpSolarr", 13."SRNE", 14."Voltronic", 32."COSUPER",
17."SMK", 31."SAKO", 18."SNADI", 21."invt",
*/
void CAN_UpdateData(void)
{
//第1页:
if(protocol == 1) CAN_Protocol_SolArk();
// else if(protocol == 2) CAN_Protocol_GoodWe();
// else if(protocol == 30) CAN_Protocol_Megarevo();
else if(protocol == 12) CAN_Protocol_Pylon();
else if(protocol == 11) CAN_Protocol_Deye();
// else if(protocol == 7) CAN_Protocol_MUST();
else if(protocol == 37) CAN_Protocol_solis();
else if(protocol == 3) CAN_Protocol_Growatt();
// else if(protocol == 4) CAN_Protocol_Aiswei();
// else if(protocol == 35) CAN_Protocol_Afore();
// else if(protocol == 27) CAN_Protocol_Victron();
// else if(protocol == 6) CAN_Protocol_Sorotec();
//第2页:
// else if(protocol == 5) CAN_Protocol_SMA();
// else if(protocol == 39) CAN_Protocol_Sunways();
// else if(protocol == 23) CAN_Protocol_Luxpower();
// else if(protocol == 24) CAN_Protocol_Schneider();
// else if(protocol == 40) CAN_Protocol_AlpSolarr();
}
//CAN报文发送函数
void CAN1_SendData(uint32_t Id, uint8_t *data)
{
uint16_t can_timeout;
can_timeout = CAN_TIMEOUT_COUNT;
if(Id < 0x1000)
{
TxMessage[CAN_SendCount].StdId = Id; //ID
TxMessage[CAN_SendCount].IDE = CAN_ID_STD; //标准ID
}
else
{
TxMessage[CAN_SendCount].ExtId = Id; //ID
TxMessage[CAN_SendCount].IDE = CAN_ID_EXT; //扩展ID
}
TxMessage[CAN_SendCount].RTR = CAN_RTR_DATA; //数据帧
TxMessage[CAN_SendCount].DLC = 8;
TxMessage[CAN_SendCount].Data[0] = data[0];
TxMessage[CAN_SendCount].Data[1] = data[1];
TxMessage[CAN_SendCount].Data[2] = data[2];
TxMessage[CAN_SendCount].Data[3] = data[3];
TxMessage[CAN_SendCount].Data[4] = data[4];
TxMessage[CAN_SendCount].Data[5] = data[5];
TxMessage[CAN_SendCount].Data[6] = data[6];
TxMessage[CAN_SendCount].Data[7] = data[7];
TxMailBox[CAN_SendCount] = CAN_Transmit(CAN1, &TxMessage[CAN_SendCount]); //发送,返回当前邮箱号
while(CAN_TransmitStatus(CAN1,TxMailBox[CAN_SendCount]) != CANTXOK) //等待发送完成
{
if((can_timeout--) == 0) return;
}
CAN_SendCount++;
}