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.

[参考译文] EK-TM4C123GXL:UARTprintf 产生无输出

Guru**** 1791880 points
Other Parts Discussed in Thread: EK-TM4C123GXL
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/570629/ek-tm4c123gxl-uartprintf-produces-no-output

器件型号:EK-TM4C123GXL

我不熟悉对 LaunchPad 进行编程、一直在尝试弄清楚如何将数据/字符串输出到我的计算机控制台。  我主要在 Linux 中使用 minicom、但我也尝试在 Windows 10中使用 PuTTY。 都不会产生任何输出。  我已经通读了 utils/uartstdio.c 和 utils/uartstdio.h 源代码、根本不能弄清楚我缺少的内容。  如果有任何帮助,我们将不胜感激。

仅供参考、我确实确保 minicom 和 PuTTY 配置为115200bps。


以下是我的代码:

#include 
#include 
#include "stdlib.h"
#include 

#include "inc/hw_types.h"
#include "void/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_uart.h"

#include "driverlib/gpio.h"



#define "driverlib_rom_define #include "#define gpio/driverlib"








(#define #define #define #define gpio.mdio/gpin #define #define #include "#define #define #define #define #define #define #define #include "in_gpin/gpio.in/gpin #define #define #define #define #define #define #include "in_unicls"


(#define #define #define #define #define #define #include "in_

ROM_SysCtlClockSet (SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOF);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

ROM_GPIOPinTypeGPIOOutput (GPIO_PORTF_BASE、LED_RELED_LED_BLE|LED_GREEN);
ROM_GPIOPinTypeGPIOInput (GPIO_Porta_base、GPIO_PIN_5);

// UARTprintf 的设置
ROM_UARTClockSourceSet (UART0_BASE、UART_CLOCK _PIOSC);
ROM_GPIOPinConfigure (GPIO_PA0_U0RX);
ROM_GPIOPinConfigure (GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART (GPIO_PORTB_BASE、GPIO_PIN_0|GPIO_PIN_1);
UARTStdioConfig (0、115200、MAP_SysCtlClockGet ());


UARTprintf ("data init");
initialize();
对于(;)
{

int32_t btn = ROM_GPIOPinRead (GPIO_Porta_base、GPIO_PIN_5);

UARTprintf ("btn %ld、btn);

if (btn!= 0)
{
cycle_lights();
}
}



void initialize()
{
ROM_GPIOPinWrite (GPIO_PORTF_BASE、LED_RED_LED_GREEN|LED_BLUE、LED_GREEN);
}

void cycle_lights ()
{
ROM_SysCtlDelay (50000000);
ROM_GPIOPinWrite (GPIO_PORTF_BASE、LED_RED、LED_RED);
ROM_SysCtlDelay (50000000);
ROM_GPIOPinWrite (GPIO_PORTF_BASE、LED_RED_LED_GREEN|LED_BLUE、LED_RED);
ROM_SysCtlDelay (100000000);
ROM_GPIOPinWrite (GPIO_PORTF_BASE、LED_RED_LED_GREEN|LED_BLUE、LED_GREEN);
}

编辑: 尝试对某些内容重新排序并使其更具可读性...

编辑:
-根据 Amit 的建议、将 UARTStdioConfig (0、115200、MAP_SysCtlClockGet ());"改回"UARTStdioConfig (0、115200、16000000);"。

-尝试通过 Makefile (而不是在 main.c 中)包含"utils/uartstdio.c"(请参阅下面的 Makefile)。

以下是我的 Makefile 文件、如果它有助于诊断:

#/tiva-template/Makefile 添加了源代码 uartstdio.c
# target:输出文件目标的名称
= main
# MCU:为
MCU 构建的器件型号= TM4C123GH6PM
# SOURCES:输入源源列表
sources = main.c startup_gcc.c uartstdio.c
#包括: include 列表、默认情况下、use includes 目录
includes =-IIncludde
# OUTDIR:用于输出
OUTDIR 的目录= Build
# TIVAWARE_PATH:tivaware 文件夹的路径
TIVAWARE_PATH =$(HOME)/Embedded/tivaware

# LD_script: 链接器脚本
LD_script =$(MCU).ld

# define flags
CFLAGS =-g -mthumb -mcpu=cortex-M4 -mfpv4-sp-D16 -mfloat-abi=softfp
CFLAGS +=-OS -ffund-SECTIONS -fdata-SECTIONS -md -isr=c99#-mcu#-t##-t##-t##-rgv1#
–t##-t#-t###-rgv1#–t###-t&t##-t#-rgv###-t##-t&t##-rgc###-t###-t##-t&t##-t&t#-t&t#-t##-t##-rand&t#-t#-t#-t#-t##-t##-t##-t#




#用户配置结束
########################
####################
##########
# BINARIES
##########################
CC = ARM-NONE - eabi-gcc
LD = ARM-NONE - eabi-ld
objcopy = ARM-NONE - eabi-objcopy
rm = rm -f
MKDIR = mkdir -p
########################

#无论源路径
对象是什么、都放置在构建目录中的目标文件列表=$(addprefix $(OUTDIR)/、$(notdir $(sources:.c=.o))

)#默认值:构建 bin
All:$(OUTDIR)/$(target).bin

$(OUTDIR)/%.o:src/%.c |$(OUTDIR)
$(CC)-o $@$^$(CFLAGS)

$(OUTDIR)/a.out:$(objects)
$(LD)-o $@$^$(LDFLAGS)

$(OUTDIR)/main.bin:$(OUTDIR)/a.out
$(objcopy)-O 二进制文件<<$@

#创建输出目录
$(OUTDIR):
$(MKDIR)$(OUTDIR)

Clean:
-$(RM)$(OUTDIR)/*

.s仿冒:全部干净

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

    [引用用户="Matt McKenna"]

       ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);
       ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);


       ROM_UARTClockSourceSet (UART0_BASE、UART_CLOCK _PIOSC);
       ROM_GPIOPinConfigure (GPIO_PA0_U0RX);
       ROM_GPIOPinConfigure (GPIO_PA1_U0TX);
       ROM_GPIOPinTypeUART (GPIO_PORTB_BASE、GPIO_PIN_0|GPIO_PIN_1);

    [/引用]我认为、GPIO PORTB 的引用应改为用于 GPIO Porta、供 UART0使用。 例如、尝试:

    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    
    
    ROM_UARTClockSourceSet (UART0_BASE、UART_CLOCK _PIOSC);
    ROM_GPIOPinConfigure (GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure (GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0|GPIO_PIN_1); 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已经有几行"ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA)"。
    我尝试将"GPIO_PORTB_BASE"替换为"GPIO_PORta_base"、但结果没有变化。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您的代码:

    #include "utils/uartstdio.c" 

    别那样做。 只包含头文件。 将 uartstdio.c 文件作为本地副本或符号链接添加到项目中。  

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

    您是否尝试使用示波器检查信号(TM4C 侧的 TX、PC 侧的 RX)? 这将有助于找出问题-初始化错误、波特率问题、电平/信号问题等

    BTW、我同意 Petrei 的说法。 包括*。c 文件被视为错误的样式-例如在头文件中放置代码。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matt、
    我建议您不要使用 UARTprintf()。 它往往是"太特定于硬件"。
    要使开发更加灵活,请使用 sprintf()将变量文本存储到字符串中。
    然后、将字符串字节发送到所需的串行端口。 更简单的方法是使用 while ()循环内的 UARTCharPut()。
    此致
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    布鲁诺

    建议的实现如下所示:
    #include
    #include
    #include
    #include
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "Uart0.h"

    void Uart0_Configuration (void);

    int main()

    Uart0_Configuration ();

    字符 str[80];
    char * pt_str;

    sprintf (str、"圆周率值=%f"、M_PI);

    PT_str = str;//指针指向 str 的地址
    while (* pt_str!='\n'){
    UARTCharPut (UART0_BASE、* pt_str);
    PT_STR_+;


    返回(0);





    void Uart0_Configuration (void){

    //启用此示例使用的外设。
    //需要启用 UART 本身以及 GPIO 端口
    //包含将要使用的引脚。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

    //
    //为 UART 功能配置 GPIO 引脚复用。
    //只有当您的器件支持 GPIO 引脚功能多路复用时才需要此功能。
    //研究数据表以查看每个引脚分配的函数。
    // TODO:更改此选项以选择您正在使用的端口/引脚
    //
    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);

    //
    //由于 GPIO A0和 A1用于 UART 功能、它们必须是
    //配置为用作外设功能(而不是 GPIO)。
    //待办事项:更改此项以匹配您正在使用的端口/引脚
    //
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

    //
    //将 UART 配置为115、200、8-N-1操作。
    //此函数使用 SysCtlClockGet ()或 ui32SysClock 获取系统时钟
    //频率。 这也可以是一个变量或硬编码值
    //而不是函数调用。
    //
    #if defined (target_IS_TM4C129_RA0)|| \
    已定义(TARGET_IS_TM4C129_RA1)|| \
    已定义(TARGET_IS_TM4C129_RA2)
    UARTConfigSetExpClk (UART0_BASE、ui32SysClock、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    其他
    UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    #endif


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    只需小心地将当前字节与 C 标准端接器0x00... 和/或确保字符串末尾有一个"newline"字符-否则、它会将整个存储器永远发送到串行端口!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Matt

    API 调用

    UARTStdioConfig (0、115200、MAP_SysCtlClockGet ());

    不正确。您已将 UART 配置为以16MHz PIOSC 时钟为源、但波特率配置为115.2Kbps 时钟频率为50MHz。 应该是这样

    UARTStdioConfig (0、115200、16000000);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这是我感到困惑的原因。 我不太理解为什么"utils/uartstdio.c"不能通过"utils/uartstdio.h"访问。

    您必须为我的基本 c 和 c++知识库设置借口、但您是否建议将源代码粘贴到我的 main.c 文件中? 或者、我应该通过某种方式在我的 Makefile 文件中创建依赖项吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您提供相关信息。 我最初在那里有16000000、但在尝试将某项输出到控制台时更改了它。 我会将其改回。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我没有,但感谢这项建议。 不过、我不确定探头的位置是否正确、除非我撕下 USB 电缆。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Bruno 和 Thiago、

    感谢您的帮助! 我会尝试一下、并告诉您我的结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我无法让您的示例在 Thiago 工作。 出于某种原因、我不断获得"对'printf'的未定义引用"。 如果你有任何其他想法、我很乐意倾听。 再次感谢。

    我最终获得了输出。 我编辑了源代码并添加了 Makefile。 任何进一步的提示和有用的批评都是非常欢迎的。 再次感谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Matt McKenna">我没有、但感谢您的建议。 不过、我不确定探头的位置是否正确、除非我撕下 USB 电缆。

    [/报价]
    如果它是反向通道 UART、通过调试器和 USB 进行路由、则只剩下 TX/RX 引脚。 检查这些信号将告诉您初始化是否正常、波特率也是正确的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在这里、我不使用 UartPrintf、在这里、请尝试使用此示例代码。  这种方法的最佳方法是通过将 UART 端口从 Uart0更改为 Uart1来重新使用它。

    该函数基本上每次放置一个焦糖。 将其放入 while 循环中、您将有一个 UartString。  请参阅 Valvano 博士书中的此修改示例。

    /*

    该示例随本书一起提供
    "嵌入式系统:与 Arm Cortex M 微控制器的实时连接"、
    ISBN:978-1463590154、Jonathan Valvano、版权所有(c) 2015
    方案5.11第5.6节,方案3.10

    版权所有2015、作者:Jonathan W. Valvano、valvano@mail.utexas.edu
    您可以使用、编辑、运行或分发此文件
    只要保留上述版权声明
    此软件"按原样"提供。 不作任何明示或暗示的保证
    或法定的、包括但不限于对的暗示担保
    适用于特定用途的适销性和适用性适用于此软件。
    VALVANO 在任何情况下都不对特殊、意外、
    或后果性损害、无论出于何种原因。
    有关我的课程、我的研究和我的书籍的更多信息、请参阅
    users.ece.utexas.edu/.../
    *

    void UART_OutString (uint8_t *点){
      while (* pt){
        UARTCharPut (UART0_BASE、*点);
         PT++;
       }


     //

    //
    //
    //
    //版权所有(c) 2012-2015 Texas Instruments Incorporated。 保留所有权利。
    //软件许可协议
    //
    //德州仪器(TI)仅提供和使用此软件
    //专门用于 TI 的微控制器产品。 该软件归其所有
    // TI 和/或其供应商、受适用版权保护
    //法律。 您不能将此软件与"病毒"开源软件结合使用
    //软件,以便形成一个更大的程序。
    //
    //此软件按“原样”提供,且存在所有故障。
    //不作任何明示、暗示或法定的保证,包括但
    //不限于对适销性和适用性的暗示保证
    //此软件的特定用途。 TI 不得以任何方式进行
    //情况,对特殊、偶然或从属事件负责
    //任何原因造成的损害。
    //
    //这是 EK-TM4C123GXL 固件包版本2.1.2.111的一部分。
    //
    //


    #include
    #include
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "Uart0.h"

    void Uart0_Configuration (void){

    //启用此示例使用的外设。
    //需要启用 UART 本身以及 GPIO 端口
    //包含将要使用的引脚。
    //
    SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
    SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

    //
    //为 UART 功能配置 GPIO 引脚复用。
    //只有当您的器件支持 GPIO 引脚功能多路复用时才需要此功能。
    //研究数据表以查看每个引脚分配的函数。
    // TODO:更改此选项以选择您正在使用的端口/引脚
    //
    GPIOPinConfigure (GPIO_PA0_U0RX);
    GPIOPinConfigure (GPIO_PA1_U0TX);

    //
    //由于 GPIO A0和 A1用于 UART 功能、它们必须是
    //配置为用作外设功能(而不是 GPIO)。
    //待办事项:更改此项以匹配您正在使用的端口/引脚
    //
    GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

    //
    //将 UART 配置为115、200、8-N-1操作。
    //此函数使用 SysCtlClockGet ()或 ui32SysClock 获取系统时钟
    //频率。 这也可以是一个变量或硬编码值
    //而不是函数调用。
    //
    #if defined (target_IS_TM4C129_RA0)||\
    已定义(TARGET_IS_TM4C129_RA1)||\
    已定义(TARGET_IS_TM4C129_RA2)
    UARTConfigSetExpClk (UART0_BASE、ui32SysClock、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    其他
    UARTConfigSetExpClk (UART0_BASE、SysCtlClockGet ()、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE));
    #endif



    //uart0测试回显用户数据、直到\n\r\n 序列
    void Uart0_test (void){
    char cThisChar;
    //
    //放置一个字符以显示示例的开头。 这将显示在上
    //终端。
    //
    UARTCharPut (UART0_BASE、"!");

    //
    //输入循环,从 UART 读取字符,然后将其写回
    //(回波)。 当接收到一个线端时、循环终止。
    //
    操作

    //
    //使用阻塞式读函数读取字符。 此函数
    //在字符可用之前不会返回。
    //
    cThisChar = UARTCharGet (UART0_BASE);

    //
    //使用阻塞写入函数写入相同的字符。 这种情况
    //函数在 FIFO 和中有空间之前不会返回
    //字符被写入。
    //
    UARTCharPut (UART0_BASE、cThisChar);

    while ((cThisChar!='\n')&&(cThisChar!='\r\n');

    //
    //放置一个字符以显示示例的末尾。 这将显示在上
    //终端。
    //
    UARTCharPut (UART0_BASE、"@");