AVR mega2560 printf()和fgetc()不工作

ryhaxcpt  于 2023-01-12  发布在  其他
关注(0)|答案(2)|浏览(170)

我想学习嵌入式编程,所以我买了一个arduino mega2560。我不是很喜欢arduino IDE(因为它感觉有点太基础和抽象了,至少对我来说:),所以我开始用纯C和avr工具包(avrdude之类的)编程。我想写一个程序,读取你的名字,然后 Flink 你名字中的每个字符的LED。
该方案的基本纲要是:
1.将LED引脚转到输出模式
1.* * printf()"输入您的姓名"
1.* * 使用fgetc、realloc等读取用户名(我没有使用scanf(),因为scanf()带有缓冲区会导致缓冲区溢出)
1.针对用户名中的每个字符 Flink LED
问题(用**表示)是我看不到printf的输出和fgetc要求输入。如何解决这个问题?
谢谢!
编辑:代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>

#ifndef STDIN
#define STDIN 0
#endif

int main(void) {
        char *name = (char *)malloc((int)NULL);
        char c;
        int cnt;
        int i;

        cnt = 1;

        DDRB |= (1 << DDB7);

        printf("Enter your name: ");

        while ((c = fgetc(STDIN)) != '\n') {
                name = (char *)realloc(name, cnt);
                strncat(name, &c, 1);

                cnt++;
        }

        for (i = 0; i < strlen(name); ++i) {
                PORTB |= (1 << PB7);
                _delay_ms(1000);
                PORTB &= ~(1 << PB7);
        }

        return 0;
}
jgzswidk

jgzswidk1#

用于MCU的stdio库,其中stdoutstdin根本不需要存在,而存在的地方则必然依赖于硬件和可用I/O,是项目开发人员的设计决策,而不是库设计人员的责任。
对于嵌入式库,通常会有一个移植或"粘合"层来将库Map到硬件依赖项,如果您不提供必要的函数,它们将链接到通用的"不执行任何操作"存根。
您需要提供的特定stub函数覆盖取决于工具链,特别是您正在使用的C库。您"安装"它们的方法因工具链而异。有些使用"弱链接",您只需提供具有相同签名的覆盖,其他则使用具有指向低级I/O函数的函数指针的结构。例如,如果您正在使用AVR Libc,你只需要提供一个get-char/put-char函数,在FILE结构中使用它们分配给stdinstdout流,如documentation中所述。
例如:

#include <stdio.h>

// Output character to stdout device
static int std_putchar(char c, FILE *stream)
{
    ...
    return 0;
}

// Input character from stdin device
static int std_getchar(char c, FILE *stream)
{
    ...
    return rxchar ;
}

// Create stdio stream
static FILE stdio_stream = FDEV_SETUP_STREAM( std_putchar, std_getchar,
                                              _FDEV_SETUP_RW ) ;

int main(void)
{
    stdout = &stdio_stream ;
    stdin = &stdio_stream ;
    stderr = &stdio_stream ;

    printf( "System Start - hello\n") ;

    // Echo input
    for(;;)
    {
        putchar( getchar() ) ;
    }
}

你可以用任何适合你的系统的方式来实现低级字符I/O功能,比如使用UART、键盘、LCD显示器、调试器接口等等。

g6ll5ycj

g6ll5ycj2#

  1. char *name = (char *)malloc((int)NULL);这完全没有意义。你基本上给name分配了0个字节。也不要强制转换malloc结果。
    1.在这个微型计算机上永远不要使用malloc类型的动态分配。它不是一台PC计算机,你需要忘记许多“大型”计算机的东西;
    1.你对这样一个目标的标准是什么?
    1.你在这台显微镜上的水平是多少?
    1.这很奇怪。而且它不会工作,因为你的参数中没有一个是C字符串。你知道最后一个参数是什么吗?
  2. strlen将不起作用,因为您没有传递C字符串。
    我不是很喜欢arduino IDE(因为它感觉有点太基础和抽象了,至少对我来说是这样:)
    我认为以你的知识水平是正确的方向,Arduino是C++ +库,并不“简单”
    是的,我没有错误。我包括了stdio. h,它实现了printf和fgetc
    添加头文件并不能解决问题。您需要将一些低级函数写入stdio函数才能开始工作。默认情况下,stdoutstdin不通过UART通信。https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#ga4c04da4953607fa5fa4d3908fecde449

相关问题