我想学习嵌入式编程,所以我买了一个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;
}
2条答案
按热度按时间jgzswidk1#
用于MCU的stdio库,其中
stdout
、stdin
根本不需要存在,而存在的地方则必然依赖于硬件和可用I/O,是项目开发人员的设计决策,而不是库设计人员的责任。对于嵌入式库,通常会有一个移植或"粘合"层来将库Map到硬件依赖项,如果您不提供必要的函数,它们将链接到通用的"不执行任何操作"存根。
您需要提供的特定stub函数覆盖取决于工具链,特别是您正在使用的C库。您"安装"它们的方法因工具链而异。有些使用"弱链接",您只需提供具有相同签名的覆盖,其他则使用具有指向低级I/O函数的函数指针的结构。例如,如果您正在使用AVR Libc,你只需要提供一个get-char/put-char函数,在
FILE
结构中使用它们分配给stdin
,stdout
流,如documentation中所述。例如:
你可以用任何适合你的系统的方式来实现低级字符I/O功能,比如使用UART、键盘、LCD显示器、调试器接口等等。
g6ll5ycj2#
char *name = (char *)malloc((int)NULL);
这完全没有意义。你基本上给name分配了0个字节。也不要强制转换malloc结果。1.在这个微型计算机上永远不要使用
malloc
类型的动态分配。它不是一台PC计算机,你需要忘记许多“大型”计算机的东西;1.你对这样一个目标的标准是什么?
1.你在这台显微镜上的水平是多少?
1.这很奇怪。而且它不会工作,因为你的参数中没有一个是C字符串。你知道最后一个参数是什么吗?
strlen
将不起作用,因为您没有传递C字符串。我不是很喜欢arduino IDE(因为它感觉有点太基础和抽象了,至少对我来说是这样:)
我认为以你的知识水平是正确的方向,Arduino是C++ +库,并不“简单”
是的,我没有错误。我包括了stdio. h,它实现了printf和fgetc
添加头文件并不能解决问题。您需要将一些低级函数写入
stdio
函数才能开始工作。默认情况下,stdout
和stdin
不通过UART通信。https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#ga4c04da4953607fa5fa4d3908fecde449