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.

[参考译文] CCS/EK-TM4C123GXL:通过 UART4读取 GPS 数据、通过 UART0发送到 PC

Guru**** 2463330 points
Other Parts Discussed in Thread: EK-TM4C123GXL, MAX3232

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/657641/ccs-ek-tm4c123gxl-reading-gps-data-by-uart4-and-sending-to-pc-by-uart0

器件型号:EK-TM4C123GXL
主题中讨论的其他器件: MAX3232

工具/软件:Code Composer Studio

大家好

我正在尝试将 U-blox Neo6M GPS 传感器连接到 EK-TM4C123GXL launchpad。 我的连接如下;

GPS Tx -> TM4C PC4

TM4C Debug USB -> PC

我正在尝试从 UART 4 (PC4-PC5)读取 GPS 数据、甚至无需触摸它、通过 UART0和 USB 电缆直接传递到 PC。 为了安全起见、我将源代码基于 UART_echo 示例。 并尝试执行为 UART4的 UART0执行的所有操作(复制函数调用、参数更改为 UART4相关参数)。

我的源代码如下

#include 
#include 
include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"

#include "driverlib_integree"#def_ude.idt_idt_intru.idt_idt_u.idt_inu.idt.idt_u.idt_u.idt.h #include #include "#idt.inc"#def_inu.idt.idt.idt_inu.idt_inu.idt.idt.idt.idt_u.idt.idt.id












uint32_t ui32Status0;
uint32_t ui32Status1;

ui32Status0 = ROM_UARTIntStatus (UART0_BASE、TRUE);
ROM_UARTIntClear (UART0_BASE、ui32Status0);

ui32Status1 = ROM_UARTIntStatus (UART4_base、true);
ROM_UARTIntClear (UART4_base、ui32Status1);

while (ROM_UARTCharsAvail (UART4_base))
{
ROM_UARTCharPutNonBlocking (UART0_BASE、ROM_UARTCharGetNonBlocking (UART4_base));
}
}

空 UARTSend (const uint8_t * pui8Buffer、uint32_t ui32Count)
{
while (ui32Count---)
{
ROM_UARTCharPutNonBlocking (UART0_BASE、* pui8Buffer++);
}
}

int
main (void)
{
ROM_FPUEnable();
ROM_FPULazyStackingEnable();

ROM_SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHz);

ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
ROM_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_2);

ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART4);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);

ROM_IntMasterEnable();

GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

GPIOPinConfigure (GPIO_PC4_U4RX);
GPIOPinConfigure (GPIO_PC5_U4TX);
ROM_GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_4 | GPIO_PIN_5);

ROM_UARTConfigSetExpClk (UART0_BASE、ROM_SysCtlClockGet ()、115200、
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
ROM_UARTConfigSetExpClk (UART4_base、ROM_SysCtlClockGet ()、9600、
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));


ROM_IntEnable (INT_UART0);
ROM_UARTIntEnable (UART0_BASE、UART_INT_RX | UART_INT_RT);

ROM_IntEnable (INT_UART4);
ROM_UARTIntEnable (UART4_base、UART_INT_RX | UART_INT_RT);

UARTSend ((uint8_t *)"\033[2JEnter 文本:"、16);

while (1)
{
}
}

当我调试代码时、暂停一段时间后、代码在 FaultISR 函数的无限循环处停止。

