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;
}