注:1.波特率计算:band = APB1(50MHz)/(1TQ 5TQ 4TQ)/prescaler=50MHz/(1 5 4)/5=1MHz
2.用CAN1必须初始化CAN0的时钟不然CAN1不能进入接收中断。
CAN1_F450.cpp
#include "CAN1_F450.hpp" #include "main.h" can_receive_message_struct receive_message; FlagStatus can1_receive_flag; CAN1_F450::CAN1_F450() { } void CAN1_F450::Init(const uint16_t baud) { can1_receive_flag = RESET; /* enable CAN clock */ rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_CAN1); rcu_periph_clock_enable(RCU_GPIOB); /* configure CAN1 GPIO */ gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12|GPIO_PIN_13); gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12|GPIO_PIN_13); gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_12|GPIO_PIN_13); can_parameter_struct can_parameter; can_struct_para_init(CAN_INIT_STRUCT, &can_parameter); can_deinit(CAN1); can_parameter.time_triggered = DISABLE; can_parameter.auto_bus_off_recovery = DISABLE; can_parameter.auto_wake_up = DISABLE; can_parameter.no_auto_retrans = DISABLE; can_parameter.rec_fifo_overwrite = DISABLE; can_parameter.trans_fifo_order = DISABLE; can_parameter.working_mode = CAN_NORMAL_MODE; can_parameter.resync_jump_width = CAN_BT_SJW_1TQ; can_parameter.time_segment_1 = CAN_BT_BS1_5TQ; can_parameter.time_segment_2 = CAN_BT_BS2_4TQ; switch(baud) { case 1000:/* 1MBps */ can_parameter.prescaler = 5;break; case 500:/* 500KBps */ can_parameter.prescaler = 10;break; case 250:/* 250KBps */ can_parameter.prescaler = 20;break; case 125:/* 125KBps */ can_parameter.prescaler = 40;break; case 100:/* 100KBps */ can_parameter.prescaler = 50;break; case 50: /* 50KBps */ can_parameter.prescaler = 100;break; case 20: /* 20KBps */ can_parameter.prescaler = 250;break; defualt: /* 1MBps */ can_parameter.prescaler = 5;break; } /* initialize CAN */ can_init(CAN1, &can_parameter); /* initialize filter */ can_filter_parameter_struct can_filter; can_struct_para_init(CAN_INIT_STRUCT, &can_filter); can_filter.filter_number=15; 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); /* enable can receive FIFO0 not empty interrupt */ can_interrupt_enable(CAN1, CAN_INT_RFNE0); /* configure CAN1 NVIC */ nvic_irq_enable(CAN1_RX0_IRQn,0,0); } void CAN1_F450::CAN_Fiter_Init() { } void CAN1_F450::SetBaud(uint16_t baud) { can_parameter_struct can_parameter; switch(baud) { case 1000:/* 1MBps */ can_parameter.prescaler = 5;break; case 500:/* 500KBps */ can_parameter.prescaler = 10;break; case 250:/* 250KBps */ can_parameter.prescaler = 20;break; case 125:/* 125KBps */ can_parameter.prescaler = 40;break; case 100:/* 100KBps */ can_parameter.prescaler = 50;break; case 50: /* 50KBps */ can_parameter.prescaler = 100;break; case 20: /* 20KBps */ can_parameter.prescaler = 250;break; defualt: /* 1MBps */ can_parameter.prescaler = 5;break; } /* initialize CAN */ can_init(CAN1, &can_parameter); } uint16_t CAN1_F450::Read(uint16_t *ID, uint8_t *buf) { /* CAN1 receive data correctly, the received data is printed */ if(SET == can1_receive_flag) { can1_receive_flag = RESET; *ID = receive_message.rx_sfid; for(uint8_t i=0;i<receive_message.rx_dlen;i ) { buf[i] = receive_message.rx_data[i]; } return receive_message.rx_dlen; } return 0; } void CAN1_F450::Write(uint16_t ID, uint8_t *buf, uint16_t len) { can_trasnmit_message_struct transmit_message; transmit_message.tx_sfid = ID; transmit_message.tx_efid = 0x00; transmit_message.tx_ft = CAN_FT_DATA; transmit_message.tx_ff = CAN_FF_STANDARD; transmit_message.tx_dlen = len; for(uint8_t i=0;i<len; i ) { transmit_message.tx_data[i] = buf[i]; } can_message_transmit(CAN1, &transmit_message); } void CAN1_F450::Write(uint16_t ID, uint16_t len) { }
CAN1_F450.hpp
#pragma once #include "Bsp/CAN.hpp" class CAN1_F450 : public CAN { private: public: CAN1_F450(); void Init(const uint16_t baud); void CAN_Fiter_Init(); void SetBaud(uint16_t baud); uint16_t Read(uint16_t *ID, uint8_t *buf); void Write(uint16_t ID, uint8_t *buf, uint16_t len); void Write(uint16_t ID, uint16_t len); uint8_t rxbuf[8]; uint8_t txbuf[8]; uint8_t rxDataLen; };
CAN.hpp
#pragma once #nclude <stdint.h>
class CAN
{
public:
CAN(){}
virtual void Init(const uint16_t baud = 1000){}
virtual void CAN_Fiter_Init(){}
virtual void SetBaud(uint16_t baud){}
virtual uint16_t Read(uint16_t *ID, uint8_t *buf){}
virtual void Write(uint16_t ID, uint8_t *buf, uint16_t len){}
virtual void Write(uint16_t ID, uint16_t len){}
uint8_t rxbuf[8];
uint8_t txbuf[8];
uint8_t rxDataLen;
};