我可能犯了一些根本错误、因为所有 UART 可能不完全相同、可能我需要另一个电路、如 MAX3232。 您能帮我解决这个问题吗?
注意:我可以在 TM4C 上测试 UART_ECHO 示例二进制文件、以便至少 UART0正常工作。

 GPS 数据表为  :www.u-blox.com/.../NEO-6_DataSheet_(GPS.G6-HW-09005).pdf

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    FaultISR 通常意味着已经发生了一个中断条件、但是没有与它相关的 ISR。

    您的项目中有一个单独的文件、我们将其称为"启动"文件。 有一条消息告诉编译器、当某个外设触发中断时、将调用哪个函数。 很明显、当 UART4接收到一个字节时、没有可调用的已定义函数、代码执行会转到默认 ISR。

    MAS3232与将 UART 电平从 TTL 转换为 RS232有关。 您的近地天体模块已以 TM4C 预期的水平发送信号、因此可以直接连接它们。 从 MCU 到 PC (PC 是需要 RS232级别的人)、我知道您正在使用 launchpad 仿真的 USB "虚拟"串行端口、对吧? 在这种情况下、同样不需要转换。

    现在、我看到您为两个 UART (0和4)配置了中断、但您的描述显示您只想将 UBlox => MCU 转发到 PC、对吧? 在这种情况下、您不应为到达端口0的字节配置中断。

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

    您好!

    为了补充 Bruno 的出色建议、并与他关于配置两个 UART 的观点一起、似乎没有调用来启用 UART0外设:

    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART4);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC); 

    我看到上述调用、但 SYSCTL_PERIPH_UART0没有。 如果您将 UART0用于 GPS 以外的其他设备、则一定要包含该信息;如果 UART0未真正投入使用、则应删除与 UART0相关的所有行。

    供参考:启动文件 Bruno 所指的是 startup_ccs.c 文件。

    此外、对于 FaultISR 问题、如果上述建议无法解决、我还建议阅读: http://www.ti.com/lit/an/spma043/spma043.pdf

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

    我也想承认 Bruno 的调查结果的价值-但主要问题似乎是没有、 "UART0 正在启用"。

    然而-用户代码的其他元素是否需要审查?   具体内容: (请参阅亮点)

    无效

    UARTIntHandler (空)

      uint32_t ui32Status0;

      uint32_t ui32Status1;

      ui32Status0 = ROM_UARTIntStatus (UART0_BASE、TRUE);

      ROM_UARTIntClear (UART0_BASE、ui32Status0);

      ui32Status1 = ROM_UARTIntStatus (UART4_base、true);

      ROM_UARTIntClear (UART4_base、ui32Status1);

      while (ROM_UARTCharsAvail (UART4_base))

      {

        ROM_UARTCharPutNonBlocking (UART0_BASE、ROM_UARTCharGetNonBlocking (UART4_base));

      }

    这两 个"ROM_UARTIntClear () s" (两者均已实现(且始终都已执行)、是否具有单个 UART 中断(但  仅由一 个 UART 生成 )、可能会"导致故障?"   (或者措辞为-是否可以  发布一个"不需要的"ROM_UARTIntClear ()-而不会造成伤害?      检测到 MCU "错误"时经过 MCU。)

    您的内部信息肯定会证明在这些细节方面有所帮助。   海报(明显)使用单个中断-为两个 UART 提供服务-寄存器(也是)异常-我不愿意"将其作为一种一般方法"-因为   "仅是这里确定的缺陷"(可能)..."

    感谢您的时间和关注...

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

    我怀疑他将一个 ISR 用于两个外设实际上是对中断工作方式的复制/粘贴误解... 两个源、单个中断例程、需要非常小心、而不仅仅是"部分"!

    在这里、我通常不做的一件事是尝试在 OP 代码中找到 Waldo:我只是一般性的怀疑、尝试提出相关问题、或者在时间允许时、尝试创建一个更通用的"基本操作方法"指南。

    因此、"一般警告"-当 Bruno 回复时、他可能没有深入了解您的代码的每一行... 这就是您的工作、海报... )

    特别是、我注意到 OP 的描述、即他"一段时间后"获得 FaultISR。 这是一个危险的描述、可能会暗示"一段时间前"一切正常... 新生在调试早期阶段代码时、关闭所有优化、并逐步运行代码、直至出现故障! 这至少将向您展示您毫无差错地取得了多大的进展!

    谢谢

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

    您好 Bruno、

    这里也有其他人-可能(通常)试图提供"通用解决方案方法"(甚至有时)、范围超出"仅 MCU "限制(通常在此处显示)-并且大多数以 MCU 为中心的论坛也是@。

    至于"某些"-"某些"(可能)建议"很少"(正如您所暗示的)、但实际上-证明范围更广-并且由于其(故意)缺乏具体性而经常被"合法"使用...   另请注意-在我的"Tag's context (标签的背景)"中、使用"非常小心"不会有、"也提供..."

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 USER="Bruno Saraiva"]我知道您正在使用 Launchpad 仿真的 USB“虚拟”串行端口,对吗?
    正确。
    [引用 user="Bruno Saraiva"]很显然,当您的 UART4收到一个字节时,没有可调用的已定义函数,代码执行将转到默认 ISR。
    在已发布的源代码中有一种回调方法、我在其中检查 uart4中的字符。 我认为该函数是所有 UART 通道的常规回调。 我在手机上、什么都检查不出来、但是我觉得需要在启动文件中为 uart4中断定义另一个函数。  
    [引用 user="Bruno Saraiva"]在这种情况下,不应为到达端口0的字节配置中断。
    对。 在匆忙的尝试中、我没有足够的时间自定义源代码。 我将更详细地介绍一下这个版本、并将其编为更简洁的版本。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、我的帖子和源代码不一致。 我将重点介绍如何从 UART4部件读取 GPS 数据(该部分源代码具有用于此目的的断点)。 我将接受在这里发布的所有建议、并尝试更精简和更一致的代码。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在我尝试快速读取 GPS TM4C 的 UART 时、我在论坛上的帖子也是如此。 我将尝试尽快提供更好的源代码和更好的调试结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢大家提出宝贵的建议。 现在、我可以将 GPS 数据读取到 TM4C 并从 TM4C 将其发送到 PC。 我重新排列了源代码并删除了不必要的器件(imho)。

    #include 
    #include 
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"#include
    "driverlib_dive.h"
    #def_udio.ide"#include"#drie.t_idio.ide"#include "driver32_intru.ide"#include "driverlib_inu.idio.ide"#include
    "u.ide"#include "u.idio.ide"#include "u.ide"
    
    
    
    
    
    {
    }
    #endif
    
    // UART4上中断的处理程序函数
    //配置在 startup_ccs.c 文件中完成
    // startup_ccs.c 中的矢量表定义 AS
    /*...*/*
    UART4IntHandler, // UART4 Rx 和 Tx */*...*/
    
    void
    UART4IntHandler (void)
    {
    //清除 UART4上的中断
    uint32_t ui32Status;
    ui32Status = ROM_UARTIntStatus (UART4_base、true);
    ROM_UARTIntClear (UART4_base、ui32Status);
    
    //在读取开始时打开 LED
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、GPIO_PIN_2);
    while (ROM_UARTCharsAvail (UART4_base))
    {
    //将 GPS 数据(从 UART4读取)写入 UART0
    ROM_UARTCharPutNonBlocking (UART0_BASE、ROM_UARTCharGetNonBlocking (UART4_base));
    }
    
    //在读取结束时关闭 LED
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、0);
    }
    
    int
    main (void)
    {
    //为中断处理程序启用怠惰堆栈。
    ROM_FPUEnable();
    ROM_FPULazyStackingEnable();
    
    //将时钟设置为直接从晶体运行。
    ROM_SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHz);
    
    //启用使用的外设:
    //端口 C 引脚将用作 UART4
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART4);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOC);
    //端口 F 将用于板载 LED
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
    //端口 A 引脚将用作 UART0 (虚拟串行连接调试)
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    
    //启用处理器中断。
    ROM_IntMasterEnable();
    
    //将 PC4设置为 UART4 RX
    GPIOPinConfigure (GPIO_PC4_U4RX);
    ROM_GPIOPinTypeUART (GPIO_PORTC_BASE、GPIO_PIN_4);
    
    //将 GPIO A1设置为 UART0 Tx (发送)
    GPIOPinConfigure (GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_1);
    
    //将 UART0配置为115、200、8-N-1操作。
    //这是 TM4C 和 PC 之间的串行连接
    ROM_UARTConfigSetExpClk (UART0_BASE、ROM_SysCtlClockGet ()、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    
    //将 UART0配置为115、200、8-N-1操作。
    //这是 TM4C 和 PC 之间的串行连接
    ROM_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、GPIO_PIN_2);
    
    //将 UART 配置为9600、8-N-1操作。 GPS 模块提供9600 bps 的数据
    //这是 GPS 模块(U-blox NEO6M)之间的连接
    ROM_UARTConfigSetExpClk (UART4_base、ROM_SysCtlClockGet ()、9600、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    
    //启用 UART4中断。 因此不需要其他中断
    //我们不希望 PC 中有任何内容,它用于显示 GPS 数据
    ROM_IntEnable (INT_UART4);
    ROM_UARTIntEnable (UART4_base、UART_INT_RX | UART_INT_RT);
    
    while (1)
    {
    }
    }
    

    我还将 STARTUP_CCS 中 UART4的默认中断处理程序更改为 UART4Handler 函数。 但我不会仅为一行更改而包含该文件。 建立 GPS 接地和 Vcc 连接后、将 GPS Tx 引脚连接到 TM4C123GXL PC4引脚。 然后通过调试端口(UART0)将 TM4C 连接到 PC。 加载软件并在 Putty 或类似软件中观察值。

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

    请务必注意、"海报成功"-尤其是您的详细代码列表-一定会对许多人有所帮助。

    所有帮助者都"错过"了外部器件(此处为 GPS)与 MCU 之间"确保存在公共 GND "的必要性。
    长期-根据 GPS 的电流要求-您可能会受益于更高的输出电源...

    更长期的-您可以考虑"使用串行驱动的小型/便携式显示器"-使您摆脱任何"PC 系带"。   (也可以使用更多标准的"并行 LCD"、但需要更多 MCU 引脚和更改的程序代码...)

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

    [引用 user="Bruno Saraiva"]研究员在调试早期阶段代码时,关闭所有优化,并逐步运行代码,直到出现故障!

    不,我建议不要这样做。 它将隐藏您真正需要查看和跟踪的故障。 这样做会错误地导致您相信您发现了编译器错误。

    Robert

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

    Robert、

    我对这个不赞同。

    调试是一种为所有级别的开发人员和任务提供服务器的工具。 当您使用分步调试器时、优化大部分时间会更改执行序列并"隐藏您的逻辑线"。

    例如、假设"全新"编程器必须转置8个字节。 要转换包含的8 uint8_t 数组

    00001111
    00001111
    00111111
    111111
    111111
    00111111
    00001111
    00001111

    对于每个字节包含原始变量第 n 位的数组:

    00011000
    00011000
    00111100
    00111100
    111111
    111111
    111111
    111111

    一个很可能使用具有两个嵌套循环的函数。 在我早期的时候、这曾经是一项典型的练习、它将从调试中受益匪浅。 查看变量的分步值等非常有趣和有用。

    如果您编译此类优化的数据、"自然预期流"将完全消失。 不可能正确使用调试器。 因此、如果程序员弄乱了一些东西(可能从索引1开始、而不是从0开始、或者将计数器限制为8而不是7、这些典型的 C 陷阱)、他根本不知道发生了什么。

    如果我找到了一段代码作为概念验证、我会记得回到这里。 但这不是"竞争",也不是一种试探,只是交流经验。 我坚持我的建议:关闭优化并使用调试器测试小函数非常有用。 对结果感到满意后、最好再次运行代码以实现所需的优化、并检查意外错误、然后需要通过一些"进一步体验"来解决这些错误。

    这尤其适用于 OP 级别、他们仍然不愿意立即了解一个计划中的不同 UART。

    此致

    布鲁诺

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

    有关您的任务和帖子的更多评论:

    - UBlox GNSS 模块能够导出 NMEA 信息和优先级二进制信息。 虽然第二个是"更复杂"或不太常用、但它更高效:您可能需要的信息可以全部打包在一条消息中、它在传输时使用的字节较少、并且需要较少的解析。 如果您在该模式下使用模块、这会很有趣。

    无论采用哪种方法,我都很确定您的下一个目标是解释所收到的值。 您将构造(或尝试在 Web 上查找) NMEA 解析器。 我的提示是、您开发它"完全独立于您的主应用程序"。 目标是一个外部函数、您只能向其传递一个带有接收到的 GNSS 消息第一个字节地址的指针、以及一个指向您希望存储您的 vales 的内部结构的指针。 请勿陷入将 GNSS 库混合到主应用程序的陷阱。

    关于帖子本身,让我指出,意味着“这解决了我的问题”的绿色按钮应该在解决您的问题的消息上点击。 你在这种情况下会指向其他地方。

    此致

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

    [引用 user="Bruno Saraiva"]但这不是"竞争",而不是试用

    因此, "法官、 陪审团、 审判律师、 不舒服的法官座席"都"在场"。 什么都不意味着!    巴西的学校系统没有教过: "如果它行走、看起来和像鸭子一样的小袋-那么这是一只鸭子!"   或试用版-在本例中...

    您知道、 "只有特定的"优化"-导致您呈现的条件-您不是?   放弃所有优化优势可能会证明"难以证明!"

    我们被警告— —“罗伯特法官”是“悬吊法官!”   (最好站在他的好一边...)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗨,Bruno,这个帐户是多年前创建的,我不知道我的名字为什么是 user-bigNumber :)。
    我对你的评论的回答;
    -是的,我所需的数据实际上比我的 GPS 模块默认发送的数据少得多。 我将查看数据表或任何其他资源、以将器件配置为尽可能少地发送数据。 现在、大家都可以看到、我直接将大量数据传递到另一个串行端口、而不进行解释。 事实上、由于传输成本占了很高的百分比或资源使用量、因此这种方法成本高昂。
    -执行第一步后、我还将尝试编写一个独立的小型 NMEA 解析器库、因为大多数开放源码解析器都是针对所有可能的 C 应用程序编写的。 但是、由于我会将传感器数据减少到我所需的数据、因此手工制作的图书馆将非常有用。