This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C123GH6PM:尝试将 HID 开发键盘项目从 TM4C123G 示例修改为 TM4C123GXL

Guru**** 2618835 points

Other Parts Discussed in Thread: EK-TM4C1294XL, EK-TM4C123GXL, TM4C123GH6PM, TM4C123GH6PGE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/787213/tm4c123gh6pm-trying-to-adapt-hid-dev-keyboard-project-from-tm4c123g-example-to-tm4c123gxl

器件型号:TM4C123GH6PM
主题中讨论的其他部件:EK-TM4C123GXLEK-TM4C1294XLTM4C123DK-TM4C123GTM4C123GH6PGE

我尝试将123G 的示例转换为123GXL、但未成功。  是否有合适的方法将示例移植到其他处理器?  嗯、当然有一种正确的方法、但我显然不知道。

我已经编译了该项目、但如果我启用 USB 引脚的模拟功能、我会得到故障 ISR。  如果我不启用模拟功能、应用程序将运行、但没有 USB 中断(这并不奇怪)。  我尝试将 GXL 的 USB 游戏 epad 的 Tiva 示例与 G 的键盘开发 HID 合并。 我可以发布代码、但这并不是很好、我担心我会因为这种方法而离开工作岗位。

最后、我需要一个用于123GXL 的 HID 开发键盘。  如果可能的话,我的头发还剩下什么。

谢谢、

