OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 72|回复: 0

RT-Thread Studio 工程中,CAN能发数据,接收不到

[复制链接]

3

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2016-2-19
在线时间
48 小时
发表于 3 天前 | 显示全部楼层 |阅读模式
1金钱
RT-Thread Studio 工程中,CAN能发数据,接收不到
  STM32F407
  PA11,12收发引脚
以下是源码
can.h
#ifndef _CAN_H_
#define _CAN_H_

#include "stdint.h"
#include <rtthread.h>
#include <drv_common.h>
#include "sys.h"

typedef union
{
    u32  reg;
    struct
    {
        u32 Priority    :   4;     //优先级,值月越小优先级越高。
        u32 No          :   8;     //优先级,值月越小优先级越高。
        u32 Adr         :  16;     //数据地址
    }D;
}Canid;

#define CAN_BUFFER_SIZE 128
typedef struct {
    uint32_t  id[CAN_BUFFER_SIZE];
    uint8_t   dlc[CAN_BUFFER_SIZE];
    uint8_t   data[CAN_BUFFER_SIZE][8];
    uint16_t  in;
    uint16_t  out;
    uint16_t  size;
}CanBuffer;

#define Can_Y_Send          5
#define Can_X_Send          6
#define Can_ADC_Send        7
#define Can_Pul             8
#define Can_Pul_cmd         9
#define Can_Pul_set        10
#define Can_Pul_status     11
extern CanBuffer tx_buf;
extern CanBuffer rx_buf;
extern Canid     canid;
extern u8        Sdata[8];

void User_Can_Rece(void);             //CAN 数据接收
void User_Can_Send_Rece(void);        //CAN 数据收发

uint8_t CAN_EnqueueTx(uint32_t ext_id, uint8_t len);

void can_printf(void);
#endif /* 0HARDWARE_CAN_H_ */


can.c

#include "define.h"
#include <rtthread.h>
#include <rtdevice.h>
#include <stdio.h>
#include "stm32f4xx.h"
#include "rtdef.h"

CAN_TxHeaderTypeDef TxHeader;      //发送
CAN_RxHeaderTypeDef RxHeader;      //接收


CanBuffer tx_buf = {0};
CanBuffer rx_buf = {0};
Canid     canid;
u8 Sdata[8]={1,2,3,4,5,6,7};

CAN_TxHeaderTypeDef Txheader;
#define CAN_SPEED_500K 0
#define CAN_SPEED_250K 1

CAN_HandleTypeDef hcan1;

