Koteyk0o 0 6 марта, 2019 Опубликовано 6 марта, 2019 (изменено) · Жалоба Всем привет Использую stm32f103c8t6 в связке с MCP2551, с другой стороны к нему подключен CAN Shield для Arduino, чтобы ловить пакеты. При включении со стороны STM32 приходят 2 пустых пакета с заголовком (насколько я понимаю) После этого STM32 уходит в Hard Fault, тактирование я вроде бы настроил правильно, кванты времени выставил для скорости 500 кбит Код генерировал в STM32CubeMX, а отладку провожу в Keil uVision5 Честно говоря это мои первые попытки работы с CAN протоколом, да и до этого я с STM32 не работал, но похоже я что-то делаю не так #include "main.h" CAN_HandleTypeDef hcan; void SystemClock_Config(void); static void CAN_Data_Send(void); static void MX_GPIO_Init(void); static void MX_CAN_Init(void); void CAN_Data_Send(void){ CAN_TxHeaderTypeDef Tx_Header; Tx_Header.StdId = 0x201; Tx_Header.IDE = CAN_ID_STD; Tx_Header.RTR = CAN_RTR_DATA; Tx_Header.DLC = 0x08; uint8_t Tx_Data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, (uint32_t *)CAN_TX_MAILBOX0); } int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_CAN_Init(); while (1){ HAL_Delay(500); CAN_Data_Send(); HAL_GPIO_TogglePin(GPIOC, CAN_Error_LED_Pin); } } void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_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(); } 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(); } } static void MX_CAN_Init(void){ hcan.Instance = CAN1; hcan.Init.Prescaler = 9; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_4TQ; hcan.Init.TimeSeg2 = CAN_BS2_3TQ; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.AutoBusOff = DISABLE; hcan.Init.AutoWakeUp = ENABLE; hcan.Init.AutoRetransmission = ENABLE; hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TransmitFifoPriority = DISABLE; if (HAL_CAN_Init(&hcan) != HAL_OK){ Error_Handler(); } } static void MX_GPIO_Init(void){ GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); HAL_GPIO_WritePin(CAN_Error_LED_GPIO_Port, CAN_Error_LED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_Output_GPIO_Port, LED_Output_Pin, GPIO_PIN_RESET); GPIO_InitStruct.Pin = CAN_Error_LED_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(CAN_Error_LED_GPIO_Port, &GPIO_InitStruct); GPIO_InitStruct.Pin = Button_1_Pin|Button_2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = LED_Output_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(LED_Output_GPIO_Port, &GPIO_InitStruct); } void Error_Handler(void){ } Изменено 6 марта, 2019 пользователем Koteyk0o Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба 29 minutes ago, Koteyk0o said: После этого STM32 уходит в Hard Fault Расшифруйте причину hardfault. В книге Дж. Ю прекрасно написано как это сделать для cortex-m0/m3/m4(f). Ибо причины могут быть совершенно разные. А некоторые даже вполне "безобидные" (например, невыровненный доступ, включается принудительно). Хотя, скорее всего, какая-нибудь ошибка доступа к памяти (выход за границы массива, неаккуратная работа с указателями). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба Верно-верно. Что-то не вижу буфер для CanTxMsgTypeDef *pTxMsg в CAN_HandleTypeDef hcan. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koteyk0o 0 6 марта, 2019 Опубликовано 6 марта, 2019 (изменено) · Жалоба Да, похоже была ошибка с почтовым ящиком в функции HAL_CAN_AddTxMessage void CAN_Data_Send(void){ CAN_TxHeaderTypeDef Tx_Header; Tx_Header.StdId = 0x321; Tx_Header.ExtId = 0x01; Tx_Header.RTR = CAN_RTR_DATA; Tx_Header.IDE = CAN_ID_STD; Tx_Header.DLC = 2; uint32_t mail_Box; uint8_t Tx_Data[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box); } С таким кодом контроллер работает, мигает встроенным светодиодом, функция отправки работает, отправка возвращает HAL_OK. Но. После отправки ОДНОГО сообщения шина сходит с ума, и ардуина с CAN Shield принимает кучу одинаковых пустых сообщений в огромнейшем колличестве до перезагрузки stm32 Я так понимаю это уже какая-то аппаратная проблема? Потому что по дебагу вроде бы все отлично, отправляется сообщение, дальше дергается нога GPIO, задержка, и так по кругу, все как и должно быть. Изменено 6 марта, 2019 пользователем Koteyk0o Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 6 марта, 2019 Опубликовано 6 марта, 2019 (изменено) · Жалоба CAN контроллер на STM не видит доставки сообщения. 1. Ошибка в физике CAN. 2. Никто не отвечает Acknowledgement. И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда? А после HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box); не нужно дождаться окончания передачи сбросить мэйлбокс? ( В версии HAL, что я использую, такой функции нет, поэтом не знаю чем она завершается) Изменено 6 марта, 2019 пользователем Andrew_Q Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koteyk0o 0 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба 12 минут назад, Andrew_Q сказал: CAN контроллер на STM не видит доставки сообщения. 1. Ошибка в физике CAN. 2. Никто не отвечает Acknowledgement. И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда? А после HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box); не нужно дождаться окончания передачи сбросить мэйлбокс? ( В версии HAL, что я использую, такой функции нет, поэтом не знаю чем она завершается) Спасибо большое, отключил AutoRetransmission и все ок, данные передаются в нужном промежутке времени Цитата И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда? Передается не то, ID указан один, приходит вообще другое Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба Смотрите что конкретно делает HAL_CAN_AddTxMessage(). Что берет? Куда кладет? Как выбирает мэйлбокс? Как его освобождает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба У меня подозрение, что мы наблюдаем проблемы а) с битовой скоростью и б) с тем, что ардуина принимает всё подряд и не говорит, что принято с ошибкой. Осцилл у Вас есть? А ещё лучше - логический анализатор (подключать между контроллером и PHY'ем CAN'а). Советики: - объявите в настройках проекта дефайн USE_FULL_ASSERT. Очень помогает в отладке этого чёртова хала - иначе при ошибках вызова он "ест" любые комбинации параметров и падает в совершенно неожиданных местах. - как что-то заработает, верните назад авторетрансмит. Это полезная фича CAN'а. Иначе на более-менее загруженных шинах сообщения будут теряться (ну или придётся руками этот ретрансмит делать). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Koteyk0o 0 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба Все заработало, извиняюсь, мой косяк Если у кого-то принимаются неверные данные с помощью MCP2515 CAN модуля для ардуино, то проверьте какой у вас там установлен кварц. Обычно там стоит кварц на 16 МГц, но у меня почему-то стоял кварц на 8 МГц, из-за этого модуль работал неправильно. Его можно или перепаять, или поменять значения квантов времени в библиотеке 1 час назад, esaulenka сказал: У меня подозрение, что мы наблюдаем проблемы а) с битовой скоростью и б) с тем, что ардуина принимает всё подряд и не говорит, что принято с ошибкой. Осцилл у Вас есть? А ещё лучше - логический анализатор (подключать между контроллером и PHY'ем CAN'а). Советики: - объявите в настройках проекта дефайн USE_FULL_ASSERT. Очень помогает в отладке этого чёртова хала - иначе при ошибках вызова он "ест" любые комбинации параметров и падает в совершенно неожиданных местах. - как что-то заработает, верните назад авторетрансмит. Это полезная фича CAN'а. Иначе на более-менее загруженных шинах сообщения будут теряться (ну или придётся руками этот ретрансмит делать). Спасибо за советы, ретрансмит включу обратно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Andrew_Q 0 6 марта, 2019 Опубликовано 6 марта, 2019 · Жалоба А ларчик просто не открывался :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kostet2010 0 29 ноября, 2019 Опубликовано 29 ноября, 2019 · Жалоба ребята расскажите по подробней ( прям вообще подробно) .как Koteyk0o собрал это все . меня итересует к каким пинам он цеплялся к stm32f103c8t6 и как и что делать в STM32CubeMX. сам Koteyk0o не отвечает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Behram 0 30 ноября, 2019 Опубликовано 30 ноября, 2019 (изменено) · Жалоба Это так не работает. Думаю, сначала стоить изучить как вообще КАН работает. Спойлер https://www.drive2.ru/c/472295770540736550/ Изменено 30 ноября, 2019 пользователем Behram Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба 17 hours ago, kostet2010 said: ребята расскажите по подробней ( прям вообще подробно) .как Koteyk0o собрал это все . меня итересует к каким пинам он цеплялся к stm32f103c8t6 и как и что делать в STM32CubeMX. сам Koteyk0o не отвечает. Поскольку Вы спрашиваете, на какие пины цеплять CAN, то это не тот вариант, когда можно соединить 3-4 проводка и "все работает". CAN - это уже настоящий сетевой контроллер, очень младший брат Ethernet. И погонять его в стиле UART без полного понимания процесса (хотябы "в общем") не получится. Пины на процессоре и плате, соответстующие CAN Вы можете легко "вычислить" из принципиальной схемы платы, а если ее (схемы) нет - то из даташита на SRM32F103 и прозвонки пинов. Для "выхода" на шину CAN нужен еще трансивер (8-лапковый soic). Вам надо ступить на "пусть самурая", те начать чтение даташитов и изучение интерфейса узла CAN (библиотечных функций и обращения с ними) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 1 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба Для STM32F0x2 я вот такую штуку сделал. Обрабатываю разные ошибки, и если на шине нет слушателя, то получаю соответствующий статус (и делаю abort передачи). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kostet2010 0 30 ноября, 2019 Опубликовано 30 ноября, 2019 · Жалоба 9 часов назад, k155la3 сказал: Поскольку Вы спрашиваете, на какие пины цеплять CAN, то это не тот вариант, когда можно соединить 3-4 проводка и "все работает". CAN - это уже настоящий сетевой контроллер, очень младший брат Ethernet. И погонять его в стиле UART без полного понимания процесса (хотябы "в общем") не получится. Пины на процессоре и плате, соответстующие CAN Вы можете легко "вычислить" из принципиальной схемы платы, а если ее (схемы) нет - то из даташита на SRM32F103 и прозвонки пинов. Для "выхода" на шину CAN нужен еще трансивер (8-лапковый soic). Вам надо ступить на "пусть самурая", те начать чтение даташитов и изучение интерфейса узла CAN (библиотечных функций и обращения с ними) я спросил на какие пины цеплять кан-шилд MCP2551 к stm32f103c8t6 и как это все в STM32CubeMX красиво прорисовать. 14 часов назад, Behram сказал: Это так не работает. Думаю, сначала стоить изучить как вообще КАН работает. там другая микросхема. я же спрашиваю(интересуюсь) как к stm32f103c8t6 подключить кан-шилд MCP2515 CAN шина модуль TJA1050 приемник SPI модуль для Arduino и как это все прописать в STM32CubeMX Скрыть контент https://www.drive2.ru/c/472295770540736550/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться