MCUXpresso Config Tools 強大的代碼生成功能超乎你的想象。下面我們來一起學(xué)習(xí)如何用 MCUXpresso Config Tools 來從頭開始創(chuàng)建一個屬于你自己的 USB 實用例程。我們以LPC55S69 的鍵盤鼠標(biāo)復(fù)合 USB 設(shè)備工程為例,一步步實現(xiàn) USB 復(fù)合設(shè)備的配置并生成相應(yīng)的 USB 源文件,進(jìn)而實現(xiàn) USB 復(fù)合設(shè)備的功能。
開發(fā)環(huán)境:MCUXpresso IDE v11.1.0,
SDK:SDK_2.7.1_LPCXpresso55S69
開發(fā)板:LPCXpresso55S69-EVK。
1. 首先在MCUXpresso IDE中安裝好 LPC55S69 的 SDK, 下面使用的 SDKSDK_2.7.1_LPCXpresso55S69,左鍵單擊 New project
2.選擇 LPCXpresso55s69 的 SDK,點擊 next
3.在 Middleware 窗口中選擇 USB device 文件,在選中 USB device 文件的同時,USBcommon 文件會同時被選中,點擊 Finish
4. 如下圖所示,為創(chuàng)建好的 usb 工程。
5. 選中新創(chuàng)建的 LPC55S69_Project 文件,單擊 Config Tool 圖標(biāo)右側(cè)的箭頭,從下拉菜單中選擇 Open Peripherals
6. 在 Peripherals 窗口中選擇 USB0,在彈出的中間的 USB0 窗口中進(jìn)行 USB 的相關(guān)配置。
7. 在 USB 設(shè)置的 Preset 下拉菜單中選擇 HID Keyboard
8.點擊 Supported interfaces 右側(cè)的加號,添加一個新的設(shè)備,在 Class 窗口中選擇HID,Preset 窗口中選擇 mouse
9.在 Problems 窗口中右鍵選擇 Error,然后選擇 Show problem in BOARD_BootClockPLL150M
10. 在“Clocks Diagram”里選中 USB0CLKSEL, 在彈出的時鐘配置界面,打開 FRO_96MHz 時鐘,將 USB0 的時鐘源設(shè)置為 FRO 96MHz clock,分頻系數(shù)選擇/2,得到 USB0 的時鐘頻率為 48MHz
11.時鐘設(shè)置好之后,回到 Peripheral 窗口中,在 Problems 窗口里,通過上一步配置 USB0時鐘源,已經(jīng)去除掉第一個 Error;繼續(xù)配置來去除第二個Error。同樣右鍵單擊 Error,這里需要我們給 USB0 分配引腳,左鍵單擊選擇 Route to[78]……, 手動切換到 PinConfiguration 界面,我們可以看到 USB0_VBUS 管腳已設(shè)置好。
12. 設(shè)置完成之后,選擇 Update Code,在圖中可以看到要創(chuàng)建和修改的文件。
13.配置好的工程文件如圖所示
14.創(chuàng)建好新的工程后,打開 source 文件夾下主程序源文件,用戶需要在 LPC55S69_Project.c文件中編寫代碼,實現(xiàn)特定的鍵盤鼠標(biāo)復(fù)合設(shè)備功能。將 15 部分所示代碼添加在在LPC55S69_Project.c 文件中,它可以實現(xiàn)鍵盤鼠標(biāo)復(fù)合設(shè)備功能。
15.添加的代碼如下。
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC55S69_cm33_core0.h"
#include "fsl_debug_console.h"
#include "usb_device_composite.h"
#include "usb_device_config.h"
#include "usb.h"
#include "usb_device.h"
#include "usb_device_class.h"
#include "usb_device_hid.h"
#include "usb_device_ch9.h"
#include "usb_device_descriptor.h"
#if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
#include "fsl_sysmpu.h"
#endif
#if defined(FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)
#include "usb_phy.h"
#endif
#if (defined(USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U))
#include "fsl_power.h"
#endif
#if (defined(USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS > 0U))
#if !((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U))
#include "fsl_mrt.h"
#endif
#include "fsl_power.h"
#endif
/* TODO: insert other include files here. */
/* TODO: insert other definitions and declarations here. */
#if defined (USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
static clock_usbfs_src_t USB0_GetClockSource(void);
#endif
#if defined (USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
/*!
* @brief Function to retrieve clock source for USB0.
*
* @return Used clock source
*/
static clock_usbfs_src_t USB0_GetClockSource()
{
clock_usbfs_src_t src;
switch (SYSCON->USB0CLKSEL)
{
case 0U:
src = kCLOCK_UsbfsSrcMainClock;
break;
case 1U:
src = kCLOCK_UsbfsSrcPll0;
break;
case 3U:
src = kCLOCK_UsbfsSrcFro;
break;
case 5U:
src = kCLOCK_UsbfsSrcPll1;
break;
default:
src = kCLOCK_UsbfsSrcNone;
break;
}
return src;
}
#endif
/*
* @brief Application entry point.
*/
int main(void)
{
/* attach 12 MHz clock to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
BOARD_InitPins();
BOARD_BootClockPLL150M();
BOARD_InitDebugConsole();
NVIC_ClearPendingIRQ(USB0_IRQn);
NVIC_ClearPendingIRQ(USB0_NEEDCLK_IRQn);
NVIC_ClearPendingIRQ(USB1_IRQn);
NVIC_ClearPendingIRQ(USB1_NEEDCLK_IRQn);
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY); /*< Turn on USB0 Phy */
POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /*< Turn on USB1 Phy */
/* reset the IP to make sure it's in reset state. */
RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB1H_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB1D_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB1_RST_SHIFT_RSTn);
RESET_PeripheralReset(kUSB1RAM_RST_SHIFT_RSTn);
#if (defined USB_DEVICE_CONFIG_LPCIP3511HS) && (USB_DEVICE_CONFIG_LPCIP3511HS)
CLOCK_EnableClock(kCLOCK_Usbh1);
/* Put PHY powerdown under software control */
*((uint32_t *)(USBHSH_BASE + 0x50)) = USBHSH_PORTMODE_SW_PDCOM_MASK;
/* According to reference mannual, device mode setting has to be set by access usb host register */
*((uint32_t *)(USBHSH_BASE + 0x50)) |= USBHSH_PORTMODE_DEV_ENABLE_MASK;
/* enable usb1 host clock */
CLOCK_DisableClock(kCLOCK_Usbh1);
#endif
#if defined (USB_DEVICE_CONFIG_LPCIP3511FS) && (USB_DEVICE_CONFIG_LPCIP3511FS > 0U)
/* Turn on USB Phy */
POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY);
/* enable usb0 host clock */
CLOCK_EnableClock(kCLOCK_Usbhsl0);
/*According to reference mannual, device mode setting has to be set by access usb host register */
*((uint32_t *)(USBFSH_BASE + 0x5C)) |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
/* disable usb0 host clock */
CLOCK_DisableClock(kCLOCK_Usbhsl0);
if (USB0_GetClockSource() == kCLOCK_UsbfsSrcFro)
{
/* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
ANACTRL->FRO192M_CTRL = (ANACTRL->FRO192M_CTRL &
~(ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK)) | ANACTRL_FRO192M_CTRL_USBCLKADJ(1U);
}
CLOCK_EnableClock(kCLOCK_Usbd0);
CLOCK_EnableClock(kCLOCK_UsbRam1);
#if defined(FSL_FEATURE_USB_USB_RAM) && (FSL_FEATURE_USB_USB_RAM)
for (int i = 0; i < FSL_FEATURE_USB_USB_RAM; i++)
{
((uint8_t *)FSL_FEATURE_USB_USB_RAM_BASE_ADDRESS)[i] = 0x00U;
}
#endif
#endif
USB_DeviceApplicationInit();
while (1U)
{
#if USB_DEVICE_CONFIG_USE_TASK
USB_DeviceTaskFn(g_UsbDeviceComposite.deviceHandle);
#endif
}
}
16. 連接開發(fā)板的 P6 調(diào)試口將 USB 程序下載到開發(fā)板中,下載完成后重新上電,將開發(fā)板的 P10 FS USB 口連接到 PC 機上。
運行結(jié)果:
對于 HID 鼠標(biāo):可觀察到鼠標(biāo)箭頭在 PC 屏幕上呈矩形移動。
對于 HID 鍵盤:可見當(dāng)前屏幕上下滾動。