新建工程
打开CubeMX
选择STM32F407ZGTx芯片新建工程,选择时钟
选择SW Debug
勾选串口1,USB_OTG_FS(USB必须使能中断)
选择时钟树配置
生成工程
移植CherryUSB
添加头文件路径
工程结构如图
CherryUSB移植适配
在main.c中实现串口重定向和usb端口初始化
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1000);
return ch;
}
void usb_dc_low_level_init(uint8_t busid)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
*/
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_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* USB_OTG_FS interrupt Init */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 3);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
}
void usb_dc_low_level_deinit(uint8_t busid)
{
}
主函数中注释掉MX_USB_OTG_FS_PCD_Init();添加USB初始化函数和测试函数
extern void cdc_acm_msc_init(uint8_t busid, uint32_t reg_base);
cdc_acm_msc_init(0, USB_OTG_FS_PERIPH_BASE);
while (1)
{
/* USER CODE END WHILE */
extern void cdc_acm_data_send_with_dtr_test(uint8_t busid);
cdc_acm_data_send_with_dtr_test(0);
/* USER CODE BEGIN 3 */
}
在stm32f4xx_it.c中的USB中断函数中注释掉HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);添加中断函数
extern void USBD_IRQHandler(uint8_t busid);
USBD_IRQHandler(0);
重点来了
复制一份cherryusb_config_template.h命名为usb_config.h放在工程的core/inc目录下并进行修改
/* ================ USB Device Port Configuration ================*/
#define CONFIG_USBDEV_MAX_BUS 1
#define CONFIG_USBDEV_EP_NUM 4
#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2
/* ---------------- DWC2 Configuration ---------------- */
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (128)
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
修改cdc_acm_msc_template.c中的端点地址
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x01
#define CDC_INT_EP 0x82
#define MSC_IN_EP 0x83
#define MSC_OUT_EP 0x03
编译运行,进行测试
打开串口助手,勾选dtr选项,测试函数成功运行,每次传输收到了2048个字节,其中2038个'a'