如何用C8T6连接CAN收发器(TJA1050、VP230等TTL转CAN模块都试过),再连接创芯科技的CAN分析仪,进行CAN报文的接收?

任务目标是使用STM32F103C8T6单片机对电机进行控制,电机是CAN通信,只需要发指令。现在测试阶段,用C8T6连接CAN收发器(TJA1050、VP230等TTL转CAN模块都试过),再连接创芯科技的CAN分析仪,进行CAN报文的接收。目前程序用hal库配置编写,在keil下载烧录,可以回环在电脑的串口助手看到数据,但是正常收发模式就调不通无法通信了

img

img

首先,您需要确认您的CAN收发器和CAN分析仪的配置是否正确。可以使用示波器或逻辑分析仪来检查CAN总线上的信号是否正确,以及确认CAN收发器和CAN分析仪是否能够正常工作。

其次,您需要确认您的STM32F103C8T6单片机的CAN总线配置是否正确。以下是使用HAL库配置STM32F103C8T6单片机的CAN总线的示例代码:

#include "stm32f1xx_hal.h"

CAN_HandleTypeDef hcan;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_CAN_Init();

  CAN_TxHeaderTypeDef TxHeader;
  uint8_t TxData[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  uint32_t TxMailbox;

  TxHeader.StdId = 0x123;
  TxHeader.ExtId = 0x01;
  TxHeader.RTR = CAN_RTR_DATA;
  TxHeader.IDE = CAN_ID_STD;
  TxHeader.DLC = 8;

  while (1)
  {
    if (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) != 0)
    {
      if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) == HAL_OK)
      {
        // Transmit success
      }
      else
      {
        // Transmit failed
      }
    }
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                              | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC

_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}

static void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 9;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = ENABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

在该示例代码中,我们使用了HAL库来配置CAN总线。首先,我们需要初始化CAN总线的基本参数,如预分频器、同步跳转宽度、时间段1、时间段2等。然后,我们使用CAN_TxHeaderTypeDef结构体定义了CAN报文的头部信息,包括标准ID、扩展ID、数据长度等。在主循环中,我们使用HAL_CAN_AddTxMessage()函数发送CAN报文,并通过HAL_CAN_GetTxMailboxesFreeLevel()函数检查发送

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,在使用C8T6连接CAN收发器之前,需要确保你已经成功地完成了CAN收发器的初始化及配置,并且CAN收发器的波特率设置和样品点设置与CAN总线上的其他设备相匹配。在此基础上,我们才能够使用C8T6来控制发送和接收CAN报文。

下面是一些基本步骤:

1.初始化CAN

需要调用HAL_CAN_Init() 初始化CAN模块,同时指定CAN模块的波特率等参数。

CAN_HandleTypeDef hcan;

void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 8;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_6TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
}

在这里,我们使用了一个名为“hcan”的CAN_HandleTypeDef结构体,用于存储CAN模块的配置信息。需要注意的是,此处我们使用的波特率为500Kbps,可以根据实际情况进行调整。

2.发送CAN报文

发送CAN报文需要使用HAL_CAN_Transmit()函数,函数的参数包括CAN_HandleTypeDef结构体以及一个名为“TxMsg”的CAN_TxHeader结构体,该结构体包含了一些重要的发送信息。

CAN_TxHeader TxMsg;
uint8_t tx_data[8];
uint32_t TxMailbox;

TxMsg.StdId = 0x7FF;
TxMsg.DLC = 8;
TxMsg.IDE = CAN_ID_STD;
TxMsg.RTR = CAN_RTR_DATA;

tx_data[0]=1;
tx_data[1]=2;
tx_data[2]=3;
tx_data[3]=4;
tx_data[4]=5;
tx_data[5]=6;
tx_data[6]=7;
tx_data[7]=8;

if (HAL_CAN_AddTxMessage(&hcan, &TxMsg, tx_data, &TxMailbox) == HAL_OK)
{
    // transmit OK
}

