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);
//测试canopen
if(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; //过滤器0
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x000 ; //32位ID
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000; //32位MASK
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;//过滤器0关联到FIFO0
sFilterConfig.FilterActivation = ENABLE; //激活滤波器0
sFilterConfig.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; // 使用标准 ID
TxHeader.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