STM32F429 не получает сообщение CAN
Я использую микроконтроллер STM32F429, и мне нужно реализовать связь по шине CAN между CAN2 и PCAN View. Я могу передать сообщение от CAN2, но не могу получить никакого сообщения. Я использую трансивер CAN TJA1041A в микроконтроллере. Проблема в том, что что во время отладки моя шина CAN должным образом инициализируется, но она не передается команде приема, хотя я инициализировал FIFO0. При этом я прилагаю программу для дальнейшего использования. Я использовал для программирования STM32 HAL Cube.
/**
******************************************************************************
* File Name : main.c
* Date : 05/12/2014 09:43:55
* Description : Main program body
******************************************************************************
*
* COPYRIGHT(c) 2014 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 "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
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();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_CAN2_Init();
/* USER CODE BEGIN 2 */
__GPIOD_CLK_ENABLE();
GPIO_InitTypeDef GPIO_Initpins;
GPIO_Initpins.Mode = GPIO_MODE_OUTPUT_PP ;
GPIO_Initpins.Pin = GPIO_PIN_5|GPIO_PIN_7;
GPIO_Initpins.Pull = GPIO_NOPULL ;
HAL_GPIO_Init(GPIOD, &GPIO_Initpins);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5|GPIO_PIN_7, GPIO_PIN_SET);
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
/* Infinite loop */
CanTxMsgTypeDef TxMess;
TxMess.StdId = 0x123;
TxMess.DLC = 0x0;
TxMess.Data[0] = 0x12;
TxMess.IDE = 0;
TxMess.RTR = 0;
hcan2.pTxMsg = &TxMess;
HAL_CAN_Transmit(&hcan2,50);
HAL_Delay(500);
/* USER CODE END 2 */
CanRxMsgTypeDef RMess;
RMess.FIFONumber = CAN_FIFO1;
RMess.FMI = 14;
RMess.StdId = 0x541;
RMess.DLC = 0;
RMess.RTR = 0;
RMess.IDE = CAN_ID_STD;
hcan2.pRxMsg = &RMess;
HAL_CAN_Receive_IT(&hcan2,CAN_FIFO1);
/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)
{
HAL_CAN_Receive(&hcan2,CAN_FIFO1,0);
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
/* CAN1 init function */
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 16;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_1TQ;
hcan1.Init.BS2 = CAN_BS2_1TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
HAL_CAN_Init(&hcan1);
/*CAN_FilterConfTypeDef CAN_Filters;
CAN_Filters.BankNumber = 0;
CAN_Filters.FilterActivation = ENABLE;
CAN_Filters.FilterFIFOAssignment = CAN_FILTER_FIFO0 ;
CAN_Filters.FilterIdHigh = 0x00;
CAN_Filters.FilterIdLow = 0x00;
CAN_Filters.FilterMaskIdHigh = 0x00;
CAN_Filters.FilterMaskIdLow = 0x00;
CAN_Filters.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_Filters.FilterNumber = 0;
CAN_Filters.FilterScale = CAN_FILTERSCALE_32BIT;
HAL_CAN_ConfigFilter(&hcan1, &CAN_Filters);*/
}
/* CAN2 init function */
void MX_CAN2_Init(void)
{
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 2;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SJW = CAN_SJW_1TQ;
hcan2.Init.BS1 = CAN_BS1_5TQ;
hcan2.Init.BS2 = CAN_BS2_2TQ;
hcan2.Init.TTCM = DISABLE;
hcan2.Init.ABOM = DISABLE;
hcan2.Init.AWUM = DISABLE;
hcan2.Init.NART = DISABLE;
hcan2.Init.RFLM = DISABLE;
hcan2.Init.TXFP = DISABLE;
HAL_CAN_Init(&hcan2);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__GPIOH_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
#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,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Спасибо
4 ответа
Если CAN2 может отправлять сообщения, конфигурации часов и главного-подчиненного между CAN1 (ведущим) и CAN2 (ведомым) в порядке.
Если есть проблемы с получением, они должны быть связаны с конфигурацией FIFO или конфигурацией фильтра приемки.
Вы настроили FIFO, но похоже, что вы не настроили "CAN2StartBank". CAN1 и CAN2 также совместно используют банки фильтров, и по умолчанию банки делятся пополам, поэтому первая половина используется для CAN1, а вторая половина для CAN2.
Из главы справочного руководства "Регистры CAN-фильтров":
Основной регистр фильтра CAN (CAN_FMR)
Смещение адреса: 0x200 Значение сброса: 0x2A1C 0E01 Все биты этого
регистр устанавливается и очищается программным обеспечением. ... CAN2SB[5:0]: стартовый банк CAN2 Эти биты устанавливаются и очищаются
программного обеспечения. Они определяют стартовый банк для интерфейса CAN2 (Slave) в
диапазон от 0 до 27. Примечание. Когда CAN2SB[5:0] = 28d, все фильтры
CAN1 может быть использован. Когда CAN2SB [5: 0] установлен на 0, фильтры CAN1 не назначаются.
Вы устанавливаете
CAN_Filters.BankNumber = 0;
но вы должны выбрать банк из второй половины с настройками по умолчанию или изменить значение CAN2StartBank на 0, если вам не нужен CAN1.
Вы также должны убедиться, что Фильтры находятся в режиме инициализации во время настройки фильтра.
Основной регистр фильтра CAN (CAN_FMR)
Бит 0 FINIT: режим инициализации фильтра Режим инициализации для банков фильтров
0: режим активных фильтров.
1: режим инициализации для фильтров
К сожалению, сейчас у меня нет аппаратного обеспечения, чтобы проверить это самостоятельно.
Попробуйте установить Filterbank более 14 для интерфейса CAN2, похоже, есть ошибка в настройке банка. У нас та же проблема, но после настройки 15 она работает.
Вы должны взять FilterNumber 14 для интерфейса CAN2; по умолчанию после RESET биты CAN2SB[5:0] инициализируются с 01110 = 14 декабря, поэтому предполагается, что интерфейс CAN1 будет использовать фильтры 0..13 и CAN2 14..27. Вы можете изменить стартовый банк с 14 на любое значение в пределах 1..27 методом CAN_SlaveStartBank(uint_8).
Проверьте регистр CAN FMR. Значение CAN2SB по умолчанию равно 0x0E в периферийных регистрах CAN1 и CAN2. Вы должны установить CAN1FMR->CANS2B на 0x00, а CAN2FMR-> CANS2B на 0x0E (любое, но не те же числа). Итак, вы разделяете набор фильтров пополам, и он отлично работает