STM32F072系列可以同时使用CAN与USB,利用这个功能可以制作一个简单的USB转CAN。
1、管脚配置
2、时钟配置
3、CAN配置,500Kbps
4、USB配置,这里用的是HID模式
5、下面对USB代码部份进行更改:
u***d_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,
};
u***d_conf.h中更改
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 20
/*---------- -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 33
u***d_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"
u***d_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
; }
USBD_CUSTOM_HID_SendReport_FS(data, CUSTOM_HID_EPIN_SIZE); } 8、在u***d_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*)hU***DeviceFS.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= 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(&hU***DeviceFS, report, len); } 这里用到的是USB的HID模式,优点就是电脑免驱,插入电脑就可以使用,用HID上位机也可以很方便进行调试。
到此USB转CAN的基本收发功能已经实现,现有的CAN的波特率是固定500K,后期可通过USB协议更改波特率。
下一步实现兼容使用周立功上位机
|