在这里,我们使用了一个名为“TxMsg”的CAN_TxHeader结构体变量,用于描述发送报文的一些重要信息,包括标准帧ID(StdId)、数据长度(DLC)、帧类型(IDE)、数据类型(RTR)等。同时我们定义了一个长度为8的字节数组tx_data,用于存储要发送的数据。如果发送成功,则函数返回一个值为HAL_OK的状态信息。

3.接收CAN报文

接收CAN报文需要使用HAL_CAN_ Receive()函数,函数的参数包括CAN_HandleTypeDef结构体以及一个名为“RxMsg”的CAN_RxHeader结构体,该结构体包含了一些重要的接收信息。

CAN_RxHeader RxMsg;
uint8_t rx_data[8];

if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxMsg, rx_data) == HAL_OK)
{
  // receive OK, data stored in rx_data
}

在这里,我们使用了一个名为“RxMsg”的CAN_RxHeader结构体变量,用于描述接收报文的一些重要信息。同时,我们定义了一个长度为8的字节数组rx_data,用于存储接收到的数据。如果接收成功,则函数返回一个值为HAL_OK的状态信息。

需要注意的是,以上这些代码只是为了说明CAN发送和接收功能的基本实现方法,并不是一份完整的代码。在实际应用中,需要结合具体的硬件环境和软件需求进行调整和编写。

另外,还需要检查以下几个问题是否存在:

1.检查CAN总线上的其他设备是否已经启动,是否已经正确地初始化和配置,包括波特率、样品点、过滤器等等。

2.检查CAN收发器和CAN总线的电气连接是否正常,包括CAN_H和CAN_L两条线和地线的连接是否良好。

3.检查代码是否有误,包括函数的调用参数、变量的类型、数量和赋值是否正确,是否有其他文本输出的干扰等等。

最后,建议可以在代码中添加一些调试信息或断点,以便查找问题所在。
如果我的回答解决了您的问题,请采纳!

内容来源与ChatGpt4及newbing和百度:


你可以使用STM32的CAN模块来与CAN收发器进行通信。首先,你需要在STM32的代码中初始化CAN模块,包括波特率、时序等参数。然后,你可以编写CAN发送和接收函数来发送和接收CAN报文。在发送CAN报文时,你需要设置报文ID、数据长度和数据内容等参数。在接收CAN报文时,你需要判断报文ID和数据长度,然后处理数据内容。

以下是一些示例代码,仅供参考:

CAN初始化:

CAN_HandleTypeDef hcan;

void MX_CAN_Init(void)
{
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 5;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_2TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = ENABLE;
  hcan.Init.AutoWakeUp = DISABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK)
  {
    Error_Handler();
  }
}

CAN发送函数:

void CAN_Send(uint32_t id, uint8_t *data, uint8_t len)
{
  CAN_TxHeaderTypeDef txHeader;
  txHeader.StdId = id;
  txHeader.RTR = CAN_RTR_DATA;
  txHeader.IDE = CAN_ID_STD;
  txHeader.DLC = len;
  uint32_t mailbox;
  if (HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &mailbox) != HAL_OK)
  {
    Error_Handler();
  }
}

CAN接收函数:

void CAN_Receive(CAN_HandleTypeDef *hcan)
{
  CAN_RxHeaderTypeDef rxHeader;
  uint8_t data[8];
  if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, data) != HAL_OK)
  {
    Error_Handler();
  }
  if (rxHeader.IDE == CAN_ID_STD && rxHeader.DLC == 8)
  {
    switch (rxHeader.StdId)
    {
      case 0x100:
        // 处理0x100报文
        break;
      case 0x200:
        // 处理0x200报文
        break;
      default:
        break;
    }
  }
}

注意,以上代码仅供参考,你需要根据具体情况进行修改。同时,你需要在代码中添加CAN收发器的初始化代码,以及与CAN分析仪的连接代码。


祝您问题迎刃而解