Joe

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Joseph Haas88"]我尝试将123G 的示例转换为123GXL,但未成功。

    我感到困惑的是、这两个数字都不是完整的器件型号。 您是否意味着您尝试转换用于 EK-TM4C1294XL Launchpad 的 TivaWare 中的示例项目、以便在 EK-TM4C123GXL Launchpad 上使用?  下面是一个介绍 TM4C123和 TM4C129器件之间差异的文档: http://www.ti.com/lit/an/spma065/spma065.pdf

    从示例项目"C:\ti\TivaWare_C_Series-2.1.4.178\examples\dk-tm4c123g\USB_host_keyboard"开始、并删除与该开发板上的 LCD 显示屏通信的所有代码可能会更容易。

    [引用 user="Joseph Haas88"]如果启用 USB 引脚的模拟功能,我将获得故障 ISR [/quot]

    您是说调用 GPIOPinTypeUSBAnalog ()时会出现数据中止吗? 对于 TM4C123、代码应为:

    //
    //启用对 USB 控制器的计时。
    //
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_USB0);
    
    //
    //配置 USB 操作所需的引脚。
    //
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOG);
    ROM_GPIOPinConfigure (GPIO_PG4_USB0EPEN);
    ROM_GPIOPinTypeUSBDigital (GPIO_PORTG_BASE、GPIO_PIN_4);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOL);
    ROM_GPIOPinTypeUSBAnalog (GPIO_PORTL_BASE、GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBAnalog (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
    

     'slellaris ICDI IFU 器件'和'slellaris ICDI JTAG/SWD 接口'  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    "FaultISR"意味着我最终会在"startup_ccs.c"文件中的 FAULTISR 陷阱中。  这通常意味着访问了一个未初始化的外设寄存器。

    因此、"123G"和"123GXL"是指 TivaWare 示例文件夹(TivaWare_C_Series-2.1.4.178)下"器件"中的文件夹。

    123GXL (Launchpad)是指 TM4C123GH6PM 芯片。  "123G"文件夹是指 TM4C123GH6PGE (在设计套件板上提供...BTW、该设计套件现在似乎已经过时)。

    我已尝试将 TM4C123GH6PGE 的键盘器件示例转换为 TM4C123GH6PM Launchpad 的项目。  我已经尝试编辑一个游戏手盘示例(  其中有 TM4C123GH6PM 的示例)、我已经尝试合并这两个示例的游戏手盘和键盘示例(Franken-keyboard、结果提示名称)、并且我已经尝试编辑键盘示例以匹配 TM4C123GH6PM 芯片端口分配。  这些尝试都没有成功。

    我的最佳尝试似乎是我的最新尝试。  我从 GamePad 示例开始(已编译并运行...我得到蓝色闪烁 LED、但我没有现成的方法来验证功能、否则-在 PC 的设备管理器中*有什么变化*、但我找不到任何新的)。  然后,我开始从键盘示例复制元素,注意限制 main()顶部和主进程循环顶部之间对代码的任何更改(这是特定于设备的端口和 USB 的发生位置)。  如果我在调试器中运行代码、我最终会遇到"startup_ccs.c"中的 faultISR 陷阱。  如果我在进入调试器后进入项目、我最终会进入主进程循环、然后我可以运行代码、而不会出现故障 ISR。  器件管理器窗口中还会显示一个新的键盘(尽管如此、实例化的键盘没有来自我的描述符的描述符信息、并且两个 LaunchPad 按钮没有动作)。

    最好将示例的结构化、使器件特定的内联函数与代码中更抽象的部分分离(并进行更好的注释)。  这将使端口更容易!

    代码片段(由 Bob Crosby 提供)来自 TM4C123GH6PGE 示例、不适用于 TM4C123GH6PM、因为 USB0模块位于不同的端口块上(对于 TM4C123GH6PM 为 D、对于 GH6PGE 为 G)。  只是更改端口字符似乎不起作用、因为我曾多次尝试过。

    现在,我有一个*关闭*的东西, 但仍然有问题(请记住、这是以游戏手盘示例开始的、因此有许多注释和一些文件名尚未经过清理/编辑-请注意、我还编辑了描述符以匹配键盘示例、我将在单独的帖子中提供这些描述符):

    //
    //
    //// usb_dev_gamepad.c - KEYBD 示例的主例程。
    //
    //版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)提供此软件仅供
    和//仅供 TI 的微控制器产品使用。 软件归
    // TI 和/或其供应商所有,并受适用的版权
    //法律保护。 您不能将此软件与"病毒"开源
    //软件组合在一起以形成更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //对于
    
    本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
    //情况下、TI 不对任何
    原因造成的特殊、意外或必然//损害负责。
    //
    //这是 EK-TM4C123GXL 固件包版本2.1.4.178的一部分。
    ////
    *****************
    
    #include 
    #include 
    include "inc/hw_memblib.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_sysctl.h"
    #include "drivers/drivers/usblib.h"
    
    
    #include "drivers/drivers/usbline.包含"drivers/usb.usb/包含"drivers/usb.usb.usbline"#drivers/包含
    "usb.usb.usb/usb.usb.usb.包含"#drivers/usb.usb.usb.us.dh"#include "#drivers/包含"#drivers/drivers/usb.usb.usb.usb.usb.usb.usb.id.us.usb.line"#include "#include "#include "#drivers/usb.us.us.usb.line"#include "#include "#drivers/usb.usb.usb.usb.usb.usb.usb.usb.us.us.dh/us.us.
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    //
    //! \addtogroup example_list
    //! 

    USB HID KEYBD 设备(USB_DEV_gamepad)

    //! //! 此示例应用将评估板转换为 USB 游戏手柄 //! 使用人机接口器件 KEYBD 类的器件。 //!上的按钮 电路板报告为按钮1和2。 X、Y 和 Z 坐标为 //! 使用 GPIO 端口 E 引脚1、2和3上的 ADC 输入进行报告。 X 输入 //! 在 PE3上、Y 输入在 PE2上、Z 输入在 PE1上。 这些是 //! 未连接到任何实数输入、因此值只读出任何已打开 的值//! 引脚。 为了获得有效值、引脚的电压范围应该是 //! 从 VDDA (3V)到0V。 PF5上的蓝色 LED 用于指示 KEYBD //! USB 总线活动时闪烁。 //// ***************** // // //从 UART 接收到的 ASCII 值到相应 // USB HID 使用代码的映射。 //// ***************** 静态常量 INT8_t g_ppi8KeyUsageCodes[][2]= { {0、HID_KEYB_USAGE_SPACE}、 // 0x20 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_1}、 //! 0x21 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_FQUOTE}、//" 0x22 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_3}、 //# 0x23 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_4}、 //$ 0x24 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_5}、 //% 0x25 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_7}、 //& 0x26 {0、HID_KEYB_USAGE_FQUOTE}、 //' 0x27 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_9}、 //(0x28 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_0}、 //) 0x29 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_8}、 //* 0x2a {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_EQUAL}、 //+ 0x2b {0、HID_KEYB_USAGE_逗 号}、 //、0x2C {0、HID_KEYB_USAGE_MINUS}、 //- 0x2D {0、HID_KEYB_USAGE_PERIOD}、 //。 0x2E {0、HID_KEYB_USAGE_FSLASH}、 /// 0x2F {0、HID_KEYB_USAGE_0}、 // 0 0x30 {0、HID_KEYB_USAGE_1}、 // 1 0x31 {0、HID_KEYB_USAGE_2}、 // 2 0x32 {0、HID_KEYB_USAGE_3}、 // 3 0x33 {0、HID_KEYB_USAGE_4}、 // 4 0x34 {0、HID_KEYB_USAGE_5}、 // 5 0x35 {0、HID_KEYB_USAGE_6}、 // 6 0x36 {0、HID_KEYB_USAGE_7}、 // 7 0x37 {0、HID_KEYB_USAGE_8}、 // 8 0x38 {0、HID_KEYB_USAGE_9}、 // 9 0x39 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_DEALD}、//:0x3a {0、HID_KEYB_USAGE_TANDED}、 //;0x3b {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_逗 号}、 //< 0x3c {0、HID_KEYB_USAGE_EQUAL}、 //= 0x3D {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_PERIOD}、//> 0x3E {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_FSLASH}、//? 0x3F {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_2}、 //@ 0x40 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_A}、 // A 0x41 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_B}、 // B 0x42 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_C}、 // C 0x43 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_D}、 // D 0x44 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_E}、 // E 0x45 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_F}、 // F 0x46 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_G}、 // G 0x47 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_H}、 // H 0x48 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_I}、 // I 0x49 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_J}、 // J 0x4a {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_K}、 // K 0x4b {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_L}、 // L 0x4c {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_M}、 // M 0x4d {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_N}、 // N 0x4e {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_O}、 // O 0x4f {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_P}、 // P 0x50 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_Q}、 // Q 0x51 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_R}、 // R 0x52 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_S}、 // S 0x53 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_T}、 // T 0x54 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_U}、 // U 0x55 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_V}、 // V 0x56 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_W}、 // W 0x57 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_X}、 // X 0x58 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_Y}、 // Y 0x59 {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_Z}、 // Z 0x5a {0、HID_KEYB_USAGE_LBRACKET}、 //[ 0x5b {0、HID_KEYB_USAGE_BSLASH}、 //\ 0x5c {0、HID_KEYB_USAGE_RBRACKET}、 //] 0x5d {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_6}、 //^ 0x5e {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_MINUS}、 //_ 0x5f {0、HID_KEYB_USAGE_BQUOTE}、 //` 0x60 {0、HID_KEYB_USAGE_A}、 // A 0x61 {0、HID_KEYB_USAGE_B}、 // b 0x62 {0、HID_KEYB_USAGE_C}、 // c 0x63 {0、HID_KEYB_USAGE_D}、 // d 0x64 {0、HID_KEYB_USAGE_E}、 // e 0x65 {0、HID_KEYB_USAGE_F}、 // f 0x66 {0、HID_KEYB_USAGE_G}、 // g 0x67 {0、HID_KEYB_USAGE_H}、 // h 0x68 {0、HID_KEYB_USAGE_I}、 // I 0x69 {0、HID_KEYB_USAGE_J}、 // j 0x6a {0、HID_KEYB_USAGE_K}、 // k 0x6b {0、HID_KEYB_USAGE_L}、 // l 0x6c {0、HID_KEYB_USAGE_M}、 // m 0x6d {0、HID_KEYB_USAGE_N}、 // n 0x6e {0、HID_KEYB_USAGE_O}、 // o 0x6f {0、HID_KEYB_USAGE_P}、 // p 0x70 {0、HID_KEYB_USAGE_Q}、 // q 0x71 {0、HID_KEYB_USAGE_R}、 // r 0x72 {0、HID_KEYB_USAGE_S}、 // s 0x73 {0、HID_KEYB_USAGE_T}、 // t 0x74 {0、HID_KEYB_USAGE_U}、 // u 0x75 {0、HID_KEYB_USAGE_V}、 // v 0x76 {0、HID_KEYB_USAGE_W}、 // w 0x77 {0、HID_KEYB_USAGE_X}、 // x 0x78 {0、HID_KEYB_USAGE_Y}、 // y 0x79 {0、HID_KEYB_USAGE_Z}、 // z 0x7a {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_LBRACKET}、//{0x7B {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_BSLASH}、//| 0x7c {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_RBRACKET}、//}0x7d {HID_KEYB_LEFT_SHIFT、HID_KEYB_USAGE_BQUOTE}、//~ 0x7E }; //********* // //此全局变量指示我们是否连接到 USB 主机。 //// ***************** volatile bool g_BConnected = false; //********* // //此全局指示 USB 总线当前是否处于挂起 //状态。 //// ***************** volatile bool g_BSusspened = false; //********* // //全局系统节拍计数器保存自应用程序启动以来经过的时间 //以十分之一秒表示。 //// ***************** 易失性 uint32_t g_ui32SysTickCount; //************* // //假设 主机已断开连接,在发送每个 USB 数据包之前等待的系统节拍数。 值50等于半秒。 //// ***************** #define MAX_SEND_DELAY 50 //********* // //一个活动计数器,用于将 LED 闪烁速度减至可见速率。 //// ***************** 静态 uint32_t g_ui32更新; //********* // //此枚举保存了 KEYBD 在 //正常运行期间可以处于的各种状态。 //// ***************** volatile enum { // //尚未配置。 // eStateNotConfigured、 // //已连接,不等待要发送的数据。 // eStateIdle、 // //暂停。 // eStateSuspend、 // //已连接并等待数据发送。 // eStateSending } g_iKeybdState; //********* // //如果驱动程序库遇到错误,则调用的错误例程。 //// ***************** #ifdef debug void __error__(char *dpcFilename、uint32_t ui32Line) { #endif //********* // //用于将12位无符号值转换为 HID 报告中返回的八位有符号值的宏//。 这将映射 ADC 中 的值、//范围从0到2047到127到-128。 //// ***************** #define Convert8Bit (ui32Value)((INT8_t)((0x7ff - ui32Value)>> 4)) //************* // //如果主机发送设置或清除请求 ,则将此全局设置为 true //任何键盘 LED。 //// ***************** Volatile bool g_BDisplayUpdateRequired; //********* // //此枚举保存了键盘在 //正常操作期间可以处于的各种状态。 //// ***************** volatile enum { // //未配置。 // 未配置状态、 // //没有要发送的密钥,也没有等待数据。 // State_Idle、 // //等待要发送的数据。 // State_Sending } g_eKeyboardState = State_Unconfigured; //********* // //处理来自 HID 键盘驱动程序的异步事件。 // //\param pvCBData 是 // USBDHIDKeyboardInit()期间提供的事件回调指针。 这是指向我们的键盘设备结构 //(&g_sKeyboardDevice)的指针。 //\param ui32event 标识我们被回叫的事件。 //\param ui32MsgData 是特定于事件的值。 //\param pvMsgData 是特定于事件的指针。 // //此函数由 HID 键盘驱动程序调用,以通知应用 //与键盘 HID //设备操作相关的特定异步事件。 // //\return 在所有情况下返回0。 //// ***************** uint32_t KeyboardHandler (void *pvCBData、uint32_t ui32Event、uint32_t ui32MsgData、 void *pvMsgData) { switch (ui32event) { // //主机已连接到我们并配置了设备。 // 案例 USB_EVENT_Connected: { G_bConnected = true; G_bSuspened = false; 中断; } // //主机已与我们断开连接。 // 案例 USB_EVENT_DISCONNECTED: { G_bConnected = false; 中断; } // //每次主机确认传输时,我们都会收到此事件 //报告的内容。 这里使用它纯粹是一种确定是否存在的方法 //主机仍在与我们交谈。 // 案例 USB_EVENT_TX_COMPLETE: { // //自我们完成发送内容后输入空闲状态。 // G_eKeyboardState = State_Idle; 中断; } // //此事件表示主机已挂起 USB 总线。 // 案例 USB_EVENT_SUSPEND: { G_bSuspened = true; 中断; } // //此事件表示主机已在总线上恢复信令。 // 案例 USB_EVENT_RESUME: { G_bSuspened = false; 中断; } // //此事件表示主机已向我们发送输出或 //功能报告,报告现在位于我们提供的缓冲区中 //之前的 USBD_HID_EVENT_GET_REPORT_BUFFER 回调。 // 案例 USBD_HID_KEYB_EVENT_SET_LED: { // //将 LED 设置为与大写锁定 LED 的当前状态相匹配。 // ROM_GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_2、 (ui32MsgData 和 HID_KEYB_CAPS_LOCK)? GPIO_PIN_2: 0); 中断; } // //我们忽略所有其它事件。 // 默认值: { 中断; } } return (0); } //********* // //等待一段时间使状态变为空闲状态。 // //\param ui32TimeoutTick 是 //声明超时并返回\b false 之前等待的系统节拍数。 // //此函数轮询当前键盘状态的 ui32TimeoutTicks 系统 //等待系统变为空闲状态的节拍数。 如果状态变为空闲状态、 //函数返回 true。 如果在// 变为空闲状态之前发生 ui32TimeoutTicks,则返回 false 表示超时。 // //返回\n 成功时返回\b true,或\n 超时返回 false。 //// ********* bool WaitForSendIdle (uint_fast32_t ui32TimeoutTicks) { uint32_t ui32Start; uint32_t ui32Now; uint32_t ui32 Elapsed; ui32Start = g_ui32SysTickCount; ui32Elapsed = 0; while (ui32Elapsed < ui32TimeoutTicks) { // //键盘空闲,立即返回。 // if (g_eKeyboardState = State_Idle) { return (true); } // //确定自我们开始等待以来已经过去了多少时间。 这种情况 //在 g_ui32SysTickCount 的换行过程中应该是安全的。 // ui32Now = g_ui32SysTickCount; ui32Elapsed =((ui32Start < ui32Now)? (ui32Now - ui32Start): ((((uint32_t) 0xFFFFFFFF - ui32Start)+ ui32Now + 1)); } // //如果我们到达这里,我们将超时,因此返回错误的返回代码以允许 //呼叫者知道。 // return (false); } //********* // ////通过 USB HID 键盘接口发送字符串。 //// ***************** void SendString (char * pcStr) { uint32_t ui32char; // //在字符串中有更多字符时循环。 // while (* pcStr) { // //从字符串中获取下一个字符。 // ui32Char =* pcStr++; // //如果该字符是不可打印字符,则跳过该字符。 // if ((ui32Char <')||(ui32Char >"~")) { 继续; } // //将字符转换为索引并将其转换为键盘使用代码 //表。 // ui32Char -='; // //发送按键消息。 // G_eKeyboardState = State_Sending; if (USBDHIDKeyboardKeyStateChange ((void *)&g_sKeyboardDevice、 G_pipe8KeyUsageCodes[ui32Char][0]、 G_pipe8KeyUsageCodes[ui32Char][1]、 true)!= KEYB_SUCCESS) { 返回; } // //等待,直到按键消息已发送。 // if (!WaitForSendIdle (MAX_SEND_DELAY)) { G_bConnected = 0; 返回; } // //发送密钥释放消息。 // G_eKeyboardState = State_Sending; if (USBDHIDKeyboardKeyStateChange ((void *)&g_sKeyboardDevice、 0、g_ppi8KeyUsageCodes [ui32Char][1]、 false)!= KEYB_SUCCESS) { 返回; } // //等待密钥释放消息被发送。 // if (!WaitForSendIdle (MAX_SEND_DELAY)) { G_bConnected = 0; 返回; } } //********* // //这是 SysTick 中断的中断处理程序。 它用于 //更新我们的本地时钟计数,该计数进而用于检查传输 //超时。 //// ***************** void SysTickIntHandler (void) { G_ui32SysTickCount++; } //********* // //配置 UART 及其引脚。 这必须在 UARTprintf()之前调用。 //// ***************** void ConfigureUART (void) { // //启用 UART 使用的 GPIO 外设。 // ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); // //启用 UART0 // ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0); // //为 UART 模式配置 GPIO 引脚。 // ROM_GPIOPinConfigure (GPIO_PA0_U0RX); ROM_GPIOPinConfigure (GPIO_PA1_U0TX); ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); // //使用内部16MHz 振荡器作为 UART 时钟源。 // UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); // //初始化控制台 I/O 的 UART // UARTStdioConfig (0、115200、16000000); } //********* // //这是运行应用程序的主循环。 //// ***************** int main (void) { // uint8_t ui8ButtonChanged、ui8Buttons; // bool bUpdate; uint_fast32_t ui32LastTickCount; bool bLastSuspend; // tContext sContext; // //将时钟设置为以50MHz 的频率从 PLL 运行 // ROM_SysCtlClockSet (SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz); // //启用用于板载 LED 的 GPIO 端口。 // ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF); // //为蓝色 LED (PF2)启用 GPIO 引脚。 // ROM_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_2); // //打开 UART0并在 UART 上显示应用程序名称。 // ConfigureUART(); UARTprintf ("Tiva C 系列 USB KEYBD 器件示例\n"); UARTprintf ("-------------------------------- \n\n"); // //最初未配置。 // G_iKeybdState = eStateNotConfigured; // //启用用于 USB 的 GPIO 外设,并配置 USB //引脚。 // ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); SysCtlGPIOAHBEnable (SYSCTL_PERIPH_GPIOD); ROM_GPIOPinTypeUSBAnalog (GPIO_PORTD_AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5); // //为按钮配置 GPIO。 // ButtonInit(); // //告诉用户我们所达到的目标。 // UARTprintf ("配置 USB\n"); // //将 USB 堆栈模式设置为设备模式。 // USBStackModeSet (0、eUSBModeForceDevice、0); // //将设备信息传递到 USB 库并放置设备 //在总线上。 // USBDHIDKeyboardInit (0、&g_sKeyboardDevice); // //将初始报告归零。 // // sReport.ui8Buttons = 0; // sReport.i8XPos = 0; // sReport.i8YPos = 0; // sReport.i8ZPos = 0;// sReport.i8ZPos = 0; // //告诉用户我们在做什么并提供一些基本说明。 // UARTprintf ("\n 为主机执行 Waiting...\n"); // //主循环从此处开始。 我们首先等待主机连接 //然后放入主键盘处理部分。 如果是主机 //断开连接,我们返回顶部并等待新连接。 // while (1) { uint8_t ui8Buttons; uint8_t ui8ButtonChanged; // //告诉用户我们在做什么并提供一些基本说明。 ///* GrStringDrawCenter(&sContext,“Waiting”, -1、i32CenterX、22、1); GrStringDrawCenter(&sContext,“for host…… "、-1、 i32CenterX、32、1); * // //在这里等待,直到 USB 设备连接到主机。 // while (!g_BConnected) { } // //更新状态。 ///* GrStringDrawCenter(&sContext," 主机 "、 -1、i32CenterX、22、1); GrStringDrawCenter(&sContext,"已连接... "、 -1、i32CenterX、32、1); * // //输入空闲状态。 // G_eKeyboardState = State_Idle; // //假设总线当前没有被暂停,如果我们刚刚被暂停 //已配置。 // bLastSuspend = false; // //继续将字符从 UART 传输到 USB 主机,用于 AS //只要我们连接到主机。 // while (g_BConnected) { // //记住当前时间。 // ui32LastTickCount = g_ui32SysTickCount; // //自上次检查以来暂挂状态是否已更改? // if (bLastSuspend!= g_bSuspened) { // //是-状态已更改,因此更新显示。 // bLastSuspend = g_BSuspened; if (bLastSuspend) { // GrStringDrawCenter(&sContext," 总线 "、-1、 // i32CenterX、22、1); // GrStringDrawCenter(&sContext,"已暂停... "、-1、 // i32CenterX、32、1); } 其他 { // GrStringDrawCenter(&sContext," 主机 "、-1、 // i32CenterX、22、1); // GrStringDrawCenter(&sContext,"已连接... "、 // -1、i32CenterX、32、1); } } // //查看是否刚刚按下按钮。 // ui8Buttons = ButtonPoll (&ui8ButtonChanged、0); // if (button_pressed (up_button、ui8Buttons、ui8ButtonChanged)) if (button_pressed (0、ui8Buttons、ui8ButtonChanged)) { // //如果总线被暂停,则恢复它。 否则、键入 //一些“随机”字符。 // if (g_BSuspened)(如果(g_BSuspened)) { USBDHIDKeyboardRemoteWakeupRequest ( (void *)&g_sKeyboardDevice); } 其他 { SendString ("切换到 TI 微控制器!"); } } // //在轮询之前等待至少1个系统勾号消失 //再次按键。 // while (g_ui32SysTickCount = ui32LastTickCount) { } } /*// //主循环从此处开始。 我们首先等待主机连接 //然后进入 KEYBD 主处理部分。 如果是主机 //断开连接,我们返回顶部并等待新连接。 // while (1) { // //在这里等待,直到 USB 设备连接到主机。 // if (g_iKeybdState == eStateIdle) { // //默认情况下不更新。 // bUpdate = false; // //查看按钮是否更新。 // ButtonPoll (&ui8ButtonChanged、&ui8Buttons); // sReport.ui8Buttons=0; // //如果左按,设置按钮1。 // if (ui8Buttons & left_button) { // sReport.ui8Buttons|= 0x01; } // //如果按下右键,设置按钮2。 // if (ui8Buttons & right_button) { // sReport.ui8Buttons|= 0x02; } if (ui8ButtonChanged) { bUpdate = true; } // //如果有更新,请发送报告。 // if (bUpdate) { USBDHIDKeyboardSendReport (&G) sKeyboardDevice、sReport、 sizeof (sReport)); // //现在正在发送数据,但保护它不受中断的影响,因为 //它也可以在中断上下文中更改。 // IntMasterDisable(); G_iKeybdState = eStateSending; IntMasterEnable(); // //限制 LED 的闪烁速率。 // if (g_ui32Updates++== 40) { // //打开蓝色 LED。 // ROM_GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、GPIO_PIN_2); // //重置更新计数。 // G_ui32Updates = 0; } } }*/ }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    struct.c:

    //
    //
    //// usb_gamepad_structs.c -定义 USB gamepad 设备的数据结构。
    //
    //版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)提供此软件仅供
    和//仅供 TI 的微控制器产品使用。 软件归
    // TI 和/或其供应商所有,并受适用的版权
    //法律保护。 您不能将此软件与"病毒"开源
    //软件组合在一起以形成更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //对于
    
    本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
    //情况下、TI 不对任何
    原因造成的特殊、意外或必然//损害负责。
    //
    //这是 EK-TM4C123GXL 固件包版本2.1.4.178的一部分。
    ////
    *****************
    
    #include 
    #include 
    #include "inc/hw_types.h"
    #include "usblib/usbdevice.h"
    #include "usblib/usbhid.h"
    #include "usblib/usbdcomp.h"
    #include "usb/device/usbind.h"
    
    #include "usb/usbid.h"#include "usb/sub/usbind.h"
    
    
    
    
    //
    //此设备支持的语言。
    ////
    *************
    const uint8_t g_pui8LangDescriptor[]=
    {
    4、
    USB_DTYPE_string、
    USBShort (USB_LANG_EN_US)
    };
    
    //*********
    //
    //制造商字符串。
    ////
    *************
    const uint8_t g_pui8ManufacturerString[]=
    {
    (17 + 1)* 2、
    USB_DTYPE_string、
    "T"、0、"e"、0、"x"、 0、"A"、0、"S"、0、 '、0、'i'、0、'n'、 0、"S"、0、
    "T"、0、"r"、0、"u"、 0、'm'、0、'e'、0、 "n"、0、"t"、0、"S"、 0、
    };
    
    //*********
    //
    //产品字符串。
    ////
    *************
    const uint8_t g_pui8ProductString[]=
    {
    (18 + 1)* 2、
    USB_DTYPE_string、
    'K'、0、'E'、0、'0'、 0、"F"、0、"F"、0、 '、0、'C'、0、'W'、 0、'、0、
    'K'、0、'e'、0、'y'、 0、"b"、0、"o"、0、 'a'、0、'r'、0、'd'、 0、'、0、
    };
    
    //************
    //
    //序列号字符串。
    // YYYYWWnnn
    //
    //*********
    const uint8_t g_pui8SerialNumberString[]=
    {
    (9 + 1)* 2、
    USB_DTYPE_string、
    "2"、0、"0"、0、"1"、 0、"9"、0、"2"、0、 "0"、0、"0"、0、"0"、 0、'1'、0
    };
    
    //*********
    //
    //接口描述字符串。
    ////
    *****************
    const uint8_t g_pui8HIDInterfaceString[]=
    {
    (21 + 1)* 2、
    USB_DTYPE_string、
    'H'、0、'I'、0、'D'、 0、'、0、'K'、0、 'e'、0、'y'、0、'b'、 0、
    'O'、0、'A'、0、'r'、 0、'd'、0、'i'、0、 'n'、0、't'、0、'e'、 0、
    'R'、0、'f'、0、'A'、 0、'c'、0、'e'、0
    };
    
    //
    //
    //配置描述字符串。
    ////
    *****************
    const uint8_t g_pui8ConfigString[]=
    {
    (25 + 1)* 2、
    USB_DTYPE_string、
    'H'、0、'I'、0、'D'、 0、'、0、'K'、0、 'e'、0、'y'、0、'b'、 0、
    'O'、0、'A'、0、'r'、 0、'd'、0、'C'、0、 'O'、0、'n'、0、'f'、 0、
    'i'、0、'g'、0、'u'、 0、'r'、0、'A'、0、 "T"、0、"I"、0、"o"、 0、
    'N'、0
    };
    
    //*********
    //
    //描述符字符串表。
    ////
    *****************
    const uint8_t * const g_ppui8StringDescriptors []=
    {
    G_pui8 LangDescriptor、
    G_pui8ManufacturerString、
    G_pui8ProductString、
    G_pui8SerialNumberString、
    G_pui8HIDInterfaceString、
    G_pui8ConfigString
    };
    
    #define NUM_STRING_descriptors (sizeof (g_ppui8StringDescriptors)/ \
    sizeof (uint8_t *)
    
    )//*********
    //
    // HID 键盘设备初始化和自定义结构。
    ////
    *****************
    tUSBDHIDKeyboardDevice g_sKeyboardDevice =
    {
    USB_VID_TI_1CBE、
    USB_PID_Keyboard、
    0、
    USB_CONF_ATTR_SELF、
    KeyboardHandler、
    (void *)&g_sKeyboardDevice、
    G_ppui8字符串描述符、
    num_string_descriptors、
    0、
    0}
    ;
    

    struct.h:

    //
    //
    // usb_gamepad_structs.h -定义游戏 epad USB 设备的数据结构。
    //
    //版权所有(c) 2013-2017 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)提供此软件仅供
    和//仅供 TI 的微控制器产品使用。 软件归
    // TI 和/或其供应商所有,并受适用的版权
    //法律保护。 您不能将此软件与"病毒"开源
    //软件组合在一起以形成更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //对于
    
    本软件,不作任何明示、暗示或法定的保证,包括但不限于对适销性和适用性的暗示保证//特定用途。 在任何
    //情况下、TI 不对任何
    原因造成的特殊、意外或必然//损害负责。
    //
    //这是 EK-TM4C123GXL 固件包版本2.1.4.178的一部分。
    ////
    *****************
    
    #ifndef _USB_Gamepad_structs_H_
    #define _USB_Gamepad_structs_H_
    
    extern uint32_t KeyboardHandler (void * pvCBData、uint32_t ui32Event、
    uint32_t ui32MsgData、void *pvMsgData);
    
    extern tUSBDHIDKeyboardDevice g_sKeyboardDevice;
    
    #endif
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Joseph、

    为什么要将 USB 引脚放在高级主机总线上? 我找不到任何用于 USB 引脚的 AHB 的情况。  编辑:显然、TivaWare 有一个示例工程可执行此操作、因此我会得到更正、但我仍然坚持以下立场:

    我将删除使用 AHB 的尝试、并使用 Bob 所述但具有正确引脚的标准调用、然后查看故障 ISR 是否消失。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Joseph Haas88"]所以、"123G"和"123GXl"是指 TivaWare 示例文件夹(TivaWare_C_Series-2.1.4.178)下"器件"中的文件夹。

    在 TivaWare 版本2.1.4.178的标准安装中、TivaWare 示例文件夹下没有"devices"文件夹。 也许此文件夹是在安装完成后由某人添加的。  

    [引用用户="Joseph Haas88">代码片段(由 Bob Crosby 提供)来自 TM4C123GH6PGE 示例、不适用于 TM4C123GH6PM 、因为 USB0模块位于不同的端口块上(对于 TM4C123GH6PM 为 D 、对于 GH6PGE 为 G)。  [/报价]

    是的、您回答正确。 (抱歉)。 在 TM4C123GH6PM 上配置 USB 引脚的代码为:

    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
    SysCtlGPIOAHBEnable (SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeUSBAnalog (GPIO_PORTD_AHB_BASE、GPIO_PIN_4 | GPIO_PIN_5);
    

    我怀疑您已经从 USB_dev_gamepad.c 文件中获得了该文件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Bob:

    我不确定该示例为什么使用 AHB、我从未在任何其他示例中使用过 AHB 作为 USB。 我认为它应该起作用、因为该示例使用它、但由于 AHB 模式如何影响整个端口、我倾向于尽可能避免这些调用。 我建议将其用于引脚初始化、而这是在所有其他示例中完成的操作:

    //
    //启用用于 USB 的 GPIO 外设,并配置 USB
    //引脚。
    //
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD);
    ROM_GPIOPinTypeUSBAnalog (GPIO_PORTD_BASE、GPIO_PIN_4 | GPIO_PIN_5); 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    两个 init 版本的行为相同。 如果有任何问题、我无法使用"非 AHB"版本使代码"运行"。 仍然需要弄清楚为什么 FaultISR 被跳闸。 由于它在单步执行代码时不进行表示、因此很难隔离。 在过去、我已经追溯了 ISR 陷阱以找到犯罪者、但当您在十年内只执行一次或两次时、这真的很痛苦...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Joseph、

    我采用了您发布的代码、将其放入新项目中、编译后加载到 EK-TM4C123GXL LaunchPad 中。 我还没有使它达到 FaultISR。 您是否知道要执行什么操作来触发故障 ISR?

    您是否尝试过清理项目并重新构建项目?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    啊,是的,清洁。 刚刚尝试过。 没有乐趣。 我甚至禁用了所有按钮代码调用、以确保没有任何按钮代码调用。 我需要检测 FAULTISR 以引入故障寄存器、以便查看它们是否将我指向正确的方向。 今晚稍后再试一下。 现在,我必须与交通作战!!!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Joseph、

    由于我没有看到任何故障 ISR、我怀疑您项目中的某些内容会被您在项目上所做的所有工作所蒙混。 我强烈建议您从 TivaWare 导入 Project 0、添加您的文件、然后从此处重新构建。 您需要重新链接 Button 文件和 usblib、但这应该很简单、如果您需要一个有关链接 buttons.c/.h 文件等文件的快速指南、我可以为此共享一个帖子。 添加 usblib 就像在 CCS 工程属性中为当前 USB 工程复制 include -> ARM 链接器->文件搜索路径一样简单、并将该行添加到新工程中。

    看看它是否起作用、如果不起作用、您应该能够轻松地压缩该项目并将其发送给我、以便我可以在我的末尾重试以重新创建 FaultISR。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    只是为了澄清、我没有其他文件、只是示例尝试引入的文件。 我只是尝试将键盘示例移植到 GH6PM (然后、我将放入我的文件)。 我不得不调整按钮的库代码、这就是为什么我对它们进行了拼写(我认为原始链接路径使用端口 G、此处理器上不可用)。 因此、我错过了指向不存在端口的端口引用、或者缺少依赖项。 所有理论和推测。 我将查看是否可以找到 FaultISR 跳闸的来源...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Ralph、您是否尝试连接到 USB0系统? 我发现、如果 USB0连接断开、我的项目将引导至等待循环。 一旦我将 USB0插入我的 PC、FAULTISR 就会出现八倍数据速率。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、烦人的错误#N...

    我能够使用堆栈对 ISR 进行反向跟踪、该堆栈将我带到 KeyboardHandler。  分解视图只是数量组、但它让我看看我之前错过的位置。

    AN01286 (也称为 spma043.pdf)是用于跟踪 ISR 故障的非常好的参考。  这并不像我上次记忆中的那样痛苦(可能是因为我不知道 AN01286直到完全拉入头发)。

    案例 USBD_HID_KEYB_EVENT_SET_LED:
    {
    //
    //将 LED 设置为与大写锁定 LED 的当前状态相匹配。
    //
    ROM_GPIOPinWrite (GPIO_PORTG_base、GPIO_PIN_2、
    (ui32MsgData 和 HID_KEYB_CAPS_LOCK)? GPIO_PIN_2:
    0);
    
    中断;
    }
    

    我错过 了 KeyboardHandler 内部的 GPIO 参考。  我将端口更改为 F、现在我可以在 PC 上注册、并且没有故障 ISR。

    现在、我可以在 PC 上枚举。  按钮无法正常工作。  可能是由于 portF 的特殊性质(您必须解锁它才能更改其配置。  我敢打赌、示例代码不会进行陷印)。

    我对"SendString("a1")发出了一个延时的调用;现在我得到了一组"a1"字符序列流式传输到我的源文件中。  这是非常好的!!!

    我不能说我有信心去做、但我肯定会去下一个难题。

    感谢所有回复!

    我想我对描述符数据很好奇。  在 PC 的设备管理器中、我可以从何处查找序列号和制造商等内容(我在随附的字文档中有一个屏幕截图"是否粘贴图像????")?  此信息是否在 PC 的 USB 堆栈中发送得太远?  我看不到任何区别数据、但需要查看的单个项目太多。

    其中一个是我的 Tiva 键盘(在拔下 launchpad 时、只有3个 HID 键盘设备条目):

    't="" paste,="" drat! ="" too="" bad,="" it="" was="" a="" work="" of="" art!="">

    标准 PS/2键盘始终存在,因此不太可能出现。 当您选择和查看详细信息时、其他选项看起来都是相同的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Joseph、

    很高兴您能够找出根本原因。 我已经插入 USB0、但也没有命中故障 ISR、但我也没有使用键盘来解决问题、因此我可能没有触发该 LED。 现在有很多道理。

    很高兴故障文档对您有所帮助!

    并非所有端口 F 都需要解锁、请查看我们的常见问题解答帖子的第一个条目: e2e.ti.com/.../755561

    关于描述符、器件驱动程序属性的第一页中通常会列出制造商。 我认为可以在属性的事件日志中看到序列号。 请注意、根据设备枚举的方式、您可能会看到 Microsoft 作为制造商。 我不知道为什么我们的驱动程序以这样的方式进行签名、但这就是它们的原因(我个人没有做过任何与窗口驱动程序兼容的工作)。