/** ****************************************************************************** * @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++; }