GD32F470之can0收发+接收中断配置以及详细波特率计算

IO口配置:
根据你自己板子上的IO口来配置,
我的can是PA11和PA12。
CAN波特率计算.
在这里插入图片描述
举个例子:我要配置成500K.

那么我的tpclk1 =60M.
从这个图可以看出,但是我的是F470,是60M。
在这里插入图片描述
那么:
1.tq = (1/60M )* 12=(1/5)us ,或者这么理解 1/(60M/12),那么12就是分频的意思。
2.𝑡𝑆𝑌𝑁𝐶_𝑆𝐸𝐺 为 1 tq(一般固定为1)
𝑡𝐵𝑆1 + 𝑡𝐵𝑆2凑出一个9 * tq就行.
我这里𝑡𝐵𝑆1 = 5 ,𝑡𝐵𝑆2=4.
所以:(1+ 5 + 4 ) tq = 10 * (1/5)us = 2us
𝐵𝑎𝑢𝑑𝑅𝑎𝑡e = 1 / 2us = 0.5 *10 ^6 hz = 500 000hz = 500K
can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;
can_parameter.prescaler = 12;

#include "gd32f4xx.h"
#include <stdio.h>
#include "gd32f470z_eval.h"

extern FlagStatus receive_flag;
extern can_receive_message_struct receive_message;
can_trasnmit_message_struct transmit_message;

void nvic_config(void);
void led_config(void);
void gpio_config(void);
ErrStatus can_networking(void);
void can_networking_init(void);
void delay(void);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    receive_flag = RESET;
    /* configure Tamper key */
    gd_eval_key_init(KEY_TAMPER, KEY_MODE_GPIO);
    /* configure GPIO */
    gpio_config();
    /* configure USART */
    gd_eval_com_init(EVAL_COM0);
    /* configure NVIC */
    nvic_config();
    /* configure LEDs */
    led_config();
    /* set all LEDs off */
    gd_eval_led_off(LED1);
    gd_eval_led_off(LED2);
    gd_eval_led_off(LED3);
    /* initialize CAN and CAN filter*/
    can_networking_init();

    /* enable CAN receive FIFO0 not empty interrupt */
    can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);

    /* initialize transmit message */
    transmit_message.tx_sfid = 0x321;
    transmit_message.tx_efid = 0x00;
    transmit_message.tx_ft = CAN_FT_DATA;
    transmit_message.tx_ff = CAN_FF_STANDARD;
    transmit_message.tx_dlen = 2;
    //printf("\r\nplease press the Tamper key to transmit data!\r\n");
    while(1) 
			{
        /* waiting for the Tamper key pressed */
       // while(0 == gd_eval_key_state_get(KEY_TAMPER)) 
				{
            transmit_message.tx_data[0] = 0xAB;
            transmit_message.tx_data[1] = 0xCD;
           // printf("\r\nCAN0 transmit data: %x,%x\r\n", transmit_message.tx_data[0], transmit_message.tx_data[1]);
            /* transmit message */
            can_message_transmit(CAN0, &transmit_message);
            delay(); delay();	delay();	delay();	delay(); delay();delay();delay();delay();
				  	delay(); delay();	delay();	delay();	delay(); delay();delay();delay();delay();
				   gd_eval_led_toggle(LED1);	
					 gd_eval_led_toggle(LED2);
		
            /* waiting for Tamper key up */
           // while(0 == gd_eval_key_state_get(KEY_TAMPER));
        }
        if(SET == receive_flag) 
					{
            gd_eval_led_toggle(LED2);
            receive_flag = RESET;
           // printf("\r\nCAN0 receive data: %x,%x\r\n", receive_message.rx_data[0], receive_message.rx_data[1]);
         }
     }
}

/*!
    \brief      initialize CAN and filter
    \param[in]  none
    \param[out] none
    \retval     none
*/
void can_networking_init(void)
{
    can_parameter_struct can_parameter;
    can_filter_parameter_struct can_filter;
    /* initialize CAN register */
    can_deinit(CAN0);

    /* initialize CAN */
    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_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;
    /* baudrate 500Kbps */
    can_parameter.prescaler = 12;
    can_init(CAN0, &can_parameter);

    /* initialize filter */
    /* CAN0 filter number */
    can_filter.filter_number = 0;

    /* initialize filter */
    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);
}

/*!
    \brief      configure the nested vectored interrupt controller
    \param[in]  none
    \param[out] none
    \retval     none
*/
void nvic_config(void)
{
    /* configure CAN0 NVIC */
    nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
}

/*!
    \brief      delay
    \param[in]  none
    \param[out] none
    \retval     none
*/
void delay(void)
{
    uint16_t nTime = 0x0000;

    for(nTime = 0; nTime <0xFFFF; nTime++) 
	  {
		//  for(nTime = 0; nTime < ; nTime++){}
    }
}

/*!
    \brief      configure the LEDs
    \param[in]  none
    \param[out] none
    \retval     none
*/
void led_config(void)
{
    gd_eval_led_init(LED1);
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);
}

/*!
    \brief      configure GPIO
    \param[in]  none
    \param[out] none
    \retval     none
*/
void gpio_config(void)
{
    /* enable can clock */
    rcu_periph_clock_enable(RCU_CAN0);
    rcu_periph_clock_enable(RCU_GPIOA);

    /* configure CAN0 GPIO, CAN0_TX(PA12) and CAN0_RX(PA11) */
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_11);

    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_12);
}

/* retarget the C library printf function to the usart */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(EVAL_COM0, (uint8_t) ch);
    while(RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));
    return ch;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaotianyun88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值