stm32407vetx 에서 두 개의 can속도를 동시에 받고자 can1, can2를 모두 사용하려 합니다. can1는 250kbps, can2는 500kbps로 설정해주었습니다.
그런데 can2로는 어떤 can 메시지도 수신되지 않고 있습니다.
can2에서 사용한 can 트랜시버를 can1에 연결하고 500kbps으로 설정하여 can1에서 테스트해보니 can 메시지가 잘 수신됩니다.
각 필터들은 아래와 같이 설정해주었습니다.
혹시 can2를 사용하기 위해 추가적으로 필요한 설정이 있을까요?
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file can.c
* @brief This file provides code for the configuration
* of the CAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "can.h"
/* USER CODE BEGIN 0 */
extern LOG syslog;
extern SYSTEM_STATE sys_state;
#ifdef ENABLE_MONITOR_CAN
extern CAN_RxHeaderTypeDef can_rx_header;
extern uint8_t can_rx_data[8];
uint8_t test1[1]={0};
#define LWS_CAN_ID_STANDARD 0x2B0
#define LWS_CAN_ID_CONFIG 0x7C0
// CCW 명령 코드
#define CCW_SET_ANGLE_ZERO 0x03
#define CCW_RESET_CALIBRATION 0x05
/* CAN message received */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
int ret = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can_rx_header, can_rx_data);
if (ret != HAL_OK) {
sys_state.CAN = false;
HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);
DEBUG_MSG("[%8lu] [ERR] CAN RX failed: %d\r\n", HAL_GetTick(), ret);
syslog.value[0] = (uint8_t)ret;
SYS_LOG(LOG_ERROR, CAN, CAN_ERR);
}
if (sys_state.CAN != true) {
sys_state.CAN = true;
HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_SET);
}
*(uint64_t *)syslog.value = *(uint64_t *)can_rx_data;
SYS_LOG(LOG_INFO, CAN, can_rx_header.StdId);
}
/* CAN error occured */
void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) {
sys_state.CAN = false;
HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);
DEBUG_MSG("[%8lu] [ERR] CAN ERROR occured\r\n", HAL_GetTick());
*(uint32_t *)syslog.value = HAL_CAN_GetError(hcan);
SYS_LOG(LOG_ERROR, CAN, CAN_ERR);
HAL_CAN_ResetError(hcan);
}
/* CAN RX FIFO full */
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) {
sys_state.CAN = false;
HAL_GPIO_WritePin(GPIOE, LED_CAN_Pin, GPIO_PIN_RESET);
DEBUG_MSG("[%8lu] [ERR] CAN RX FIFO full\r\n", HAL_GetTick());
*(uint32_t *)syslog.value = HAL_CAN_GetState(hcan);
SYS_LOG(LOG_ERROR, CAN, CAN_ERR);
HAL_CAN_ResetError(hcan);
}
void HAL_CAN_RxFifo0OverrunCallback(CAN_HandleTypeDef *hcan) {
HAL_GPIO_WritePin(GPIOE, LED_ERR_SYS_Pin, GPIO_PIN_SET);
}
int CAN_SETUP(void) {
CAN_FilterTypeDef CAN_FILTER;
CAN_FILTER.FilterBank = 0;
CAN_FILTER.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FILTER.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FILTER.FilterIdHigh = 0x0;
CAN_FILTER.FilterMaskIdHigh = 0x0;
CAN_FILTER.FilterIdLow = 0x0;
CAN_FILTER.FilterMaskIdLow = 0x0;
CAN_FILTER.FilterFIFOAssignment = CAN_RX_FIFO0;
CAN_FILTER.FilterActivation = ENABLE;
CAN_FILTER.SlaveStartFilterBank = 14; // CAN1과 CAN2의 필터 뱅크 분할 지점 설정
CAN_FilterTypeDef CAN_FILTER1;
CAN_FILTER1.FilterBank = 14;
CAN_FILTER1.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FILTER1.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FILTER1.FilterIdHigh = 0x0;
CAN_FILTER1.FilterMaskIdHigh = 0x0;
CAN_FILTER1.FilterIdLow = 0x0;
CAN_FILTER1.FilterMaskIdLow = 0x0;
CAN_FILTER1.FilterFIFOAssignment = CAN_RX_FIFO0;
CAN_FILTER1.FilterActivation = ENABLE;
CAN_FILTER1.SlaveStartFilterBank = 14; // CAN1과 CAN2의 필터 뱅크 분할 지점 설정
int ret = HAL_CAN_ConfigFilter(&hcan1, &CAN_FILTER);
if (ret != HAL_OK) {
return 1;
}
ret = HAL_CAN_Start(&hcan1);
if (ret != HAL_OK) {
return 2;
}
ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
if (ret != HAL_OK) {
return 3;
}
ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_FULL);
if (ret != HAL_OK) {
return 4;
}
ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_OVERRUN);
if (ret != HAL_OK) {
return 5;
}
ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_BUSOFF);
if (ret != HAL_OK) {
return 6;
}
ret = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_ERROR);
if (ret != HAL_OK) {
return 7;
}
ret = HAL_CAN_ConfigFilter(&hcan2, &CAN_FILTER1);
if (ret != HAL_OK) {
return -1;
}
ret = HAL_CAN_Start(&hcan2);
if (ret != HAL_OK) {
return -2;
}
ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
if (ret != HAL_OK) {
return -3;
}
ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_FULL);
if (ret != HAL_OK) {
return -4;
}
ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_OVERRUN);
if (ret != HAL_OK) {
return -5;
}
ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_BUSOFF);
if (ret != HAL_OK) {
return -6;
}
ret = HAL_CAN_ActivateNotification(&hcan2, CAN_IT_ERROR);
if (ret != HAL_OK) {
return -7;
}
HAL_StatusTypeDef CAN_SendMessage(uint32_t id, uint8_t *data, uint8_t length) {
CAN_TxHeaderTypeDef txHeader;
uint32_t txMailbox;
txHeader.DLC = length;
txHeader.StdId = id;
txHeader.IDE = CAN_ID_STD;
txHeader.RTR = CAN_RTR_DATA;
return HAL_CAN_AddTxMessage(&hcan2, &txHeader, data, &txMailbox);
}
// 보정 상태 확인 및 보정 수행 함수
void Calibrate_Sensor() {
uint8_t canData[8] = {0};
// 보정 상태 초기화
canData[0] = CCW_RESET_CALIBRATION;
if (CAN_SendMessage(LWS_CAN_ID_CONFIG, canData, 8) != HAL_OK) {
// 에러 처리
}
HAL_Delay(100); // 보정 초기화 후 약간의 지연
// 보정 수행
canData[0] = CCW_SET_ANGLE_ZERO;
if (CAN_SendMessage(LWS_CAN_ID_CONFIG, canData, 8) != HAL_OK) {
// 에러 처리
}
}
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData1[8] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // CCW 값이 0x03인 메시지
uint8_t TxData[8] = {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // CCW 값이 0x03인 메시지
uint32_t TxMailbox;
TxHeader.StdId = 0x7C0; // CAN ID 설정
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 8; // 데이터 길이 (8바이트)
TxHeader.TransmitGlobalTime = DISABLE;
if (HAL_CAN_AddTxMessage(&hcan2, &TxHeader, TxData1, &TxMailbox) != HAL_OK) {
// 전송 실패 처리
Error_Handler();
}
// 메시지 전송 시도
if (HAL_CAN_AddTxMessage(&hcan2, &TxHeader, TxData, &TxMailbox) != HAL_OK) {
// 전송 실패 처리
Error_Handler();
}
Calibrate_Sensor();
if (HAL_CAN_IsTxMessagePending(&hcan2, TxMailbox) == 0) {
// 송신이 성공적으로 완료됨
HAL_GPIO_WritePin(GPIOE, LED_SD_Pin, GPIO_PIN_SET);
}
return SYS_OK;
}
#endif
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 12;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_11TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
/* CAN2 init function */
void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN2_Init 0 */
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 6;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_11TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = ENABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
/* USER CODE END CAN2_Init 2 */
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOD_CLK_ENABLE();
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* CAN2 clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_TX_IRQn);
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN1 GPIO Configuration
PD0 ------> CAN1_RX
PD1 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0|GPIO_PIN_1);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */
/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN2_CLK_DISABLE();
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);
/* CAN2 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN2_TX_IRQn);
HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */
/* USER CODE END CAN2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */