本文章主要用于 看自己写的CAN协议代码是否正确 然后因为只有一块板子,不能通信的情况
can.h
#ifndef __CAN_H
#define __CAN_H
#include "head.h"
extern FlagStatus can0_receive_flag;
extern FlagStatus can0_error_flag;
extern can_trasnmit_message_struct transmit_message;
extern can_receive_message_struct receive_message;
void CAN0_init(void);
#endif
can.c
#include "can.h"
FlagStatus can0_receive_flag=RESET;
FlagStatus can0_error_flag=RESET;
can_trasnmit_message_struct transmit_message;
can_receive_message_struct receive_message;
void CAN0_init(void)
{
can_parameter_struct can_parameter;
can_filter_parameter_struct can_filter;
//使能CAN0和GPIOA的时钟
rcu_periph_clock_enable(RCU_CAN0);
rcu_periph_clock_enable(RCU_GPIOA);
//配置GPIO口,CAN0_RX:PA11 CAN0_TX:PA12
gpio_init(GPIOA,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_11);
gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
//NVIC中断配置
nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn ,0,0);
//初始化CAN0参数
can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
can_deinit(CAN0);
can_parameter.time_triggered = DISABLE;//非时间触发通信模式
can_parameter.auto_bus_off_recovery = DISABLE;//软件自动离线管理
can_parameter.auto_wake_up = DISABLE;//睡眠模式通过软件唤醒
can_parameter.auto_retrans = ENABLE;//报文自动重传
can_parameter.rec_fifo_overwrite = DISABLE;//报文不锁定,新的覆盖旧的
can_parameter.trans_fifo_order = DISABLE;
can_parameter.working_mode = CAN_SILENT_LOOPBACK_MODE;//四种通信模式:正常,回环,静默,回环静默
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;//重新同步跳跃宽度
can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;//时间段 1 占用时间单位
can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;//时间段 2 占用时间单位
can_parameter.prescaler = 6;/* 1MBps */
can_init(CAN0, &can_parameter);
//初始化CAN过滤器,不过滤任何ID
can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
can_filter.filter_number=0;
can_filter.filter_mode = CAN_FILTERMODE_MASK;
can_filter.filter_bits = CAN_FILTERBITS_32BIT;
can_filter.filter_list_high = 0x0000;
can_filter.filter_list_low = 0x0000;
can_filter.filter_mask_high = 0x0000;
can_filter.filter_mask_low = 0x0000;
can_filter.filter_fifo_number = CAN_FIFO0;
can_filter.filter_enable = ENABLE;
can_filter_init(&can_filter);
//使能接收中断,receive FIFO0 not empty interrupt enable
can_interrupt_enable(CAN0, CAN_INT_RFNE0);
}
/************************************函数功能描述************************************************
Function Name : USBD_LP_CAN0_RX0_IRQHandler(void)
Description : CAN0的接收中断,如果接收到指定的数据则让can0_receive_flag置1,否则can0_error_flag置1
Input : 无
Output : 无
*************************************************************************************************
例如,初始化发送结构体,发送完毕之后就会进入中断
transmit_message.tx_sfid = 0x300>>1;
transmit_message.tx_efid = 0x00;
transmit_message.tx_ft = CAN_FT_DATA;//帧的类型:数据帧或者遥控帧
transmit_message.tx_ff = CAN_FF_STANDARD;//帧的格式:标准帧或者拓展帧
transmit_message.tx_dlen = 2;
transmit_message.tx_data[0] = 0x55;
transmit_message.tx_data[1] = 0xAA;
can_message_transmit(CAN0, &transmit_message);
*************************************************************************************************/
void USBD_LP_CAN0_RX0_IRQHandler(void)
{
/* check the receive message */
can_message_receive(CAN0, CAN_FIFO0, &receive_message);
if((0x300>>1 == receive_message.rx_sfid)&&(CAN_FF_STANDARD == receive_message.rx_ff)&&(2 == receive_message.rx_dlen)){
can0_receive_flag = SET;
}else{
can0_error_flag = SET;
}
}