注意事項: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
#include <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;
};