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-TM4C1294XL:如何在 UART 上打印浮动值

Guru**** 2473260 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/682450/ccs-ek-tm4c1294xl-how-to-print-floating-values-on-uart

器件型号:EK-TM4C1294XL

工具/软件:Code Composer Studio

您好,

我正在尝试使用 UART 打印 ADC 值的计算功率和电压值。 我已经按照 TIvaware 中的 sensohub 示例进行了操作。 但我会得到以下错误。

此行有多个标记
   -#1531-D (ULP 5.2)检测到浮点运算。 建议移动它们
   在运行期间写入 RAM、或者不使用、因为这些是处理/功耗密集型的
   "="">processors.wiki.ti.com/.../
   225">#225-D 函数"uftostr"隐式声明

代码如下:

//
//
// single_ended.c -演示如何为配置 ADC 的示例
//                 单端操作。
//
//版权所有(c) 2010-2017 Texas Instruments Incorporated。  保留所有权利。
//软件许可协议
//
//  以源代码和二进制形式重新分发和使用,有无
//  如果满足以下条件,则允许进行修改
//  满足:
//
//  重新分发源代码必须保留上述版权
//  注意、此条件列表和以下免责声明。
//
//  二进制形式的重新分发必须复制上述版权
//  注意、中的条件列表和以下免责声明
//  随提供的文档和/或其他材料
//  分布。
//
//  德州仪器公司的名称和的名称都不是
//  其贡献者可用于认可或推广衍生产品
//  未经特定的事先书面许可,从该软件下载。
//
//本软件由版权所有者和作者提供
//“原样”以及任何明示或暗示的保证,包括但不包括
//限于对适销性和适用性的暗示保证
//一个特定的目的是免责的。 在任何情况下、版权均不得
//所有者或贡献者应对任何直接、间接、偶然、
//特殊、典型或必然的损害(包括但不包括)
//仅限于采购替代货物或服务;
//数据或利润;或业务中断)
//责任理论,无论是合同责任、严格责任还是侵权行为
//(包括疏忽或其他)以任何方式因使用而产生
//此软件,即使已被告知可能会发生此类损坏。
//
//这是 Tiva 固件开发包的修订版2.1.4.178的一部分。
//
//

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

#include "utils/uartstdio.h"

#include
#include
#include "inc/hw_memmap.h"
#include
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/rom.h"
#include "driverlib/interrupt.h"


#include "inc/hw_ints.h"

//
//
//! 添加到组 ADC_Examples_list
//!

单端 ADC (single_ended)


//!
//! 此示例展示了如何将 ADC0设置为单端输入并采用
//! AIN0/PE3上的单个采样。
//!
//! 此示例使用以下外设和 I/O 信号。  您必须执行的操作
//! 查看这些内容并根据您自己的董事会的需要进行更改:
//! - ADC0外设
//! - GPIO 端口 E 外设(用于 AIN0引脚)
//! AIN0 - PE3
//!
//! 以下 UART 信号仅配置为显示控制台
//! 消息。  操作时不需要这些
//! ADC。
//! UART0外设
//! - GPIO 端口 A 外设(用于 UART0引脚)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! 此示例使用以下中断处理程序。  来使用该示例
//! 在您自己的应用程序中、您必须将这些中断处理程序添加到
//! 矢量表。
//! -无。
//
//
//volatile uint32_t adcResult[1];

//volatile unit32_t pui32ADC0Value1[1];

uint32_t pui32ADC0Value[1];
静态易失性 bool g_bIntFlag = false;
#define SAMPLE_PERIOD_US 1000
浮点电流= 0;
   浮点电压=3.3;
   浮点功率= 0;
   浮点 maxPwr = 0;
   float avgPwr = 0;
   int i = 0;
//#define SAMPLE_PERIOD ((g_syshz*SAMPLE_PERIOD_US)/1000000)
//
//
//此函数将 UART0设置为用于控制台显示信息
//因为示例正在运行。
//
//
无效
InitConsole (空)

   //
   //启用用于 UART0引脚的 GPIO 端口 A。
   // TODO:将其更改为您正在使用的 GPIO 端口。
   //
   SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);

   //
   //为端口 A0和 A1上的 UART0功能配置引脚复用。
   //如果您的器件不支持引脚复用、则无需执行此步骤。
   // TODO:更改此选项以选择您正在使用的端口/引脚。
   //
   GPIOPinConfigure (GPIO_PA0_U0RX);
   GPIOPinConfigure (GPIO_PA1_U0TX);

   //
   //启用 UART0以便我们可以配置时钟。
   //
   SysCtlPeripheralEnable (SYSCTL_Periph_UART0);

   //
   //使用内部16MHz 振荡器作为 UART 时钟源。
   //
   UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);

   //
   //为这些引脚选择替代(UART)功能。
   // TODO:更改此选项以选择您正在使用的端口/引脚。
   //
   GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);

   //
   //初始化控制台 I/O 的 UART
   //
   UARTStdioConfig (0、115200、16000000);



