【问题标题】:Passing a variable in string in Embedded C在嵌入式 C 中传递字符串中的变量
【发布时间】:2016-07-12 09:26:07
【问题描述】:

我正在使用 ATmega8,我正在尝试通过 USART(printf 样式)发送包含变量的字符串。我使用 Atmel Studio 6.2 作为 AVR 编程的 IDE。这是我的代码:-

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>

void USARTInit(uint16_t ubrr_value)  // initialize USART
{

    UBRRL = ubrr_value;
    UBRRH = (ubrr_value>>8);
    UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

}

void USARTWriteChar(char data) // send character using USART
{

    while(!(UCSRA & (1<<UDRE)));
    UDR=data;
}

void send_string(char s[])   // send string using USART
{
    int i =0;

    while (s[i] != 0x00)
    {
        USARTWriteChar(s[i]);
        i++;
    }
    USARTWriteChar('\n');
}


int main(void)
{
    USARTInit(51);
    char val='A';
    while(1)
    {
        send_string("Value = %c",val);

    }
}

现在当我编译我的代码时,我得到了这个错误:-

函数 'send_string` 的参数太多

因此,显然它不像在 C 编程中那样接受 %cembedded C 有没有办法在字符串中传递变量?

【问题讨论】:

  • 没有“嵌入式C”语言!而且该函数不是标准库的一部分,因此,它在“C 编程”中工作。您可能首先想学习 C 以及什么是函数。

标签: c gcc microcontroller avr-gcc atmelstudio


【解决方案1】:

函数参数太多send_string

那里的信息很清楚,您的 send_string() 仅接受指向 char 的指针作为输入参数,但在调用时,您试图传递两个输入参数 "Value = %c",val 导致不匹配。

您不能在此处按照您显示的方式使用格式说明符。

一般来说,方法是使用临时缓冲区,使用snprintf() 生成输入字符串,然后将缓冲区传递给send_string() 调用。

也就是说,由于您只是有兴趣c 的值传递给send_string(),因此您可以将函数缩减为仅采用char,例如

void send_string(char s) { ...

然后,传递常量(预定义)字符串Value =,然后,输入参数得到同样的效果。

【讨论】:

  • 你实际上可以 - 但是你需要重新编写函数来获取变量参数列表。但是,您使用 s[n]printf 的方法要少得多。
  • 抱歉,但在嵌入式系统上使用printf-bloat 是一个非常糟糕的主意——如果它完全可用的话。
  • @tofro 这就是为什么我提到“..你展示的方式..”.
  • @Olaf 好的,在这方面,我添加了另一种方法。
【解决方案2】:

首先,没有嵌入式 C 语言。您正在使用 C 语言进行编程。此代码无效。

你的函数 void send_string(char s[]) 只接受一个 char [] 类型的参数。您将其称为send_string("Value = %c",val);,因此您将两个参数传递给它。在 C 字符串中,% 字符没有特殊含义。它只对printf 函数有意义。你打电话相当于send_string("It doesn't matter what you write here", 'A');

你可以用另一种方式做你想做的事:

#include <stdio.h>
...
int main(void)
{
    USARTInit(51);
    char val='A';
    char buffer[64];
    sprintf(buffer, "Value = %c", val);
    while(1)
    {
        send_string(buffer);
    }
}

【讨论】:

  • 我重复我写给另一个答案的内容:在嵌入式系统上使用 printf-bloat 是一个非常糟糕的主意 - 如果它完全可用的话。 (并且您的答案与另一个答案相同,只是更详细一点)。顺便提一句。 1KiB 内存的系统上的 1KiB 缓冲区?认真的吗?
  • @Olaf 只要您不经常调用它,它就应该那么糟糕。对我来说,它在 STM32 上运行良好。在 Atmega8 上它肯定更糟......是的,Atmega8 上的 1KiB 缓冲区可能不是一个好主意......无论如何,我们不知道 OP 试图实现什么,但显然他想使用printf 语法。我也不推荐。
  • @Olaf 我的意思是,如果操作需要 1 秒,但每分钟执行一次,那么它的执行时间是可以接受的。我简单地回答了这个问题。他想使用printf 语法。如果您愿意,请写一个更好的答案,但显然 OP 不是经验丰富的程序员并且想要一些简单的东西......什么是慢的,什么不是取决于您的要求。有时你想快速实现一个特性,而不是重新发明浮点到字符串的转换之类的东西。
  • 您没有回答这个问题,因为您没有考虑隐式约束。 embedded 标签的存在是有原因的。不,OP不想使用“printf语法”,而是输出一个额外的字符。格式字符串就是他尝试过的方式。仅从这个问题就可以判断 OP 缺乏基础知识,只是复制一种模式,但不知道它的含义(事实上,没有冒犯!)。
猜你喜欢
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多