完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言
stm32f1xx_hal_msp.c 文件定义了两个函数 HAL_MspInit 和 HAL_MspDeInit。这两个函数分别被文件 stm32f1xx_hal.c 中的 HAL_Init 和 HAL_DeInit 所调用。HAL_MspInit 函数的主要作用是进行 MCU相关的硬件初始化操作。例如我们要初始化某些硬件,我们可以硬件相关的初始化配置 写在HAL_MspDeinit 函数中。这样的话,在系统启动后调用了 HAL_Init 之后,会自动调用硬件初始化函数。 实际上,我们在工程模板中直接删掉 stm32f1xx_hal_msp.c 文件也不会对程序运行产生任何影响。 1.函数组成 main.c里面仅包含一个USB设备函数初始化函数 MX_USB_DEVICE_Init(),在程序开始时调用。 u***d_cdc_interface.c为USB的CDC类应用层文件,里面包含虚拟串口的接收,发送和控制等函数。 u***_desc.c 包含USB的描述符,以及USB枚举处理等函数。 u***_conf.c 为USB管脚配置文件,包含引USB引脚初始化以及参数设置,中断回调函数等。 2.初始化 定义USB结构体句柄 STM32的标准库中,句柄是一种特殊的指针,通常指向结构体! USBD_HandleTypeDef hU***DeviceFS 在HAL库中,USBD初始化结构体变量,我们要定义为全局变量。所以说上述代码放在函数外边。句柄用于管理进程例程之间的共享数据资源,查看结构体USBD_HandleTypeDef成员: typedef struct _USBD_HandleTypeDef { uint8_t id; uint32_t dev_config; uint32_t dev_default_config; uint32_t dev_config_status; USBD_SpeedTypeDef dev_speed; USBD_EndpointTypeDef ep_in[15]; USBD_EndpointTypeDef ep_out[15]; uint32_t ep0_state; uint32_t ep0_data_len; uint8_t dev_state; uint8_t dev_old_state; uint8_t dev_address; uint8_t dev_connection_status; uint8_t dev_test_mode; uint32_t dev_remote_wakeup; USBD_SetupReqTypedef request; USBD_DescriptorsTypeDef *pDesc; USBD_ClassTypeDef *pClass; void *pClassData; void *pUserData; void *pData; } USBD_HandleTypeDef; 声明用户自定义变量 //u***d_cdc_if.c #define APP_RX_DATA_SIZE 2048 #define APP_TX_DATA_SIZE 2048 //通过USB接收的数据存储在此缓冲区中 uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; //通过USB CDC发送的数据存储在此缓冲区中 uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; USB初始化 //u***_device.c void MX_USB_DEVICE_Init(void) { if (USBD_Init(&hU***DeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) { Error_Handler(); } if (USBD_RegisterClass(&hU***DeviceFS, &USBD_CDC) != USBD_OK) { Error_Handler(); } if (USBD_CDC_RegisterInterface(&hU***DeviceFS, &USBD_Interface_fops_FS) != USBD_OK) { Error_Handler(); } if (USBD_Start(&hU***DeviceFS) != USBD_OK) { Error_Handler(); } } 初始化函数第三步如下: uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops) { uint8_t ret = USBD_FAIL; if(fops != NULL) { pdev->pUserData= fops; ret = USBD_OK; } return ret; } USBD_CDC_ItfTypeDef结构体定义如下: 有四个成员,分别是四个函数指针 typedef struct _USBD_CDC_Itf { int8_t (* Init) (void); int8_t (* DeInit) (void); int8_t (* Control) (uint8_t, uint8_t * , uint16_t); int8_t (* Receive) (uint8_t *, uint32_t *); }USBD_CDC_ItfTypeDef; USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = { CDC_Init_FS, CDC_DeInit_FS, CDC_Control_FS, CDC_Receive_FS }; int8_t CDC_Init_FS(void) 初始化CDC媒体底层,设置了收发Buffer static int8_t CDC_Init_FS(void) { /* Set Application Buffers */ USBD_CDC_SetTxBuffer(&hU***DeviceFS, UserTxBufferFS, 0); USBD_CDC_SetRxBuffer(&hU***DeviceFS, UserRxBufferFS); return (USBD_OK); } static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length) CDC控制命令处理,列举了主机有可能向设备发送的一些命令。没有具体的处理过程,需要用户自己编写。其中包括串口参数的设置,要做串口转USB通信的话需要修改这里。只是为了用USB与PC通信则不用管这里。每个命令具体的意思需要查询CDC类手册。 static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length) { switch (cmd) { case CDC_SEND_ENCAPSULATED_COMMAND: break; case CDC_GET_ENCAPSULATED_RESPONSE: break; case CDC_SET_COMM_FEATURE: break; case CDC_GET_COMM_FEATURE: break; case CDC_CLEAR_COMM_FEATURE: break; case CDC_SET_LINE_CODING: break; case CDC_GET_LINE_CODING: break; case CDC_SET_CONTROL_LINE_STATE: break; case CDC_SEND_BREAK: break; default: break; } return (USBD_OK); } int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) 虚拟串口接收函数,Buf为接收缓存。这个缓存实际上就是CDC_Init_FS()中设置的UserRxBufferFS[]数组。这个全局数组的定义在u***d_cdc_if.c文件中。Len为接收到数据的长度。这个变量不是全局的,需要用户声明变量把这个传出去。 static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { USBD_CDC_SetRxBuffer(&hU***DeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hU***DeviceFS); return (USBD_OK); } 注意:CDC_Receive_FS()是接收函数。这个函数不需要调用。直接在函数中添加代码把接受到的数据和数据长度复制到自己定义的接收缓存。 u***d_cdc_if.c中CDC_Transmit_FS()是发送函数。要发送时调用这个函数,需要传入待发送数据的指针和长度。 //处理数据函数 void HandleReceiveData (uint8_t* Buf, uint32_t *Len) { CDC_Transmit_FS(Buf,(uint16_t)Len); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1752 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1611 浏览 1 评论
1052 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1666 浏览 2 评论
1926浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
711浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
560浏览 3评论
583浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 14:03 , Processed in 0.805757 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号