/** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2019 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions 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 STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f1xx_hal.h" #include "adc.h" #include "can.h" #include "dma.h" #include "iwdg.h" #include "usart.h" #include "gpio.h" #include "tim.h" /* USER CODE BEGIN Includes */ #include "eeprom_flash.h" #include "eeprom_24c02.h" #include "var.h" #include "tasks.h" #include "can_process.h" #include "motor_control.h" #include "light_driver.h" #include "power12V_driver.h" #include "key_driver.h" #include "remain_distance.h" #include "protect_check.h" #include "fault_check.h" #include "app_loader.h" #include "stm32fxx_STUlib.h" #include "ctf_process.h" #include "log_save.h" #include "flash_read_protection.h" #include "hardware_check.h" #include "enviolo_can.h" /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ uint8_t TimeBase_10ms=0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ void STU_TimeBase(void); /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * * @retval None */ int main(void) { /* USER CODE BEGIN 1 */ IAP_Init(); //Bootloader 200ms MCUManufacturer = IdentifyMCUManufacturer(); //Flash读保护设置 #if 0 Flash_ReadProtection(); #endif /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ //Light驱动IO初始化 LightDriver_Init(); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM1_Init(); MX_TIM2_Init(); MX_TIM3_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_ADC2_Init(); MX_CAN_Init(); MX_USART3_UART_Init(); STU_InitRunTimeChecks(); /* USER CODE BEGIN 2 */ //ADC启动 ADC_Start(); HAL_Delay(20);//20ms //定时器2启动计数 HAL_TIM_Base_Start(&htim2); //变量初始化 Var_Init(); //看门狗初始化 #if DEBUG MX_IWDG_Init(); #endif //传感器初始化 MC_SensorInit(); //EEPROM_24C02初始化 EEPROM_24C02_Init(&I2C_Handle_EEPROM); //测试用于清除所有数据 #if 0 EEPROM_24C02_ClearData(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_FLAG, EEPROM_24C02_ADDR_END, 0xFF); EEPROM_Flash_Erase(EEPROM_FLASH_BEGIN_ADDRESS, EEPROM_FLASH_END_ADDRESS); #endif //EEPROM_Flash初始化 EEPROM_Flash_Check(); //EEPROM读取参数 if(EEPROM_24C02_Check(&I2C_Handle_EEPROM) == ACK_FAIL)//260ms { //EEPROM读取数据失败处理 //... } //掉电临时数据搬移到24C02 IsPowerOffDataBkp_SaveFlag = EEPROM_Flash_TempCheck(); SavePowerOffBakData(&I2C_Handle_EEPROM, IsPowerOffDataBkp_SaveFlag);//75ms //擦除临时掉电数据存储区域为0xFF,关机前写入时无需擦除 EEPROM_Flash_Erase(EEPROM_FLASH_ADDR_TEMP_BEGIN_ADDRESS, EEPROM_FLASH_ADDR_TEMP_END_ADDRESS);//100ms //MC控制初始化 MC_Init();//145ms //变速器参数初始化 GearBox_Init(); //检查电机是否授权 #if 0 Read_Ctf_Info(&MC_ErrorCode); #endif //外部设备授权校验 #if 0 #if 1 //校验电池 MC_DeviceCheck(&BMS_CheckInfo, &MC_ErrorCode); #endif #if 0 //校验按键 MC_DeviceCheck(&PBU_CheckInfo, &MC_ErrorCode); #endif #if 1 //校验仪表 MC_DeviceCheck(&HMI_CheckInfo, &MC_ErrorCode); #endif #endif //初始化完成标志 IsInitFinish_Flag = TRUE; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ #if 1 // 测试运行周期 static uint8_t RunPeriodTestCnt = 0; RunPeriodTestCnt++; if(RunPeriodTestCnt > 200) { RunPeriodTestCnt = 0; } #endif //硬件版本识别 GetHardware_Versin( HardwareVersion_AD ); //无码表模式初始化处理 NoPBUMode_Ini(); //CAN数据解析及处理 CanRx_Process(); //UART数据解析及处理 UartRx_Process(); //CAN设备通信状态检测 MC_CanRxCheck_Process(MC_ConfigParam1.NoPBU_Flag, PBU_ConfigParam.NoHMI_Flag, MC_WorkMode, &MC_ControlCode.GearSt); //UART设备通信状态检测 MC_UartRxCheck_Process(); //CAN设备心跳包 Device_Handshake_Process(); //速度传感器采集及计算 if(MC_ConfigParam1.SpeedSignal == MC_SPEED_CADENCE_CAL) //0xAA, 根据踏频估算 { if(MC_RunInfo.CadenceDir != MC_Cadence_Forward) //脚踏向后或停止时,采用电机转速 { SpeedCal_ByCadence(MC_RunInfo.MotorSpeed / 11, &MC_SpeedSensorData.Speed_Data, MC_ConfigParam1.TeethNum_F, MC_ConfigParam1.TeethNum_B, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, &MC_RunInfo.BikeSpeed); } else //脚踏向前时,取大值 { SpeedCal_ByCadence((MC_RunInfo.MotorSpeed / 11 > MC_RunInfo.Cadence) ? MC_RunInfo.MotorSpeed / 11 : MC_RunInfo.Cadence, &MC_SpeedSensorData.Speed_Data, MC_ConfigParam1.TeethNum_F, MC_ConfigParam1.TeethNum_B, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, &MC_RunInfo.BikeSpeed); } } else if(MC_ConfigParam1.SpeedSignal == MC_SPEED_COMMUNICATION) //0xEE, 根据通信获取的车轮旋转周期 { SpeedCal_ByCommunication(&MC_SpeedSensorData, &MC_RunInfo.BikeSpeed, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj); } else { SpeedSensor_Process(&MC_SpeedSensorData, &MC_RunInfo.BikeSpeed, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, (MC_ConfigParam1.SpeedSensorPoles == 0) ? 1: MC_ConfigParam1.SpeedSensorPoles); } //检测变速信号 GearSensor_Check(&IsGearSensorTrig_Flag); //检测刹车信号 Break_Check(&IsBreakTrig_Flag); //续航里程计算 do { static uint8_t RD_RemainDis_InitFinished = 0x00; if(RD_RemainDis_InitFinished == 0x00) { if((IsComOK_BMS.IsOK_Flag == TRUE) || (HAL_GetTick() > 10000))//初始化续航计算相关变量 { //续航里程计算变量初始化 RD_RemainDis_Init(MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, IsComOK_BMS.IsOK_Flag, MC_RunInfo.BusVoltage / 10, MC_MotorParam.Rate_Voltage, BMS_RunInfo.RC); RD_RemainDis_InitFinished = 0x01; } } else { RD_CalculateRemainDis(MC_SpeedSensorData.WheelTurnCount, BMS_RunInfo.RC, BMS_RunInfo.SOC, MC_RunInfo.BusCurrent); RD_SaveAndUpdateInfo(MC_ControlCode.GearSt, MC_CalParam.AssistRunMode); } }while(0); //更新电机运行信息 MC_RunInfo_Update(); //更新电机调试信息 MC_DebugInfo_Update(); //计算运行总时间 MC_RunTime_Cal(); //温度历史数据记录 MC_TemperatureLogProcess(); //根据踏频计算限流系数 MC_CadenceLimit_K = MC_CadenceLimit_Cal(MC_RunInfo.Cadence, MC_RunInfo.BusCurrent, MC_RunInfo.T_Coil); //Flash数据存储更新处理 if(MC_CalParam.Foc_Flag == RESET) { EEPROM_Flash_DataUpdate(&IsFlashSaveDataUpdate); } //故障日志存储更新处理 if(MC_CalParam.Foc_Flag == RESET) { ErrorLogSave_Process(&MC_ErrorLogSaveInfo, &IsErrorLogSaveInfoUpdateFlag); RunLogSave_Process(&RunLogSaveIndex); } #if 1 //异常掉电时保存里程数据 if(PowerDown_SaveFlag==TRUE) { MC_PowerOffBkp.ODO_Km = MC_RideLog.ODO_Km; MC_PowerOffBkp.ODO_Time = MC_RideLog.ODO_Time; MC_PowerOffBkp.Trip_Km = MC_RideLog.TRIP_Km; MC_PowerOffBkp.Trip_Time = MC_RideLog.TRIP_Time; MC_PowerOffBkp.Run_Time = MC_RunLog1.RunTime; MC_PowerOffBkp.Log_ODO_Km = MC_RunLog1.ODO_Km; MC_PowerOffBkp.Log_ODO_Time = MC_RunLog1.ODO_Time; MC_PowerOffBkp.PedalPoweSum = MC_AvgPower.PedalPowerSum; SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP, (uint8_t*)&MC_PowerOffBkp.ODO_Km, 40);//写入掉电临时保存数据,写入前该区域需擦除为0xFF才能操作成功 SaveDataToEEPROM_Flash(EEPROM_FLASH_ADDR_POWEROFF_BKP_FLAG, (uint8_t*)"FLAG", 4); //掉电存储的数据标志更新 PowerDown_SaveFlag = FALSE; } #endif #if 1 //故障检测 MC_Fault_Check_Process(); //保护判断 MC_Protect_Check_Process(); #endif //发送故障码 MC_SendErrorCode_Process(MC_ErrorCode); //非运行模式,主动发送电机运行信息和调试 #if 1 MC_SendRunInfo_Process(MC_WorkMode); MC_SendDebugInfo_Process(MC_WorkMode); #endif //定时发送传感器数据给TE MC_TE_SensorData_Process(&MC_TE_SensorData); //指拨模式计算函数 SpdProportion_calculate(); //变速器处理 GearBox_Loop(); //MCU自检 STU_TimeBase(); STU_DoRunTimeChecks(); //看门狗清零 #if DEBUG HAL_IWDG_Refresh(&hiwdg); #endif /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* USER CODE BEGIN 4 */ void STU_TimeBase(void) { STU_TestStatus ram_test; if(TimeBase_10ms >= 10 ) { TimeBase_10ms = 0; TimeBaseFlag = 0xAAAAAAAAuL; TimeBaseFlagInv = 0x55555555uL; /*--------------------------------------------------------------------------*/ /* --------------------- RAM functional test -------------------*/ /*--------------------------------------------------------------------------*/ __disable_irq(); ram_test = STU_RamRun(); __enable_irq(); switch ( ram_test ) { case TEST_RUNNING: break; case TEST_OK: break; case TEST_FAILURE: case CLASS_C_DATA_FAIL: default: FailSafePOR(); break; } } } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @param file: The file name as string. * @param line: The line in file as a number. * @retval None */ void _Error_Handler(char *file, int line) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ while(1) { MC_MotorStop(&MC_StarFlag); Power12V_Driver_Process(RESET); Disable_PwmGpio_Out(); //Debug,输出当前错误信息 #if 1 uint8_t PrintData[32] = {0,}; memcpy((uint8_t*)PrintData, file, strlen(file)); memcpy((uint8_t*)(PrintData + strlen(file)), (uint8_t*)" , ", 3); memcpy((uint8_t*)(PrintData + strlen(file) + 3), &line, sizeof(line)); SendData(ID_MC_BC, MODE_REPORT , 0xFF20, PrintData); HAL_Delay(200); #endif } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/