本帖最后由 shiyongzhu 于 2015-10-13 22:45 编辑
拿到F446有段时间了,这段时间主要对F446开发板的USB功能进行了一下学习。
F446开发板的功能还是比较强大的,其既有全速的USB还有高速的USB接口,而且都支持OTG功能,可以说完全满足的开发者的各种的不同需求。因此本人打算使用F446开发板做个鼠标,也算是抛砖引玉了。
当前进行STM32 MCU开发,有两种库工选择,即标准外设库和hal库(cubemx生成),hal库开发方法是ST公司极力推广的开发方法,因此本帖采用这种开发方法。
1、 使用cubemx生成代码 (1)打开cubemx的更新软件STM32CubeUpdater,检查是否有F446开发板的固件库(需要1.8.0版本)。如图没有,则进行更新。 (2)打开cubemx程序,选择New Project建立新的工程。再Board Selector中选择Nucleo类型的 F446RE开发板。 点击OK则得到工程模板,进入Pinout界面进行引脚配置,开启USB_OTG_FS外设为Device模式,即将开发板作为外设设备,开启该外设后右侧封装图中PA11、PA12将会进行示意表示。为了生成USB设备基本的代码还需要配置MiddleWares中的USB_DEVICE IP为Human Interface Device Class(HID)。 然后进行时钟配置,注意当使用内部时钟作为锁相环的输入时,无法使系统时钟达到最大的180MHz,经测试100MHz可以达到,因此按照100MHz配置,USB外设采用专用的48MHz时钟。 2、 代码修改 (1)根据以上的配置最终可以生成需要的代码模板,该代码实现了USB设备的枚举过程。在主程序中加入led.c、delay.c代码,主程序代码如下: - /* Includes ------------------------------------------------------------------*/
- #include "stm32f4xx_hal.h"
- #include "usb_device.h"
- /* USER CODE BEGIN Includes */
- #include "usb_device.h"
- #include "usbd_core.h"
- #include "usbd_desc.h"
- #include "usbd_hid.h"
- #include "delay.h"
- #include "led.h"
- /* USER CODE END Includes */
- /* Private variables ---------------------------------------------------------*/
- extern USBD_HandleTypeDef hUsbDeviceFS;
- /* USER CODE BEGIN PV */
- /* Private variables ---------------------------------------------------------*/
- //¼ÆÊýÆ÷
- volatile uint32_t count_millsecond; //ϵͳ¼ÆÊýÆ÷
- /* USER CODE END PV */
- /* Private function prototypes -----------------------------------------------*/
- void SystemClock_Config(void);
- static void MX_GPIO_Init(void);
- void HAL_SYSTICK_Callback(void);
- /* USER CODE BEGIN PFP */
- /* Private function prototypes -----------------------------------------------*/
- /* USER CODE END PFP */
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- int main(void)
- {
- /* USER CODE BEGIN 1 */
- uint32_t led_time;
- uint8_t HID_Buffer[4]={0x00,0x0a,0x22,0x00};
- /* USER CODE END 1 */
- /* MCU Configuration----------------------------------------------------------*/
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
- /* Configure the system clock */
- SystemClock_Config();
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_USB_DEVICE_Init();
- /* USER CODE BEGIN 2 */
- /* USER CODE END 2 */
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- if((Check_Delay(led_time))) //µç»úÔËÐÐʱLEDÉÁ˸
- {
- led_time = Set_Delay(250);
- Led_Change();
- USBD_HID_SendReport(&hUsbDeviceFS, HID_Buffer, 4);
- }
- /* USER CODE BEGIN 3 */
- }
- /* USER CODE END 3 */
- }
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- /** System Clock Configuration
- */
- void SystemClock_Config(void)
- {
- RCC_OscInitTypeDef RCC_OscInitStruct;
- // RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
- __PWR_CLK_ENABLE();
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
- RCC_OscInitStruct.HSIState = RCC_HSI_ON;
- RCC_OscInitStruct.HSICalibrationValue = 16;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
- RCC_OscInitStruct.PLL.PLLM = 8;
- RCC_OscInitStruct.PLL.PLLN = 100;
- RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
- RCC_OscInitStruct.PLL.PLLQ = 8;
- RCC_OscInitStruct.PLL.PLLR = 2;
- HAL_RCC_OscConfig(&RCC_OscInitStruct);
- HAL_PWREx_ActivateOverDrive();
- RCC_ClkInitStruct.ClockType = 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_DIV4;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
- HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
- PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48;
- PeriphClkInitStruct.PLLSAI.PLLSAIM = 16;
- PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
- PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2;
- PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4;
- PeriphClkInitStruct.PLLSAIDivQ = 1;
- PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLSAIP;
- HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
- HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
- HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
- /* SysTick_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
- }
- /** Configure pins as
- * Analog
- * Input
- * Output
- * EVENT_OUT
- * EXTI
- PA2 ------> USART2_TX
- PA3 ------> USART2_RX
- */
- void MX_GPIO_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStruct;
- /* GPIO Ports Clock Enable */
- __GPIOC_CLK_ENABLE();
- __GPIOH_CLK_ENABLE();
- __GPIOA_CLK_ENABLE();
- __GPIOB_CLK_ENABLE();
- /*Configure GPIO pin : PC13 */
- GPIO_InitStruct.Pin = GPIO_PIN_13;
- GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
- /*Configure GPIO pins : PA2 PA3 */
- GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- /*Configure GPIO pin : PA5 */
- GPIO_InitStruct.Pin = GPIO_PIN_5;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
- }
- /* USER CODE BEGIN 4 */
- /*
- * º¯ÊýÃû³Æ: HAL_SYSTICK_Callback();
- * ¹¦ÄÜÃèÊö: ϵͳ¼ÆÊ±Æ÷Öжϴ¦Àíº¯Êý
- * ÊäÈë²ÎÊý: void
- * ·µ»Ø²ÎÊý: ÎÞ
- */
- void HAL_SYSTICK_Callback()
- {
- count_millsecond++;
- }
- /* USER CODE END 4 */
(2)为了让顺利的运行,还需要根据USB协议规定,全速设备须在数据D+上上拉1.5K电阻。 由于源程序代码有8MB多,没法直接上传,有需要代码的可以私信我。
|