stm32制作CAN适配器1--USB转CAN

STM32F072系列可以同时使用CAN与USB,利用这个功能可以制作一个简单的USB转CAN。

1、管脚配置

2、时钟配置

3、CAN配置,500Kbps

4、USB配置,这里用的是HID模式

5、下面对USB代码部份进行更改:

usbd_custom_hid_if.c文件中更改HID报文描述,发送与接收长度设置为20

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
	0x05,0x8C,
	0x09,0x01,
	0xA1,0x01,
	//the input report
	0x09,0x03,
	0x15,0x00,
	0x26,0x00,0xFF,
	0x75,0x08,
	0x95,CUSTOM_HID_EPIN_SIZE,
	0x81,0x02,
	//the output report
	0x09,0x04,
	0x15,0x00,
	0x26,0x00,0xFF,
	0x75,0x08,
	0x95,CUSTOM_HID_EPOUT_SIZE,
	0x91,0x02,
	
	0xC0,
};

usbd_conf.h中更改

#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     20
/*---------- -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE     33

usbd_desc.c中更改VID与PID

#define USBD_VID     0x1234
#define USBD_LANGID_STRING     1033
#define USBD_MANUFACTURER_STRING     "STMicroelectronics"
#define USBD_PID_FS     0x5678
#define USBD_PRODUCT_STRING_FS     "STM32 Custom Human interface"
#define USBD_CONFIGURATION_STRING_FS     "Custom HID Config"
#define USBD_INTERFACE_STRING_FS     "Custom HID Interface"

usbd_customhid.h更改端点大小

#define CUSTOM_HID_EPIN_ADDR                 0x81U
#define CUSTOM_HID_EPIN_SIZE                 20U

#define CUSTOM_HID_EPOUT_ADDR                0x01U
#define CUSTOM_HID_EPOUT_SIZE                20U

#define USB_CUSTOM_HID_CONFIG_DESC_SIZ       41U
#define USB_CUSTOM_HID_DESC_SIZ              9U

#ifndef CUSTOM_HID_HS_BINTERVAL
#define CUSTOM_HID_HS_BINTERVAL            0x05U
#endif /* CUSTOM_HID_HS_BINTERVAL */

#ifndef CUSTOM_HID_FS_BINTERVAL
#define CUSTOM_HID_FS_BINTERVAL            0x05U
#endif /* CUSTOM_HID_FS_BINTERVAL */

#ifndef USBD_CUSTOMHID_OUTREPORT_BUF_SIZE
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE  0x40U
#endif /* USBD_CUSTOMHID_OUTREPORT_BUF_SIZE */
#ifndef USBD_CUSTOM_HID_REPORT_DESC_SIZE
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE   163U
#endif /* USBD_CUSTOM_HID_REPORT_DESC_SIZE */

6、在main函数中启动CAN

CAN_RxHeaderTypeDef RxHeader = {0};
  CAN_FilterTypeDef filter;
	uint8_t Rxdata[8] = {0};

	uint8_t data[64] = {0};
filter.FilterMode = CAN_FILTERMODE_IDMASK;
  filter.FilterScale = CAN_FILTERSCALE_32BIT;
  filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  filter.FilterActivation = CAN_FILTER_ENABLE;
  filter.FilterBank = 0;
  filter.SlaveStartFilterBank = 0;
  
  if( HAL_CAN_ConfigFilter( &hcan, &filter ) != HAL_OK )
  {
   	Error_Handler();
  }

	if (HAL_CAN_Start(&hcan) != HAL_OK)
    {
      Error_Handler();
    }

7、在while中把接收到的CAN数据从USB发送出去

if(HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) >= 1)
	{
		HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, &Rxdata[0]);

		HAL_GPIO_TogglePin(RED_GPIO_Port, RED_Pin);

		data[0] = RxHeader.Timestamp;
		data[1] = RxHeader.Timestamp >> 8;
		data[2] = RxHeader.Timestamp >> 16;
		data[3] = RxHeader.Timestamp >> 24;

		data[4] = RxHeader.IDE;
		data[5] = RxHeader.RTR;

		if(RxHeader.IDE == CAN_ID_STD)
		{
			data[6] = RxHeader.StdId;
			data[7] = RxHeader.StdId >> 8;
			data[8] = RxHeader.StdId >> 16;
			data[9] = RxHeader.StdId >> 24;
		}
		else
		{
			data[6] = RxHeader.ExtId;
			data[7] = RxHeader.ExtId >> 8;
			data[8] = RxHeader.ExtId >> 16;
			data[9] = RxHeader.ExtId >> 24;
		}

		data[10] = RxHeader.DLC;

		for(i=0;i<8;i++)
		{
			data[i + 11] = Rxdata[i];
		}

		USBD_CUSTOM_HID_SendReport_FS(data, CUSTOM_HID_EPIN_SIZE);
	}

8、在usbd_custom_hid_if.c中把USB接收到的数据从CAN发出去

static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
  CAN_TxHeaderTypeDef msg;
  uint8_t data[8];
  uint8_t i;
   uint32_t txMailbox = 0;
  
  USBD_CUSTOM_HID_HandleTypeDef *hhid = (void*)hUsbDeviceFS.pClassData;

  HAL_GPIO_TogglePin(YEL_GPIO_Port, YEL_Pin);	

  if(hhid->Report_buf[4] == CAN_ID_STD)
  {
	msg.IDE = CAN_ID_STD;
	msg.StdId = hhid->Report_buf[6];
	msg.StdId += ((uint32_t)hhid->Report_buf[7] << 8);
  }
  else
  {
  	msg.IDE = CAN_ID_EXT;
	msg.ExtId = hhid->Report_buf[6];
	msg.ExtId += ((uint32_t)hhid->Report_buf[7] << 8);
	msg.ExtId += ((uint32_t)hhid->Report_buf[8] << 8);
	msg.ExtId += ((uint32_t)hhid->Report_buf[9] << 8);
  }
	msg.RTR = CAN_RTR_DATA;
  msg.DLC = hhid->Report_buf[10];
  for(i=0;i<8;i++)
  {
  	data[i] = hhid->Report_buf[11+i];
  }

  HAL_CAN_AddTxMessage(&hcan, &msg, data,  &txMailbox);
	
	return 0;
  /* USER CODE END 6 */
}

/* USER CODE BEGIN 7 */
/**
  * @brief  Send the report to the Host
  * @param  report: The report to be sent
  * @param  len: The report length
  * @retval USBD_OK if all operations are OK else USBD_FAIL
  */

 int8_t USBD_CUSTOM_HID_SendReport_FS(uint8_t *report, uint16_t len)
{
  return USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, report, len);
}

这里用到的是USB的HID模式,优点就是电脑免驱,插入电脑就可以使用,用HID上位机也可以很方便进行调试。

到此USB转CAN的基本收发功能已经实现,现有的CAN的波特率是固定500K,后期可通过USB协议更改波特率。

下一步实现兼容使用周立功上位机

网盘网盘icon-default.png?t=N6B9https://pan.baidu.com/s/1nIK4ig2TW4pdCfUxiYL6VA?pwd=1234

  • 17
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值