测试下CAN通信。
一、CAN硬件接口
1.1、硬件电路图
1.2、引脚配置
使用FDCAN1接口,需要外接收发器芯片。
1.3、硬件连接
二、软件
2.1、fdcan.c
#include "main.h"
#include "fdcan/fdcan.h"
FDCAN_HandleTypeDef g_fdcanx_handle; /* FDCAN1句柄 */
FDCAN_TxHeaderTypeDef g_fdcanx_txheade; /* 发送消息 */
FDCAN_RxHeaderTypeDef g_fdcanx_rxheade; /* 接收消息 */
/**
* @brief FDCAN MSP Initialization
* This function configures the hardware resources used in this example
* @param hfdcan: FDCAN handle pointer
* @retval None
*/
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(hfdcan->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspInit 0 */
/* USER CODE END FDCAN1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInitStruct.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
// if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
// {
// Error_Handler();
// }
/* Peripheral clock enable */
__HAL_RCC_FDCAN_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**FDCAN1 GPIO Configuration
PB9 ------> FDCAN1_TX
PB8 ------> FDCAN1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN FDCAN1_MspInit 1 */
/* USER CODE END FDCAN1_MspInit 1 */
}
}
/**
* @brief FDCAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hfdcan: FDCAN handle pointer
* @retval None
*/
void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* hfdcan)
{
if(hfdcan->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspDeInit 0 */
/* USER CODE END FDCAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_FDCAN_CLK_DISABLE();
/**FDCAN1 GPIO Configuration
PB9 ------> FDCAN1_TX
PB8 ------> FDCAN1_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9|GPIO_PIN_8);
/* USER CODE BEGIN FDCAN1_MspDeInit 1 */
/* USER CODE END FDCAN1_MspDeInit 1 */
}
}
uint8_t fdcan_init(uint16_t presc, uint8_t tsjw, uint16_t ntsg1, uint8_t ntsg2, uint32_t mode)
{
FDCAN_FilterTypeDef fdcan_filterconfig;
HAL_FDCAN_DeInit(&g_fdcanx_handle); /* 先清除以前的设置 */
g_fdcanx_handle.Instance = FDCAN1;
g_fdcanx_handle.Init.FrameFormat = FDCAN_FRAME_CLASSIC; /* 传统模式 */
g_fdcanx_handle.Init.Mode = mode; /* 模式设置 */
g_fdcanx_handle.Init.AutoRetransmission = DISABLE; /* 关闭自动重传!传统模式下一定要关闭!!! */
g_fdcanx_handle.Init.TransmitPause = DISABLE; /* 关闭传输暂停 */
g_fdcanx_handle.Init.ProtocolException = DISABLE; /* 关闭协议异常处理 */
g_fdcanx_handle.Init.NominalPrescaler = presc; /* 分频系数 */
g_fdcanx_handle.Init.NominalSyncJumpWidth = tsjw; /* 重新同步跳跃宽度 */
g_fdcanx_handle.Init.NominalTimeSeg1 = ntsg1; /* tsg1范围:2~256 */
g_fdcanx_handle.Init.NominalTimeSeg2 = ntsg2; /* tsg2范围:2~128 */
g_fdcanx_handle.Init.MessageRAMOffset = 0; /* 信息RAM偏移 */
g_fdcanx_handle.Init.StdFiltersNbr = 0; /* 标准信息ID滤波器编号 */
g_fdcanx_handle.Init.ExtFiltersNbr = 0; /* 扩展信息ID滤波器编号 */
g_fdcanx_handle.Init.RxFifo0ElmtsNbr = 1; /* 接收FIFO0元素编号 */
g_fdcanx_handle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; /* 接收FIFO0元素大小:8字节 */
g_fdcanx_handle.Init.RxBuffersNbr = 0; /* 接收FIFO0元素编号 */
g_fdcanx_handle.Init.TxEventsNbr = 0; /* 发送事件编号 */
g_fdcanx_handle.Init.TxBuffersNbr = 0; /* 发送缓冲编号 */
g_fdcanx_handle.Init.TxFifoQueueElmtsNbr = 1; /* 发送FIFO序列元素编号 */
g_fdcanx_handle.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; /* 发送FIFO序列模式 */
g_fdcanx_handle.Init.TxElmtSize = FDCAN_DATA_BYTES_8; /* 发送大小:8字节 */
if (HAL_FDCAN_Init(&g_fdcanx_handle) != HAL_OK)
{
return 1; /* 初始化 */
}
fdcan_filterconfig.IdType = FDCAN_STANDARD_ID; /* 标准ID */
fdcan_filterconfig.FilterIndex = 1; /* 滤波器索引 */
fdcan_filterconfig.FilterType = FDCAN_FILTER_RANGE;//FDCAN_FILTER_MASK; /* 滤波器类型 */
fdcan_filterconfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; /* 过滤器0关联到FIFO0 */
fdcan_filterconfig.FilterID1 = 0x0321; /* 32位ID */
fdcan_filterconfig.FilterID2 = 0x0322; /* 如果FDCAN配置为传统模式的话,这里是32位掩码 */
/* 过滤器配置 */
if (HAL_FDCAN_ConfigFilter(&g_fdcanx_handle, &fdcan_filterconfig) != HAL_OK)
{
return 2; /* 滤波器初始化 */
}
HAL_FDCAN_Start(&g_fdcanx_handle); /* 开启FDCAN */
HAL_FDCAN_ActivateNotification(&g_fdcanx_handle, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
return 0;
}
uint8_t fdcan_send_msg(uint8_t *msg, uint32_t len)
{
g_fdcanx_txheade.Identifier = 0x12; /* 32位ID */
g_fdcanx_txheade.IdType = FDCAN_STANDARD_ID; /* 标准ID */
g_fdcanx_txheade.TxFrameType = FDCAN_DATA_FRAME; /* 使用标准帧 */
g_fdcanx_txheade.DataLength = len; /* 数据长度 */
g_fdcanx_txheade.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
g_fdcanx_txheade.BitRateSwitch = FDCAN_BRS_OFF; /* 关闭速率切换 */
g_fdcanx_txheade.FDFormat = FDCAN_CLASSIC_CAN; /* 传统的CAN模式 */
g_fdcanx_txheade.TxEventFifoControl = FDCAN_NO_TX_EVENTS; /* 无发送事件 */
g_fdcanx_txheade.MessageMarker = 0;
if (HAL_FDCAN_AddMessageToTxFifoQ(&g_fdcanx_handle, &g_fdcanx_txheade, msg) != HAL_OK) /* 发送消息 */
{
return 1;
}
return 0;
}
uint8_t fdcan_receive_msg(uint8_t *buf)
{
if (HAL_FDCAN_GetRxMessage(&g_fdcanx_handle, FDCAN_RX_FIFO0, &g_fdcanx_rxheade, buf) != HAL_OK) /* 接收数据 */
{
return 0;
}
return g_fdcanx_rxheade.DataLength>>16;
}
2.2、main.c
#include "main.h"
#include "usart/usart.h"
#include "led/led.h"
#include "sdram/sdram.h"
#include "lcd/dsi_lcd.h"
#include "key/key.h"
#include "fdcan/fdcan.h"
static void MPU_Config(void);
static void SystemClock_Config(void);
static void CPU_CACHE_Enable(void);
static void Error_Handler(void);
int main(void)
{
uint8_t key_val=0;
uint8_t fdcan_txdat[20];
uint8_t fdcan_rxdat[20];
uint8_t js=0;
MPU_Config();
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config(); /* Configure the system clock to 400 MHz */
usart_init(115200);
init_sdram();
init_led();
led1_on();
init_key();
init_lcd();
fdcan_init(10, 8, 31, 8, FDCAN_MODE_NORMAL);
while(1)
{
js++;
fdcan_txdat[0]=js;
fdcan_txdat[1]=0x01;
fdcan_send_msg(fdcan_txdat, FDCAN_DLC_BYTES_8);
if(fdcan_receive_msg(fdcan_rxdat)!=0)
{
printf("rxdat: %2x %2x %2x %2x %2x %2x %2x %2x \r\n",fdcan_rxdat[0],fdcan_rxdat[1],fdcan_rxdat[2],fdcan_rxdat[3],\
fdcan_rxdat[4],fdcan_rxdat[5],fdcan_rxdat[6],fdcan_rxdat[7]);
}
HAL_Delay(200);
}
}
三、程序运行
3.1、CAN发送数据
3.2、CAN接收数据
本帖最后由 TL-LED 于 2024-1-3 11:04 编辑