1.0
This commit is contained in:
@@ -56,6 +56,7 @@ void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
void CAN1_TX_IRQHandler(void);
|
||||
void CAN1_RX0_IRQHandler(void);
|
||||
void TIM6_DAC_IRQHandler(void);
|
||||
void OTG_FS_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
@@ -86,6 +86,8 @@ void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
|
||||
/* CAN1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(CAN1_TX_IRQn, 2, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
|
||||
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
/* USER CODE BEGIN CAN1_MspInit 1 */
|
||||
|
||||
/* USER CODE END CAN1_MspInit 1 */
|
||||
@@ -111,6 +113,7 @@ void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
|
||||
|
||||
/* CAN1 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
|
||||
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
|
||||
/* USER CODE BEGIN CAN1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END CAN1_MspDeInit 1 */
|
||||
|
||||
@@ -42,13 +42,25 @@
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin : PB2 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ CAN_RxHeaderTypeDef RxHeader;
|
||||
uint8_t RxData[8];
|
||||
volatile uint8_t can_rx_flag = 0; // 告诉主程序“有数据来了”的标志位
|
||||
/* USER CODE END PV */
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
@@ -65,19 +64,23 @@ void SystemClock_Config(void);
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
// 完美解决 USB 忙碌丢包的重定向函数
|
||||
// 完美解决 USB 忙碌丢包,且防中断死锁的重定向函数
|
||||
int _write(int file, char *ptr, int len) {
|
||||
uint8_t result = CDC_Transmit_FS((uint8_t*)ptr, len);
|
||||
extern USBD_HandleTypeDef hUsbDeviceFS; // 引入 USB 状态句柄
|
||||
|
||||
// 使用简单的变量自增来做超时等待,坚决不用 HAL_Delay
|
||||
int _write(int file, char *ptr, int len) {
|
||||
// 1. 致命拦截:如果电脑压根没连上 USB,直接丢弃数据,坚决不死等!
|
||||
if (hUsbDeviceFS.dev_state != USBD_STATE_CONFIGURED) {
|
||||
return len;
|
||||
}
|
||||
|
||||
uint8_t result = CDC_Transmit_FS((uint8_t*)ptr, len);
|
||||
uint32_t timeout = 0;
|
||||
|
||||
// 50000 只是一个大概的经验值,纯耗费 CPU 周期
|
||||
while(result == USBD_BUSY && timeout < 50000) {
|
||||
// 2. 极短超时:就算 USB 连着但突然卡了,最多循环 5000 次就强行放弃,保命要紧
|
||||
while(result == USBD_BUSY && timeout < 5000) {
|
||||
timeout++;
|
||||
result = CDC_Transmit_FS((uint8_t*)ptr, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
/* USER CODE END 0 */
|
||||
@@ -137,20 +140,18 @@ int main(void)
|
||||
canFilterConfig.SlaveStartFilterBank = 14;
|
||||
|
||||
HAL_StatusTypeDef fs = HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig);
|
||||
printf("Filter: %d\r\n", fs);
|
||||
|
||||
HAL_StatusTypeDef ss = HAL_CAN_Start(&hcan1);
|
||||
printf("Start: %d\r\n", ss);
|
||||
|
||||
// 这句开启接收中断的函数极其重要,确认它还在!
|
||||
HAL_StatusTypeDef ns = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
printf("Notif: %d\r\n", ns);
|
||||
|
||||
printf("=== CAN Ready ===\r\n");
|
||||
// 💡 修改这里:必须加这一句!给你的电脑 3 秒钟时间去识别 USB 虚拟串口
|
||||
HAL_Delay(3000);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
static uint32_t last_heartbeat = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
@@ -159,12 +160,6 @@ int main(void)
|
||||
// ==========================================
|
||||
// 强制打印 1:每隔 1 秒无条件打印一次(心跳包)
|
||||
// ==========================================
|
||||
if (HAL_GetTick() - last_heartbeat >= 1000) {
|
||||
last_heartbeat = HAL_GetTick();
|
||||
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_2);
|
||||
// 只要 USB 串口是好的,你就一定能每秒看到这句话!
|
||||
printf("System Running... Waiting for CAN...\r\n");
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 强制打印 2:原来的 CAN 接收处理逻辑
|
||||
@@ -172,12 +167,15 @@ int main(void)
|
||||
if (can_rx_flag == 1) {
|
||||
can_rx_flag = 0; // 赶紧先把标志位清零
|
||||
|
||||
// 加了超级醒目的感叹号,防止看漏
|
||||
printf("!!! BINGO !!! Got CAN MSG! ID:0x%03lX Data: ", RxHeader.StdId);
|
||||
for(int i = 0; i < RxHeader.DLC; i++) {
|
||||
printf("%02X ", RxData[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
// 💡 修改这里:用一个数组把要发的话拼起来,只调用一次 printf!
|
||||
// 这能彻底防止 168MHz 的 CPU 把 USB 虚拟串口瞬间撑爆死机
|
||||
char usb_buf[100];
|
||||
sprintf(usb_buf, "!!! BINGO !!! Got CAN MSG! ID:0x%03lX Data: %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
|
||||
RxHeader.StdId,
|
||||
RxData[0], RxData[1], RxData[2], RxData[3],
|
||||
RxData[4], RxData[5], RxData[6], RxData[7]);
|
||||
|
||||
printf("%s", usb_buf);
|
||||
}
|
||||
/* USER CODE END WHILE */
|
||||
}
|
||||
|
||||
@@ -214,6 +214,20 @@ void CAN1_TX_IRQHandler(void)
|
||||
/* USER CODE END CAN1_TX_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CAN1 RX0 interrupts.
|
||||
*/
|
||||
void CAN1_RX0_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN CAN1_RX0_IRQn 0 */
|
||||
|
||||
/* USER CODE END CAN1_RX0_IRQn 0 */
|
||||
HAL_CAN_IRQHandler(&hcan1);
|
||||
/* USER CODE BEGIN CAN1_RX0_IRQn 1 */
|
||||
|
||||
/* USER CODE END CAN1_RX0_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
|
||||
*/
|
||||
|
||||
40
FDR-Core.ioc
40
FDR-Core.ioc
@@ -34,24 +34,25 @@ Mcu.Pin0=PE5
|
||||
Mcu.Pin1=PE6
|
||||
Mcu.Pin10=PA6
|
||||
Mcu.Pin11=PA7
|
||||
Mcu.Pin12=PE9
|
||||
Mcu.Pin13=PE11
|
||||
Mcu.Pin14=PD12
|
||||
Mcu.Pin15=PD13
|
||||
Mcu.Pin16=PC6
|
||||
Mcu.Pin17=PC7
|
||||
Mcu.Pin18=PC8
|
||||
Mcu.Pin19=PC9
|
||||
Mcu.Pin12=PB2
|
||||
Mcu.Pin13=PE9
|
||||
Mcu.Pin14=PE11
|
||||
Mcu.Pin15=PD12
|
||||
Mcu.Pin16=PD13
|
||||
Mcu.Pin17=PC6
|
||||
Mcu.Pin18=PC7
|
||||
Mcu.Pin19=PC8
|
||||
Mcu.Pin2=PC14-OSC32_IN
|
||||
Mcu.Pin20=PA11
|
||||
Mcu.Pin21=PA12
|
||||
Mcu.Pin22=PA13
|
||||
Mcu.Pin23=PA14
|
||||
Mcu.Pin24=PB8
|
||||
Mcu.Pin25=PB9
|
||||
Mcu.Pin26=VP_SYS_VS_Systick
|
||||
Mcu.Pin27=VP_TIM6_VS_ClockSourceINT
|
||||
Mcu.Pin28=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin20=PC9
|
||||
Mcu.Pin21=PA11
|
||||
Mcu.Pin22=PA12
|
||||
Mcu.Pin23=PA13
|
||||
Mcu.Pin24=PA14
|
||||
Mcu.Pin25=PB8
|
||||
Mcu.Pin26=PB9
|
||||
Mcu.Pin27=VP_SYS_VS_Systick
|
||||
Mcu.Pin28=VP_TIM6_VS_ClockSourceINT
|
||||
Mcu.Pin29=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin3=PC15-OSC32_OUT
|
||||
Mcu.Pin4=PH0-OSC_IN
|
||||
Mcu.Pin5=PH1-OSC_OUT
|
||||
@@ -59,13 +60,14 @@ Mcu.Pin6=PA0-WKUP
|
||||
Mcu.Pin7=PA1
|
||||
Mcu.Pin8=PA2
|
||||
Mcu.Pin9=PA3
|
||||
Mcu.PinsNb=29
|
||||
Mcu.PinsNb=30
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F407VGTx
|
||||
MxCube.Version=6.15.0
|
||||
MxDb.Version=DB.6.0.150
|
||||
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.CAN1_RX0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
|
||||
NVIC.CAN1_TX_IRQn=true\:2\:0\:true\:false\:true\:true\:true\:true
|
||||
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
|
||||
NVIC.ForceEnableDMAVector=true
|
||||
@@ -105,6 +107,8 @@ PA6.Signal=S_TIM3_CH1
|
||||
PA7.GPIOParameters=GPIO_Label
|
||||
PA7.GPIO_Label=RL_ENC_B
|
||||
PA7.Signal=S_TIM3_CH2
|
||||
PB2.Locked=true
|
||||
PB2.Signal=GPIO_Output
|
||||
PB8.Locked=true
|
||||
PB8.Mode=CAN_Activate
|
||||
PB8.Signal=CAN1_RX
|
||||
|
||||
Reference in New Issue
Block a user