/*void Timerconf(void)


   //必须启用 Timer0外设才能使用。
   SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);
   //将 Timer0B 配置为32位周期定时器。
   TimerConfigure (Timer1_base、timer_CFG_PERIODICRACRACASE);
   //将 Timer0A 加载值设置为1ms。
   TimerLoadSet (Timer1_base、timer_A、sample_period);

   //启用触发
   TimerControlTrigger (Timer1_base、timer_A、true);
   }*/
//
//
//为单端输入和单个采样配置 ADC0。  一次
//样本就绪,将设置中断标志。  使用轮询方法、
//数据将被读取,然后通过 UART0显示在控制台上。
//
//
内部
main (空)

#if defined (target_IS_TM4C129_RA0)||                                        \
   已定义(TARGET_IS_TM4C129_RA1)||                                        \
   已定义(TARGET_IS_TM4C129_RA2)
   uint32_t ui32SysClock;
#endif

   //
   //该数组用于存储从 ADC FIFO 读取的数据。 它
   //必须与正在使用的序列发生器的 FIFO 一样大。  此示例
   //使用 FIFO 深度为1的序列3。  如果是另一个序列
   //与更深的 FIFO 一起使用,则必须更改数组大小。
   //
   //uint32_t pui32ADC0Value[1];
   uint32_t 值= 0;

   浮点电流= 0;
   浮点电压=3.3;
   浮点功率= 0;
   浮点 maxPwr = 0;
   float avgPwr = 0;
   int i = 0;

   //
   //使用 PLL 将时钟设置为以20MHz (200MHz/10)运行。  时间
   //使用 ADC,您必须使用 PLL 或提供16 MHz 时钟
   //源。
   // TODO:必须更改 SYSCTL_XTAL_VALUE 以匹配的值
   板上的//晶体。
   //
#if defined (target_IS_TM4C129_RA0)||                                        \
   已定义(TARGET_IS_TM4C129_RA1)||                                        \
   已定义(TARGET_IS_TM4C129_RA2)
   ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
                                      SYSCTL_OSC_MAIN |
                                      SYSCTL_USE_PLL |
                                      SYSCTL_CFG_VCO_480)、20000000);
其他
   SysCtlClockSet (SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                  SYSCTL_XTAL_16MHz);
#endif

   uint32_t g_syshz;


   G_SYshz = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |
                                                SYSCTL_OSC_MAIN |
                                                SYSCTL_USE_PLL |
                                                SYSCTL_CFG_VCO_480)、
                                                120000000L);



   //设置用于显示消息的串行控制台。  这是
   //仅用于此示例程序,ADC 操作不需要。
   //
   InitConsole();
   //Timerconf();
   //
   //在控制台上显示设置。
   //
   UARTprintf ("ADC ->\n");
   UARTprintf (" 类型:单端\n");
   UARTprintf (" 示例:一个\n");
   UARTprintf (" 更新速率:250ms\n");
   UARTprintf (" 输入引脚:AIN0/PE3\n\n");

   /*
    *
    *开关触发器的设置
    *
    *



       //启用端口 J
       //SysCtlPeripheralEnable (SYSCTL_Periph_GPIOJ);
       //延迟以使时钟保持稳定
      // SysCtlDelay (3);

       /*
       使用将 Launchpad 左侧的开关 GPIO_PIN_0配置为输入
       内部上拉。
     *
     //GPIOPinTypeGPIOInput (GPIO_PORTJ_BASE、GPIO_PIN_0);
     //GPIOPadConfigSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
     //GPIOIntTypeSet (GPIO_PORTJ_BASE、GPIO_PIN_0、GPIO_FALLING_EDGE);
     //GPIOADCTriggerEnable (GPIO_PORTJ_BASE、GPIO_PIN_0);
       //使 PF4成为 ADC 的触发器
      // GPIOADCTriggerEnable (GPIO_PORTJ_BASE、GPIO_PIN_0);

   //
   //必须启用 ADC0外设才能使用。
   //
   SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);

   //
   //对于此示例、ADC0与端口 E7上的 AIN0一起使用。
   //您使用的实际端口和引脚可能有所不同,请参阅
   //数据表以了解更多信息。  需要启用 GPIO 端口 E
   //因此可以使用这些引脚。
   // TODO:将其更改为您正在使用的 GPIO 端口。
   //
   SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);

   //
   //为这些引脚选择模拟 ADC 功能。
   //请查阅数据表以查看每个引脚分配的函数。
   // TODO:更改此选项以选择您正在使用的端口/引脚。
   //
   GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_3);

   //
   //使用处理器信号触发器启用采样序列3。  序列3
   //将在处理器发送信号启动时执行单次采样
   //转换。  每个 ADC 模块有4个可编程序列、序列0
   //至序列3。  此示例任意使用序列3。
   //
   ADCSequenceConfigure (ADC0_BASE,3,ADC_TRIGGER_TIMER,0);

   //
   //在序列3上配置步骤0。  对中的通道0 (ADC_CTL_CH0)进行采样
   //单端模式(默认)并配置中断标志
   //(ADC_CTL_IE)将在采样完成时置1。  告诉 ADC 逻辑
   //这是序列3上的最后一次转换(ADC_CTL_END)。  序列
   // 3只有一个可编程步骤。  序列1和2有4个步骤、和
   //序列0有8个可编程步骤。  因为我们只做一个
   //使用序列3进行转换,我们将仅配置步骤0。  了解详情
   //有关 ADC 序列和步骤的信息、请参考数据表。
   //
   ADCSequenceStepConfigure (ADC0_BASE、3、0、ADC_CTL_CH0 | ADC_CTL_IE |
                            ADC_CTL_END);

   //
   //由于采样序列3现在已配置,因此必须将其启用。
   //
   ADCSequenceEnable (ADC0_BASE、3);

   //
   //清除中断状态标志。  这样做是为了确保
   //中断标志在我们进行采样之前被清除。
   //

   ADCIntClear (ADC0_BASE、3);


   /*
    *计时器
    *

   //必须启用 Timer1外设才能使用。
       SysCtlPeripheralEnable (SYSCTL_Periph_Timer1);
       //将 Timer1A 配置为32位周期定时器。
       TimerConfigure (Timer1_base、timer_CFG_PERIODICRACRACASE);
       //将 Timer1A 加载值设置为1ms。
       //TimerLoadSet (Timer1_base、timer_A、sample_period);
#define F_sample   1000
       TimerLoadSet (Timer1_base、timer_A、SysCtlClockGet ()/F_sample);
       //启用触发
      // TimerControlTrigger (Timer1_base、timer_A、true);
       TimerControlTrigger (Timer1_base、timer_A、true);






   IntMasterEnable();

       //启用 ADC 中断
    ADCIntEnable (ADC0_BASE、3);

       //在 NVIC 中启用 ADC0序列发生器3中断
   IntEnable (INT_ADC0SS3);
   //永久采样 AIN0。  显示控制台上的值。

   //启用 Timer1A。
   TimerEnable (Timer1_base、timer_A);

  while (1)
   {
       //
       //触发 ADC 转换。
       //
      //ADCProcessorTrigger (ADC0_BASE、3);

     //值= GPIOPinRead (GPIO_PORTJ_BASE、GPIO_PIN_0);

   //如果按下 PF4、则触发 ADC 转换
     // if (((value & GPIO_PIN_0)=0){

       //
       //等待转换完成。
       //
      // while (!ADCIntStatus (ADC0_BASE、3、false)

           while (!g_bIntFlag)
       {
       }

       //

       //清除 ADC 中断标志。
       //
       ADCIntClear (ADC0_BASE、3);

       //
       //读取 ADC 值。
       //
      /* ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value);
       电流=(0.3/4096)*pui32ADC0Value[0];

       功率=电流*电压;
       i++;

              // avgPwr = avgPwr *(I-1)/I +(power/I);
       avgPwr = avgPwr *(I-1)/I +(POWER/I);
              // i++;

       if (power > maxPwr) maxPwr = power;
*
       //
       //在控制台上显示 AIN0 (PE3)数字值。
       //
     UARTprintf ("ADC 感应数据=%4D\r\n、pui32ADC0Value[0]);

     pccar CurrentBuf[12];
    

         //
         //将结构的浮点成员转换为字符串。
         //
         uftostr(pcCurrentBuf, 12, 3, current);
        

         //
         //用三位十进制精度打印电流。
         //
         UARTprintf ("测量的电流:\t\t%s\t"、pcCurrentBuf);

         //
         //打印湿度,精度为三位数。
         //
     //   UARTprintf ("湿度:\t%s\n"、pcHumidityBuf);


       //此函数提供了生成恒定长度的方法
       //延迟。  函数延迟(以周期为单位)= 3 *参数。  延迟
       //任意地250ms。
       //Q
#if defined (target_IS_TM4C129_RA0)||                                        \
   已定义(TARGET_IS_TM4C129_RA1)||                                        \
   已定义(TARGET_IS_TM4C129_RA2)
       SysCtlDelay (ui32SysClock / 12);
其他
       SysCtlDelay (SysCtlClockGet ()/12);
#endif
      //}
   }



void ADC0SS3_handler (void)

  //unit32_t adcResult = 0;

   //adcResult= ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value1);

   ADCIntClear (ADC0_BASE、3);
   //读取 ADC 值。
   ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value);
   ADCSequenceDataGet (ADC0_BASE、3、pui32ADC0Value);
           电流=(3.3/4096)*pui32ADC0Value[0];

           功率=电流*电压;
           i++;

                  // avgPwr = avgPwr *(I-1)/I +(power/I);
           avgPwr = avgPwr *(I-1)/I +(POWER/I);
                  // i++;

           if (power > maxPwr) maxPwr = power;
  //电流=(3.3/4096)*pui32ADC0Value[0];
   G_bIntFlag = true;



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

    最好的方法是使用 printf()/sprintf();

    最明智的方法是使用 printf()/sprintf(),前提是在代码的其余部分已经使用 printf()/sprintf()。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    水晶般清澈!
    这里有人指出,偶尔使用"上案"符合惯例,而且是免费的!