12下一页
返回列表 发新帖我要提问本帖赏金: 5.00元(功能说明)

[STM32F4] 【F446RE开发板试用】 ——做个USB鼠标玩玩

[复制链接]
4481|25
 楼主| shiyongzhu 发表于 2015-10-13 22:43 | 显示全部楼层 |阅读模式
本帖最后由 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版本)。如图没有,则进行更新。
查看更新库.JPG
2)打开cubemx程序,选择New Project建立新的工程。再Board Selector中选择Nucleo类型的 F446RE开发板。
开发板中已有STM32F466.JPG
点击OK则得到工程模板,进入Pinout界面进行引脚配置,开启USB_OTG_FS外设为Device模式,即将开发板作为外设设备,开启该外设后右侧封装图中PA11PA12将会进行示意表示。为了生成USB设备基本的代码还需要配置MiddleWares中的USB_DEVICE IPHuman Interface Device Class(HID)
配置成Device.jpg
选择HID.jpg
然后进行时钟配置,注意当使用内部时钟作为锁相环的输入时,无法使系统时钟达到最大的180MHz,经测试100MHz可以达到,因此按照100MHz配置,USB外设采用专用的48MHz时钟。
时钟配置.JPG
2、  代码修改
1)根据以上的配置最终可以生成需要的代码模板,该代码实现了USB设备的枚举过程。在主程序中加入led.cdelay.c代码,主程序代码如下:
         
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "stm32f4xx_hal.h"
  3. #include "usb_device.h"

  4. /* USER CODE BEGIN Includes */
  5. #include "usb_device.h"
  6. #include "usbd_core.h"
  7. #include "usbd_desc.h"
  8. #include "usbd_hid.h"
  9. #include "delay.h"
  10. #include "led.h"

  11. /* USER CODE END Includes */

  12. /* Private variables ---------------------------------------------------------*/
  13. extern USBD_HandleTypeDef hUsbDeviceFS;
  14. /* USER CODE BEGIN PV */
  15. /* Private variables ---------------------------------------------------------*/
  16. //¼ÆÊýÆ÷
  17. volatile uint32_t count_millsecond;                                                                                                        //ϵͳ¼ÆÊýÆ÷
  18. /* USER CODE END PV */

  19. /* Private function prototypes -----------------------------------------------*/
  20. void SystemClock_Config(void);
  21. static void MX_GPIO_Init(void);
  22. void HAL_SYSTICK_Callback(void);
  23. /* USER CODE BEGIN PFP */
  24. /* Private function prototypes -----------------------------------------------*/

  25. /* USER CODE END PFP */

  26. /* USER CODE BEGIN 0 */

  27. /* USER CODE END 0 */

  28. int main(void)
  29. {

  30.   /* USER CODE BEGIN 1 */
  31.         uint32_t led_time;
  32.         uint8_t HID_Buffer[4]={0x00,0x0a,0x22,0x00};
  33.   /* USER CODE END 1 */

  34.   /* MCU Configuration----------------------------------------------------------*/

  35.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  36.   HAL_Init();

  37.   /* Configure the system clock */
  38.   SystemClock_Config();

  39.   /* Initialize all configured peripherals */
  40.   MX_GPIO_Init();
  41.   MX_USB_DEVICE_Init();

  42.   /* USER CODE BEGIN 2 */

  43.   /* USER CODE END 2 */

  44.   /* Infinite loop */
  45.   /* USER CODE BEGIN WHILE */
  46.   while (1)
  47.   {
  48.   /* USER CODE END WHILE */
  49.                 if((Check_Delay(led_time)))                                                                                                                                                                        //µç»úÔËÐÐʱLEDÉÁ˸
  50.                 {
  51.                         led_time = Set_Delay(250);
  52.                         Led_Change();
  53.                         USBD_HID_SendReport(&hUsbDeviceFS, HID_Buffer, 4);
  54.                 }
  55.   /* USER CODE BEGIN 3 */

  56.   }
  57.   /* USER CODE END 3 */

  58. }
  59.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  60. /** System Clock Configuration
  61. */
  62. void SystemClock_Config(void)
  63. {

  64.   RCC_OscInitTypeDef RCC_OscInitStruct;
  65. //  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  66.   RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

  67.   __PWR_CLK_ENABLE();

  68.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  69.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  70.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  71.   RCC_OscInitStruct.HSICalibrationValue = 16;
  72.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  73.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  74.   RCC_OscInitStruct.PLL.PLLM = 8;
  75.   RCC_OscInitStruct.PLL.PLLN = 100;
  76.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  77.   RCC_OscInitStruct.PLL.PLLQ = 8;
  78.   RCC_OscInitStruct.PLL.PLLR = 2;
  79.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  80.   HAL_PWREx_ActivateOverDrive();

  81.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
  82.                               |RCC_CLOCKTYPE_PCLK2;
  83.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  84.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  85.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  86.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  87.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  88.   PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CK48;
  89.   PeriphClkInitStruct.PLLSAI.PLLSAIM = 16;
  90.   PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
  91.   PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2;
  92.   PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4;
  93.   PeriphClkInitStruct.PLLSAIDivQ = 1;
  94.   PeriphClkInitStruct.Clk48ClockSelection = RCC_CK48CLKSOURCE_PLLSAIP;
  95.   HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

  96.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  97.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  98.   /* SysTick_IRQn interrupt configuration */
  99.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  100. }

  101. /** Configure pins as
  102.         * Analog
  103.         * Input
  104.         * Output
  105.         * EVENT_OUT
  106.         * EXTI
  107.      PA2   ------> USART2_TX
  108.      PA3   ------> USART2_RX
  109. */
  110. void MX_GPIO_Init(void)
  111. {

  112.   GPIO_InitTypeDef GPIO_InitStruct;

  113.   /* GPIO Ports Clock Enable */
  114.   __GPIOC_CLK_ENABLE();
  115.   __GPIOH_CLK_ENABLE();
  116.   __GPIOA_CLK_ENABLE();
  117.   __GPIOB_CLK_ENABLE();

  118.   /*Configure GPIO pin : PC13 */
  119.   GPIO_InitStruct.Pin = GPIO_PIN_13;
  120.   GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  121.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  122.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  123.   /*Configure GPIO pins : PA2 PA3 */
  124.   GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
  125.   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  126.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  127.   GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  128.   GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  129.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  130.   /*Configure GPIO pin : PA5 */
  131.   GPIO_InitStruct.Pin = GPIO_PIN_5;
  132.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  133.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  134.   GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  135.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  136. }

  137. /* USER CODE BEGIN 4 */
  138. /*
  139. * º¯ÊýÃû³Æ: HAL_SYSTICK_Callback();
  140. * ¹¦ÄÜÃèÊö: ϵͳ¼ÆÊ±Æ÷Öжϴ¦Àíº¯Êý
  141. * ÊäÈë²ÎÊý: void
  142. * ·µ»Ø²ÎÊý: ÎÞ
  143. */
  144. void HAL_SYSTICK_Callback()
  145. {
  146.         count_millsecond++;
  147. }
  148. /* USER CODE END 4 */
