STM32F103C8T6 CAN通信 HAL库
·
1、CUBEMAX配置:
时钟以及其他基础配置不在叙述,可以参考前面的文章STM32之CUBEMX及KEIL 5基础配置
主要看一下CAN的配置:


配置中断:

拓展一下时钟知识:CAN挂载在APB1总线上,STM32F103C8T6的APB1总线时钟频率为36MHz

2、程序代码:
定义CAN相关参数:
/* USER CODE BEGIN PTD */
/***************CAN相关参数******************************/
#define CAN_ID ((uint32_t)0x1314)
CAN_RxHeaderTypeDef CanRx; //接收消息报文信息
CAN_TxHeaderTypeDef CanTx; //发送消息报文信息
uint8_t RxData[8] = {0}; //接收数据区
uint8_t Flag_Rx = 0; //接收到数据的标志
uint32_t pTxMailbox = 0; //发送邮箱盒子
/* USER CODE END PTD */
CAN的基础配置:
/* USER CODE BEGIN PD */
HAL_StatusTypeDef Can_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
CanTx.StdId = 0x00;
CanTx.ExtId = CAN_ID;
CanTx.IDE = CAN_ID_EXT; //扩展帧模式
CanTx.RTR = CAN_RTR_DATA; //数据帧
CanTx.DLC = 8; //数据长度
CanTx.TransmitGlobalTime = DISABLE;//时间戳
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; //筛选器使能
sFilterConfig.FilterBank = 0; //筛选器0
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//指定将分配给过滤器的FIFO(0或1U)。
sFilterConfig.FilterIdHigh = ((CAN_ID<<3) & 0xFFFF0000)>>16; //ID的高16位
sFilterConfig.FilterIdLow = ((CAN_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA) & 0xFFFF; //ID的低16位,过滤接收扩展帧模式、数据帧
sFilterConfig.FilterMaskIdHigh = 0xFFFF;//高16位掩码,接收到的 ID 高 16 位与过滤器的 ID 高 16 位匹配时,消息才会通过;为0x0000时不做过滤
sFilterConfig.FilterMaskIdLow = 0xFFFF;//低16位掩码,接收到的 ID 低 16 位与过滤器的 ID 低 16 位匹配时,消息才会通过;为0x0000时不做过滤
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//32位
sFilterConfig.SlaveStartFilterBank = 0;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
return HAL_ERROR;
}
if(HAL_CAN_Start(&hcan) != HAL_OK) //启动CAN
{
return HAL_ERROR;
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//激活CAN_IT_RX_FIFO0_MSG_PENDING中断
{
return HAL_ERROR;
}
return HAL_OK;
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//报文接收中断
{
if(HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0, &CanRx, RxData) == HAL_OK)
{
Flag_Rx = 1;
}
}
/* USER CODE END PD */
MAIN函数中初始化:
/* USER CODE BEGIN 2 */
Can_Config();//CAN初始化
/* USER CODE END 2 */
循环中,配置CAN测试函数,接收到什么数据,就发送什么数据:
while (1)
{
if(Flag_Rx)//CAN标志位
{
Flag_Rx = 0;
if(HAL_CAN_AddTxMessage(&hcan, &CanTx, RxData, &pTxMailbox) != HAL_OK)
{
printf("Tx Fail\r\n");
}
memset(U2RxBuf, 0, 8);
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
3、上位机测试:
使用cangaroo上位机

选择需要的波特率和采样点:点击ok,板载三色灯会亮起,可以发送和接受CAN总线上的数据


数据收发测试图

更多推荐



所有评论(0)