KeGiuiiiii 2022-09-08 14:29 采纳率: 80%
浏览 119
已结题

GD32F450只用一路can无法收发,这个 怎么解决

GD32F450只用一路can无法收发,这个 怎么解决

img

img

mcu_can.c

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include "gd32f4xx.h"
#include "mcu_dev/mcu_can.h"
#include "emqueue.h"

#define CAN_MSG_MAX            4000

typedef can_trasnmit_message_struct can0_send_msg_t;

QUEUE_DECLARE(can0_send_msg_t, CAN_MSG_MAX);
QUEUE_DEFINE(can0_send_msg_t);
QUEUE_TYPE(can0_send_msg_t) can0_txq;

static can0_send_msg_t can0_send_msg;
static uint8_t can0_wait_fifo_to_send;

void CAN0_RX0_IRQHandler(void)
{
    // CAN0 连接输入卡槽
    // 输入卡槽接收ID列表: 0x002 ~ 0x0FF
    // 输出卡槽接收ID列表: 0x102 ~ 0x1FF
    can_receive_message_struct rx_msg;
    can0_send_msg_t    can0_tx_msg;

    can_message_receive(CAN0, CAN_FIFO0, &rx_msg);

    if(rx_msg.rx_sfid >= 0x102 && rx_msg.rx_sfid <= 0x1FF)
    {
        can0_tx_msg.tx_sfid        = rx_msg.rx_sfid;
        can0_tx_msg.tx_efid        = rx_msg.rx_efid;
        can0_tx_msg.tx_ff        = rx_msg.rx_ff;
        can0_tx_msg.tx_ft        = rx_msg.rx_ft;
        can0_tx_msg.tx_dlen        = rx_msg.rx_dlen;
        memcpy(can0_tx_msg.tx_data, rx_msg.rx_data, 8);
        QUEUE_PUSH(can0_send_msg_t, &can0_txq, can0_tx_msg);
    }
}

void mcu_can_init(void)
{
    QUEUE_INIT(can0_send_msg_t, &can0_txq);

    can0_wait_fifo_to_send = 0;

    rcu_periph_clock_enable(RCU_CAN0);
    
    rcu_periph_clock_enable(RCU_GPIOA);
    

    // CAN0
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_11);
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_12);

    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_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);

    

    nvic_irq_enable(CAN0_RX0_IRQn,0,0);
    

    /*
    **    .prescaler变量,代表产生CAN总线波特率的时钟分频值
    **    CAN模块总线时钟50MHz
    **  采样点 = (1+SEG1)/(1+SEG1+SEG2),要求在75%~80%之间
    **      1MBps - 5;        500KBps - 10;    250KBps - 20;
    **        100KBps - 50;  50KBps - 100
    **/
    can_parameter_struct        canParameter = {
        .working_mode            = CAN_NORMAL_MODE,
        .resync_jump_width        = CAN_BT_SJW_1TQ,
        .time_segment_1            = CAN_BT_BS1_7TQ,
        .time_segment_2            = CAN_BT_BS2_2TQ,
        .time_triggered         = DISABLE,
        .auto_bus_off_recovery     = DISABLE,
        .auto_wake_up             = DISABLE,
        .auto_retrans             = ENABLE,
        .rec_fifo_overwrite        = DISABLE,
        .trans_fifo_order        = ENABLE,
        .prescaler                = 5,

    };
    can_deinit(CAN0);
    

    can_init(CAN0, &canParameter);
    

    // CAN0 连接输入卡槽,即需实现:输出卡槽(CAN1)--> 输入卡槽(CAN0) ==> CAN1接收0x002 ~ 0x0FF
    // CAN1 连接输出卡槽,即需实现:输入卡槽(CAN0)--> 输出卡槽(CAN0) ==> CAN0接收0x102 ~ 0x1FF
    // 输入卡槽接收ID列表: 0x002 ~ 0x0FF
    // 输出卡槽接收ID列表: 0x102 ~ 0x1FF
    can_filter_parameter_struct can_filter;
    can_filter.filter_number=0;
    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);


    can_interrupt_enable(CAN0, CAN_INT_RFNE0);
}

void mcu_can_proc(void)
{
    int ret;
    int can0_msg_tx_flag = 0;

    if(can0_wait_fifo_to_send)
    {
        printf("111\r\n");
        can0_msg_tx_flag = 1;
    }
    else if(QUEUE_LENGTH(can0_send_msg_t, &can0_txq))
    {
                printf("2\r\n");

        can0_send_msg = QUEUE_POP(can0_send_msg_t, &can0_txq);
        can0_msg_tx_flag = 1;
    }

    if(can0_msg_tx_flag)
    {
                printf("3\r\n");

        ret = can_message_transmit(CAN0, &can0_send_msg);
        can0_wait_fifo_to_send = (ret == CAN_NOMAILBOX) ? 1 : 0;
    }
}

mcu_can.h

#ifndef _MCU_CAN_H_
#define _MCU_CAN_H_


void mcu_can_init(void);
void mcu_can_proc(void);



#endif // !_MCU_CAN_H_


  • 写回答

1条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 10月17日
  • 已采纳回答 10月9日
  • 创建了问题 9月8日

悬赏问题

  • ¥15 PFENet的预训练权重
  • ¥15 程序哪有错误怎么改?
  • ¥15 交换机和交换机之间的链路带宽以及主机带宽的理解
  • ¥15 ai创想家对战模式代码
  • ¥15 集合A由3个2行4列二维数组构成,从集合A中任意取一个二维数组元素、如果该二维数组元素的对应列位置的上、下两数都是奇数,而且仅有2个列是奇数/奇数,则该数组有意义,并放入集合B中打印输出。
  • ¥15 电信IPV6 无法外网访问吗
  • ¥15 有偿求效果比较好的遥感影像匹配的c++代码
  • ¥15 博主,你好,我下载了你的智能网联汽车辅助驾驶安全信息检测系统,现在不会运行,可以教我吗,
  • ¥15 怎么在excle输入下列公式
  • ¥15 Arduino,利用modbus的RS485协议,进行对外置的温湿度传感器进行数据读取