天天看点

GD32F450,CAN1收发数据总结

注意事项: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;
};