BMS STM32 V4.0.0.0
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user