2)为了让顺利的运行,还需要根据USB协议规定,全速设备须在数据D+上上拉1.5K电阻。
上拉电阻.jpg
由于源程序代码有8MB多,没法直接上传,有需要代码的可以私信我。


打赏榜单

21ic小喇叭 打赏了 5.00 元 2015-10-26

kevin0129 发表于 2015-10-14 08:51 | 显示全部楼层
QQ截图20151014084947.jpg
楼主把时钟配置成这样就能泡在180M主频,同时USB的48M时钟也不会有问题
songchenping 发表于 2015-10-14 08:56 | 显示全部楼层
谢谢分享
 楼主| shiyongzhu 发表于 2015-10-14 18:16 | 显示全部楼层
kevin0129 发表于 2015-10-14 08:51
楼主把时钟配置成这样就能泡在180M主频,同时USB的48M时钟也不会有问题

我使用了片内时钟,片外估计能跑到180MHz吧
 楼主| shiyongzhu 发表于 2015-10-14 18:18 | 显示全部楼层
kevin0129 发表于 2015-10-14 08:51
楼主把时钟配置成这样就能泡在180M主频,同时USB的48M时钟也不会有问题

我使用了片内时钟,片外估计能跑到180MHz吧
643757107 发表于 2015-10-14 18:55 | 显示全部楼层
做好的鼠标能用吗?给个图看看,什么效果。
玛尼玛尼哄 发表于 2015-10-14 22:45 | 显示全部楼层
如何让计算机认为你的那个MCU发送的指令是鼠标指令啊。
minzisc 发表于 2022-12-4 19:52 | 显示全部楼层
usb怎么配置的?              
houjiakai 发表于 2022-12-4 22:22 | 显示全部楼层
需要上位机控制的吗?
              
MessageRing 发表于 2022-12-6 13:59 | 显示全部楼层
usb怎么配置啊
sesefadou 发表于 2022-12-6 14:01 | 显示全部楼层
这个是否需要安装相关的驱动呢?              
Stahan 发表于 2022-12-6 15:21 | 显示全部楼层
如何让计算机认为你的那个MCU发送的指令是鼠标指令啊
Henryko 发表于 2022-12-6 15:42 | 显示全部楼层
这个要不要装驱动啊
jackcat 发表于 2024-6-5 15:01 | 显示全部楼层
USB外设采用专用的48MHz时钟
mollylawrence 发表于 2024-6-5 21:18 | 显示全部楼层
在cubemx中选择New Project,选择F446RE开发板,并开启USB_OTG_FS外设作为Device模式。配置USB_DEVICE IP为Human Interface Device Class (HID)。
robincotton 发表于 2024-6-7 16:57 | 显示全部楼层
需要熟悉USB协议,尤其是HID(Human Interface Device)类设备的标准,因为鼠标属于HID设备。了解报告描述符、设备描述符等USB描述符的构造对于正确配置USB设备至关重要。
linfelix 发表于 2024-6-9 12:57 | 显示全部楼层
在IDE中新建工程,并正确配置使用标准HAL库,以避免编译时出现未定义声明的错误。
geraldbetty 发表于 2024-6-12 12:03 | 显示全部楼层
STM32F4系列提供了USB库,可以用来简化USB设备的开发过程。
plsbackup 发表于 2024-6-14 11:20 | 显示全部楼层
需要熟悉USB协议栈,特别是USB HID(Human Interface Device)协议,因为鼠标是HID类设备。
1988020566 发表于 2024-6-14 20:31 | 显示全部楼层
STM32CubeMX可以用来生成初始化代码,同时STM32 HAL库包含USB设备库,这将大大简化USB设备的编程。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

19

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部