void CAN_Init(uint8_t speed_mode)
{
    CAN_FilterTypeDef filter = {
        .FilterIdHigh = 0x0000,
        .FilterMaskIdHigh = 0x0000,  // 接收所有ID
        .FilterFIFOAssignment = CAN_FILTER_FIFO0,
        .FilterBank = 0,
        .FilterMode = CAN_FILTERMODE_IDMASK,
        .FilterScale = CAN_FILTERSCALE_32BIT,
        .FilterActivation = ENABLE
    };
  // 公共参数配置
  hcan1.Instance = CAN1;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;

  // 速度参数动态配置
  switch(speed_mode) {
    case CAN_SPEED_500K:
      hcan1.Init.Prescaler = 7;
      hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
      hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
      break;

    case CAN_SPEED_250K:
      hcan1.Init.Prescaler = 14;
      hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
      hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
      break;
  }

  // 其他固定参数
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = ENABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;

  HAL_CAN_ConfigFilter(&hcan1, &filter);

  HAL_CAN_Init(&hcan1);  // 初始化CAN控制器 :ml-citation{ref="8" data="citationList"}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    if(hcan->Instance == CAN1)
    {
        /* 1. 使能时钟 */
        __HAL_RCC_CAN1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        /* 2. 配置GPIO复用功能 */
        GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    }
}
void CAN_Receive_Init(CAN_HandleTypeDef *hcan)
{
    // 启用FIFO0接收中断
    HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
    HAL_CAN_Start(hcan);
}
// 发送数据入队
uint8_t CAN_EnqueueTx(uint32_t ext_id, uint8_t len)
{
    //u16 i = 0;

    if(tx_buf.size >= CAN_BUFFER_SIZE) return 0;

    tx_buf.id[tx_buf.in] = ext_id;
    tx_buf.dlc[tx_buf.in] = len;
    memcpy(tx_buf.data[tx_buf.in], Sdata, len);
    //for( i=0; i<len; i++ )
    //{  tx_buf.data[tx_buf.in][i] = Sdata[i];  }

    tx_buf.in = (tx_buf.in + 1) % CAN_BUFFER_SIZE;
    tx_buf.size++;
    if( Printf_Can_Send_In )
    {
        RTC_PrintfData();
        rt_kprintf("Can Send in  %3d out %3d size %3d" ,tx_buf.in,tx_buf.out,tx_buf.size);/*
        rt_kprintf("TX in %3d out %3d size %3d RX in %3d out %3d size %3d\n"
                ,tx_buf.in,tx_buf.out,tx_buf.size
                ,rx_buf.in,rx_buf.out,rx_buf.size);*/
    }
    return 1;
}
// 发送状态机处理
void CAN_TxSend( void )
{
    static uint8_t retry_count = 0;
    static uint8_t retry_reg = 0;
    u16 i = 0;
    if( tx_buf.size > 0)
    {
        Txheader.ExtId = tx_buf.id[tx_buf.out];
        Txheader.DLC = tx_buf.dlc[tx_buf.out];
        Txheader.IDE = CAN_ID_EXT;
        Txheader.RTR = CAN_RTR_DATA;
        Txheader.TransmitGlobalTime = DISABLE;

      //if( HAL_CAN_AddTxMessage(hcan1, &Txheader, tx_buf.data[tx_buf.out], NULL) == HAL_OK)
        retry_reg = HAL_CAN_AddTxMessage(&hcan1, &Txheader, tx_buf.data[tx_buf.out], NULL);
        if( retry_reg == HAL_OK)
        {
            //LED_CAN |= 1;
            if( Printf_Can_Send_Out )
            {
                RTC_PrintfData();
                rt_kprintf("Can Send out %3d out %3d size %3d" ,tx_buf.in,tx_buf.out,tx_buf.size);
            }
            tx_buf.out = (tx_buf.out + 1) % CAN_BUFFER_SIZE;
            tx_buf.size--;
            retry_count = 0;
        }
        else if( Printf_Can_Send_Out )
        {
            RTC_PrintfData();
            if( retry_reg == HAL_ERROR)
            {  rt_kprintf("CAN TX HAL_ERROR " ); }
            else if( retry_reg == HAL_BUSY)
            {  rt_kprintf("CAN TX HAL_BUSY "  ); }
            else if( retry_reg == HAL_TIMEOUT)
            {  rt_kprintf("CAN TX HAL_TIMEOUT " ); }
        }
        /*
        else
        {
            if(++retry_count > 3)
            {
                tx_buf.out = (tx_buf.out + 1) % CAN_BUFFER_SIZE;
                tx_buf.size--;
                retry_count = 0;
            }
        }*/
    }
}

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    CAN_RxHeaderTypeDef rx_header;
    uint8_t rx_data[8];

    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, &rx_data) == HAL_OK)
    {
        if(rx_buf.size < CAN_BUFFER_SIZE)
        {
            LED_CAN |= 2;
            rx_buf.id[rx_buf.in] = rx_header.ExtId;
            rx_buf.dlc[rx_buf.in] = rx_header.DLC;
            memcpy(rx_buf.data[rx_buf.in], rx_data, rx_header.DLC);

            if( Printf_Can_Rece_In )
            {
                RTC_PrintfData();
                rt_kprintf("Can Rece in  %3d out %3d size %3d" ,rx_buf.in,rx_buf.out,rx_buf.size);
            }
            rx_buf.in = (rx_buf.in + 1) % CAN_BUFFER_SIZE;
            rx_buf.size++;
        }
    }
    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &rx_header, &rx_data) == HAL_OK)
    {
        if(rx_buf.size < CAN_BUFFER_SIZE)
        {
            LED_CAN |= 2;
            rx_buf.id[rx_buf.in] = rx_header.ExtId;
            rx_buf.dlc[rx_buf.in] = rx_header.DLC;
            memcpy(rx_buf.data[rx_buf.in], rx_data, rx_header.DLC);

            if( Printf_Can_Rece_In )
            {
                RTC_PrintfData();
                rt_kprintf("Can Rece in  %3d out %3d size %3d" ,rx_buf.in,rx_buf.out,rx_buf.size);
            }
            rx_buf.in = (rx_buf.in + 1) % CAN_BUFFER_SIZE;
            rx_buf.size++;
        }
    }
}
void CAN1_RX0_IRQHandler(void)
{
    rt_interrupt_enter();
    HAL_CAN_IRQHandler(&hcan1);
    rt_interrupt_leave();
}
void can_thread_entry(void *args)
{
    //u16 inc=0;
    while(1)
    {
        rt_thread_mdelay(1);
        CAN_TxSend();
        User_Can_Rece();
        User_Can_Send_Rece();
        //inc++;
        //if( inc >= 22 )  {  inc = 0;  CAN_EnqueueTx( 123, 8 );  }
    }
}
u8 MX_Can_init(void)
{
    if( FSD_Can )
    {
        CAN_Init( CAN_SPEED_500K );
        CAN_Receive_Init( &hcan1 );

        //HAL_CAN_Start( &hcan1 );  // 必须启动CAN控制器

        Printf_Can_Send_In    = 1;                //
        Printf_Can_Send_Out   = 1;                //
        Printf_Can_Send_Hex   = 1;                //
        Printf_Can_Rece_In    = 1;                //
        Printf_Can_Rece_Out   = 1;                //
        Printf_Can_Rece_Hex   = 1;                //

        tx_buf.in = 0;
        tx_buf.out = 0;
        tx_buf.size = 0;
        rx_buf.in = 0;
        rx_buf.out = 0;
        rx_buf.size = 0;

        // 创建 serial 线程
        rt_thread_t thread = rt_thread_create("Can", can_thread_entry, RT_NULL, 1024, 16, 20);
        // 创建成功则启动线程
        if (thread != RT_NULL)
        {
            rt_thread_startup(thread);
        }
    }
    return 0;
}
INIT_DEVICE_EXPORT( MX_Can_init );
void can_printf(void)
{
    RTC_PrintfData();
    rt_kprintf("TX in %3d out %3d size %3d RX in %3d out %3d size %3d"
            ,tx_buf.in,tx_buf.out,tx_buf.size
            ,rx_buf.in,rx_buf.out,rx_buf.size);
}

麻烦各位帮我析一下什么原因

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-2 20:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表