前言
GD32VF103_环境配置_GPIO_外部中断
GD32VF103_定时器中断
GD32VF103_串口发送_printf_接收中断_DMA
GD32VF103_DAC
我们前三节写了GPIO, EXTI, TIMER, USART, DAC的用例, 本节写 CAN 发送的用例, 为什么是发送不是接收, 还不是因为接收比较复杂, 没有调好… 用的 CAN1(PB13--CAN1_TX
, PB12--CAN1_RX
), 自己拿烙铁焊了 CAN电平转换芯片 TCAN1051DQ1
, 带Q的车规的片子:
CAN1接CAN分析仪, 500k, 终端电阻用了CAN分析仪上的120Ω, 虽然不是60Ω, 在这里问题不大.
新建工程
打开NucleiStudio:
- File -> New -> C/C++ Project, 选择C Managed Build
- 选择GigaDevice RISC-V Project, 填入工程名
- MCU默认暂时只有GD32VF103, 然后Demo也没法选, 只有Running_LED, 不变
- 下一步, 完成.
CAN发送
CAN, 标准帧, 扩展帧等的基本原理和相关资料不再赘述, 网上搜去, STM32的资料或者搞汽车方面的比较多.
主要配置下CAN的通讯速率, 应该是
APB1的54M时钟, 预分配(prescaler)12, 得4.5MHz, 然后 can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
, can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
, 所以最后通讯速率 4.5M/(5+3+1) = 0.5M = 500k, 与can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
关系不大.
代码如下:
#include "gd32vf103.h"
#include "systick.h"
can_trasnmit_message_struct transmit_message;
void can1_config(void) {
can_parameter_struct can_parameter;
can_filter_parameter_struct can_filter;
/* initialize CAN register */
can_deinit(CAN1);
/* initialize CAN */
can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = ENABLE;
can_parameter.auto_wake_up = ENABLE;
can_parameter.auto_retrans = ENABLE; //no_auto_retrans
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_3TQ;
/* baudrate 1Mbps */
can_parameter.prescaler = 12; //54M / 12 / (5+3+1) = 500kbps
can_init(CAN1, &can_parameter);
}
int main(void) {
rcu_periph_clock_enable(RCU_CAN1);
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); //PB13 -- CAN1_TX
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_12); //PB12 -- CAN1_RX
//gpio_pin_remap_config(GPIO_CAN1_REMAP,DISABLE); //Remap
can1_config();
transmit_message.tx_sfid = 0x321; //standard format frame identifier
transmit_message.tx_efid = 0x00; //extended format frame identifier
transmit_message.tx_ft = CAN_FT_DATA; //type of frame, data or remote
transmit_message.tx_ff = CAN_FF_STANDARD; //format of frame, standard or extended format
transmit_message.tx_dlen = 2; //data length
transmit_message.tx_data[0] = 0x00;
transmit_message.tx_data[1] = 0x00;
while(1) {
++transmit_message.tx_data[1];
can_message_transmit(CAN1, &transmit_message);
delay_1ms(1000);
}
return 0;
}
调试运行
结果如下:
符合代码预期.