nickson.b.k 0 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба В продолжение темы по CAN на stm32f3xx. Не получив успеха в запуске CAN внутри своего проекта, решил откатиться назад и создать новый проект, на котором нужно отладить код с работай CAN. Итак. Имею два абсолютно одинаковых устройства. - на плате есть трансивер, подключённый к МК. - на выходе трансивера имеется резистор на 120. - МК тактируется от внешнего кварца. - цепи проверены, обрывов нет. Решил набросать пример на HAL образу из данного видео (уверен, что видео известное): и часть 2: Первым делом, если вспомнить о режимах CAN внутри stm32, где выход можно замкнуть на вход, то можно произвести первичную отладку в рамках одного камня. Задача: - настроить МК в режим где выход замкнут на вход, пусть будет CAN_MODE_LOOPBACK. - в цикле МК пусть оправляет что-нибудь по кругу - а в прерывании приёма пусть переключает состояние светодиода. - кванты времени взяты с ресурса http://www.bittiming.can-wiki.info/ : -- частота тактирования шины 32MHz -- выбранная частота самая низкая - 10kbit-s Вот что у меня вышло: /* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * <h2><center>© Copyright (c) 2021 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ CAN_FilterTypeDef sFilterConfig; CAN_TxHeaderTypeDef TxHeader; CAN_RxHeaderTypeDef RxHeader; uint8_t Can_Data_Tx[8]; uint8_t Can_Data_Rx[8]; /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ CAN_HandleTypeDef hcan; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_CAN_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ // Прерывание приёма. Если будет что-то получено, то переключить состояние светодиода. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, Can_Data_Rx) == HAL_OK) { GPIOB -> ODR ^= GPIO_ODR_6; } } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* 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 */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ //светодиод "ERROR" (pcb) //PA3(18) RCC -> AHBENR |= RCC_AHBENR_GPIOAEN; // тактирование порта A GPIOA -> MODER |= GPIO_MODER_MODER3_0; // 01: General purpose output mode //светодиод "TR" (панель пульта) //PB6(58) RCC -> AHBENR |= RCC_AHBENR_GPIOBEN; // Тактирование порта B GPIOB -> MODER |= GPIO_MODER_MODER6_0; // 01: General purpose output mode GPIOB -> ODR |= GPIO_ODR_6; // выключение светодиода "TR" // Init_TIM4(); //светодиод "EL" (панель пульта) //PB7(59) RCC -> AHBENR |= RCC_AHBENR_GPIOBEN; // Тактирование порта B GPIOB -> MODER |= GPIO_MODER_MODER7_0; // 01: General purpose output mode GPIOB -> ODR |= GPIO_ODR_7; // выключение светодиода "EL" // Init_TIM4(); //светодиод "ERR" (панель пульта) //PB5(57) RCC -> AHBENR |= RCC_AHBENR_GPIOBEN; // Тактирование порта B GPIOB -> MODER |= GPIO_MODER_MODER5_0; // 01: General purpose output mode GPIOB -> ODR |= GPIO_ODR_5; // выключение светодиода "ERR" // Init_TIM3(); MX_GPIO_Init(); MX_CAN_Init(); /* USER CODE BEGIN 2 */ Can_Data_Tx[0] = 1; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { Can_Data_Tx[0] = 1; Can_Data_Tx[1] = 0xf0; HAL_CAN_AddTxMessage(&hcan, &TxHeader, Can_Data_Tx, &sFilterConfig); GPIOA -> ODR ^= GPIO_ODR_3; HAL_Delay(200); Can_Data_Tx[0] = 2; Can_Data_Tx[1] = 0xf0; HAL_CAN_AddTxMessage(&hcan, &TxHeader, Can_Data_Tx, &sFilterConfig); GPIOA -> ODR ^= GPIO_ODR_3; HAL_Delay(200); Can_Data_Tx[0] = 3; Can_Data_Tx[1] = 0xf0; HAL_CAN_AddTxMessage(&hcan, &TxHeader, Can_Data_Tx, &sFilterConfig); GPIOA -> ODR ^= GPIO_ODR_3; HAL_Delay(200); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses 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_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } } /** * @brief CAN Initialization Function * @param None * @retval None */ static void MX_CAN_Init(void) { /* USER CODE BEGIN CAN_Init 0 */ /* USER CODE END CAN_Init 0 */ /* USER CODE BEGIN CAN_Init 1 */ /* USER CODE END CAN_Init 1 */ hcan.Instance = CAN; hcan.Init.Prescaler = 200; hcan.Init.Mode = CAN_MODE_LOOPBACK; hcan.Init.SyncJumpWidth = CAN_SJW_2TQ; hcan.Init.TimeSeg1 = CAN_BS1_13TQ; hcan.Init.TimeSeg2 = CAN_BS2_2TQ; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.AutoBusOff = ENABLE; hcan.Init.AutoWakeUp = DISABLE; hcan.Init.AutoRetransmission = ENABLE; hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TransmitFifoPriority = ENABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN CAN_Init 2 */ sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { Error_Handler(); } HAL_CAN_Start(&hcan); HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING); HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING); HAL_CAN_ActivateNotification(&hcan, CAN_IT_ERROR); TxHeader.StdId = 0x122; TxHeader.ExtId = 0xff; TxHeader.IDE = CAN_ID_EXT; TxHeader.DLC = 8; TxHeader.TransmitGlobalTime = DISABLE; TxHeader.RTR = CAN_RTR_DATA; /* USER CODE END CAN_Init 2 */ } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ /* 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****/ К сожалению, данный пример не работает. - судя по светодиоду отправки и по осциллограмме между CAN_H и CAN_L, шина работает. - но вот приёмник не работает. Прошу помощи форумчан. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба Зачем создавать две темы с одинаковой сутью? А по делу - даже видео называется "...странности HAL", так может просто написать свое по мануалу на МК? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nickson.b.k 0 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба 16 минут назад, Arlleex сказал: Зачем создавать две темы с одинаковой сутью? А по делу - даже видео называется "...странности HAL", так может просто написать свое по мануалу на МК? А может лучше не выпендриваться, а помочь)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nickson.b.k 0 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба Первая часть моей задачи заработала.Я вернулся на страницу Куба, где выставляются настройки периферии, и там включил все прерывания.В рамках одного устройства данные отправляются и принимаются.Теперь буду пробовать объединить два устройства.- Одно устройство будет находиться в режиме CAN_MODE_LOOPBACK. Получается, что оно будет отправлять кадры на второе устрой и принимать кадры от самого себя же.- А второе устройство будет в CAN_MODE_NORMAL. И будет закомментирован цикл отправки. Получается, что второе устройство будет постоянно находится в ожидании сообщения. И если сообщение придёт, то оно в такт с первым будет моргать светодиодом. Ну вот прикол и случился.- Устройство передающее отправляет сообщения на второе и слышит само себя,- но вот второе устройство молчит.Такая же ситуация, если оба устройства перевести в CAN_MODE_NORMAL.Прошу помощи. Что сейчас может быть не так??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 11 октября, 2021 Опубликовано 11 октября, 2021 · Жалоба Пардон, но не увидел включение тактирования CAN. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 2 11 октября, 2021 Опубликовано 11 октября, 2021 · Жалоба Если второе устройство только слушает, его стоило в режим Silent выставить, а не normal. Посмотрите шину осциллографом: идут ли в ней данные. Если идут, проверьте, не перепутали ли CANL/CANH. Если не перепутали, то проверяйте, что там у вас с настройками принимающей стороны. Лучше всего было бы, как уже неоднократно советовали, настроить по даташиту (взяв за образец сниппет), тогда хотя бы можно будет сюда выложить код настройки, чтобы люди посмотрели и посоветовали. В дебрях хала никто ковыряться не будет, потому что никто его не использует! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться