STM32F103的CAN通讯接收测试
首先配置CUBEMX
1.打开CUBEMX
设置时钟,由于我没有外部时钟,所以我选择内部时钟,选择8倍频,1分频,APB1时钟频率为32MKHZ,也就是说每秒能够执行 3200 万个时钟周期,1M是每秒执行100万个时钟周期。
2.CAN收发测试(回环测试)
选择回环测试的原因是我现在没有接收设备,所以选择回环模式
3.激活接收中断
4.输出代码
CAN代码:
我用过灯进行表示接收到可信息。
int main(void)
{HAL_Init();MX_GPIO_Init();MX_CAN_Init();// 使能CAN接收中断HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING); CAN_Config();HAL_CAN_Start(&hcan);//使能can总线,必须有没有不行while (1){CAN_SendMessage(0x0182,TxData,8);//测试canopenif(canopen_Rx_Data_Glag == 1) {HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET); }HAL_Delay(1000);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);HAL_Delay(1000);}
}
void CAN_Config(void)
{ CAN_FilterTypeDef sFilterConfig;/*配置CAN过滤器*/sFilterConfig.FilterBank = 0; //过滤器0sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x000 ; //32位IDsFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000; //32位MASKsFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;//过滤器0关联到FIFO0sFilterConfig.FilterActivation = ENABLE; //激活滤波器0sFilterConfig.SlaveStartFilterBank = 14;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 消息函数
void CAN_SendMessage(uint32_t id, uint8_t *data, uint8_t len) {CAN_TxHeaderTypeDef TxHeader; // 定义 CAN 发送头uint32_t TxMailbox; // 邮箱标识TxHeader.DLC = len; // 数据长度,最大 8 字节TxHeader.StdId = id; // 标准标识符TxHeader.IDE = CAN_ID_STD; // 使用标准 IDTxHeader.RTR = CAN_RTR_DATA; // 数据帧TxHeader.TransmitGlobalTime = DISABLE; // 关闭全局时间戳// 发送 CAN 消息,使用 HAL 库提供的函数if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailbox) != HAL_OK) {// 如果发送失败,调用错误处理函数Error_Handler();}
}
//if(HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK);
//{//}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{CAN_RxHeaderTypeDef rxHeader;uint8_t rxData[8]; // 接收数据缓冲区if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK){
// if (rxHeader.StdId == 0x80) // SYNC 消息的标准 ID
// {
// canopen_Rx_Data_Glag = 1;
// }canopen_Rx_Data_Glag = 1;HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);}}
.H
#ifndef __CANOPEN_H_
#define __CANOPEN_H_
#include "can.h"
#include "main.h"
extern uint8_t canopen_Rx_Data_Glag;
void CAN_Config(void);
void CAN_SendMessage(uint32_t id, uint8_t *data, uint8_t len) ;uint16_t CRC16_Calculate(uint8_t *data, uint32_t length);#endif