CUBEMX配置说明
首先打开STM32CubeMX选择你开发的芯片型号,这里我选择的是F103R6Tx的芯片。然后第一步选择SYS里面的debug模式,如果用HAL库不进行SWD或JTAG配置,单片机只能进行下载一次程序,要进行第二次或更多次程序下载,需要按复位键(如果你的单片机有复位按键的话),或者用镊子夹住复位线路上的电容使其短路,点击Keil下载,再松开镊子。
然后RCC时钟源选择外部高速时钟,自接外部晶振
然后配置时钟树
配置CAN相关参数,波特率设定为500K,时钟频率为36M,
波特率计算公式:36M/9/(5+2+1)=500K.
模式选择正常通讯
使能CAN RX0中断,代表的是接受邮箱0的接收中断
CAN相关函数说明
HAL_CAN_Start //开启CAN通讯
HAL_CAN_Stop //关闭CAN通讯
HAL_CAN_RequestSleep //尝试进入休眠模式
HAL_CAN_WakeUp //从休眠模式中唤醒
HAL_CAN_IsSleepActive //检查是否成功进入休眠模式
HAL_CAN_AddTxMessage //向 Tx 邮箱中增加一个消息,并且激活对应的传输请求
HAL_CAN_AbortTxRequest //请求中断传输
HAL_CAN_IsTxMessagePending //检查是否有传输请求在指定的 Tx 邮箱上等待
HAL_CAN_GetRxMessage //从Rx FIFO 收取一个 CAN 帧
过滤器的配置
关于过滤器的说明与详解,可以参考这个
链接: 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结.
这个博客里面讲解的很详细
CUBEMX并没有初始化过滤器的相关内容,需要我们自己添加
void MX_CAN1_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_5TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = ENABLE;
hcan.Init.AutoWakeUp = ENABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 0;//过滤器0 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
sFilterConfig.FilterIdHigh = 0x0000; //设置过滤器ID高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器ID低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
{
Error_Handler();
}
}
回调函数的改写
CAN_TxHeaderTypeDef TXHeader;
CAN_RxHeaderTypeDef RXHeader;
uint8_t TXmessage[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
uint8_t RXmessage[8];
uint32_t pTxMailbox = 0;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//接受邮箱0挂起中断回调函数
{
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RXHeader,RXmessage);//获取数据
}
}
发送函数的改写
void CAN_senddata(CAN_HandleTypeDef *hcan)
{
TXHeader.StdId=0x00000000;
TXHeader.ExtId=0x12345000;
TXHeader.DLC=8;
TXHeader.IDE=CAN_ID_EXT;
TXHeader.RTR=CAN_RTR_DATA;
TXHeader.TransmitGlobalTime = DISABLE;
HAL_CAN_AddTxMessage(hcan,&TXHeader,TXmessage,&pTxMailbox);
}
CUBEMX配置说明
首先打开STM32CubeMX选择你开发的芯片型号,这里我选择的是F103R6Tx的芯片。然后第一步选择SYS里面的debug模式,如果用HAL库不进行SWD或JTAG配置,单片机只能进行下载一次程序,要进行第二次或更多次程序下载,需要按复位键(如果你的单片机有复位按键的话),或者用镊子夹住复位线路上的电容使其短路,点击Keil下载,再松开镊子。
然后RCC时钟源选择外部高速时钟,自接外部晶振
然后配置时钟树
配置CAN相关参数,波特率设定为500K,时钟频率为36M,
波特率计算公式:36M/9/(5+2+1)=500K.
模式选择正常通讯
使能CAN RX0中断,代表的是接受邮箱0的接收中断
CAN相关函数说明
HAL_CAN_Start //开启CAN通讯
HAL_CAN_Stop //关闭CAN通讯
HAL_CAN_RequestSleep //尝试进入休眠模式
HAL_CAN_WakeUp //从休眠模式中唤醒
HAL_CAN_IsSleepActive //检查是否成功进入休眠模式
HAL_CAN_AddTxMessage //向 Tx 邮箱中增加一个消息,并且激活对应的传输请求
HAL_CAN_AbortTxRequest //请求中断传输
HAL_CAN_IsTxMessagePending //检查是否有传输请求在指定的 Tx 邮箱上等待
HAL_CAN_GetRxMessage //从Rx FIFO 收取一个 CAN 帧
过滤器的配置
关于过滤器的说明与详解,可以参考这个
链接: 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结.
这个博客里面讲解的很详细
CUBEMX并没有初始化过滤器的相关内容,需要我们自己添加
void MX_CAN1_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_5TQ;
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = ENABLE;
hcan.Init.AutoWakeUp = ENABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterActivation = ENABLE;//打开过滤器
sFilterConfig.FilterBank = 0;//过滤器0 这里可设0-13
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
sFilterConfig.FilterIdHigh = 0x0000; //设置过滤器ID高16位
sFilterConfig.FilterIdLow = 0x0000;//设置过滤器ID低16位
sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
if(HAL_CAN_ConfigFilter(&hcan,&sFilterConfig) != HAL_OK)//初始化过滤器
{
Error_Handler();
}
if(HAL_CAN_Start(&hcan) != HAL_OK)//打开can
{
Error_Handler();
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接受邮箱0挂起中断
{
Error_Handler();
}
}
回调函数的改写
CAN_TxHeaderTypeDef TXHeader;
CAN_RxHeaderTypeDef RXHeader;
uint8_t TXmessage[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
uint8_t RXmessage[8];
uint32_t pTxMailbox = 0;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//接受邮箱0挂起中断回调函数
{
if(hcan->Instance==CAN1)
{
HAL_CAN_GetRxMessage(hcan,CAN_FILTER_FIFO0,&RXHeader,RXmessage);//获取数据
}
}
发送函数的改写
void CAN_senddata(CAN_HandleTypeDef *hcan)
{
TXHeader.StdId=0x00000000;
TXHeader.ExtId=0x12345000;
TXHeader.DLC=8;
TXHeader.IDE=CAN_ID_EXT;
TXHeader.RTR=CAN_RTR_DATA;
TXHeader.TransmitGlobalTime = DISABLE;
HAL_CAN_AddTxMessage(hcan,&TXHeader,TXmessage,&pTxMailbox);
}
举报