【发布时间】:2018-07-20 05:27:16
【问题描述】:
我已经重新开始学习 C,并且一直在进行“学术”练习以再次提高一些旧技能。我的项目围绕着生成正弦的相当简单的过程展开。我刚开始只是在命令行(Fedora Core 20)上为 x86 编码,一切正常。然后我将代码迁移到 AVR,我开始学到很多东西。例如,如何将 UART 设置为标准输出。然而,由于正弦是浮点数,我在使用 printf 和 sprintf 时遇到了问题。
程序生成 30 个正弦,然后将值打印到终端。文本“正弦:”打印正确,但随后我得到浮点数的问号。 用常量替换变量没有效果。
我被建议的第一件事是,如果我记得链接器选项以支持完全浮点 - 实际上我已经忘记了。同样,将其添加到我的 makefile 中没有任何效果。
我不确定这里复制和粘贴代码的政策:我应该将它和我的 makefile 粘贴到这里以供检查吗?
编辑:抱歉耽搁了这么久。我已经阅读了更多内容,包括第一个答案链接到的内容。我之前已经阅读过该参考资料(GNU 参考资料),并且我已将链接包含在我的 Makefile 中,这就是我如此困惑的原因。这是我所有荣耀的 Makefile:
P = sines
OBJ = sines.o
PROGRAMMER = buspirate
PORT = /dev/ttyUSB0
MCU_TARGET = atmega328p
AVRDUDE_TARGET = atmega328p
HZ = 16000000
DEFS =
LIBS = -lprintf_flt -lm
CC = avr-gcc
override CFLAGS = -g -DF_CPU=$(HZ) -Wall -O1 -mmcu=$(MCU_TARGET) $(DEFS)
override LDFLAGS= -Wl,-Map,$(P).map -u,vfprintf
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
all: $(P).elf lst text
$(P).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
rm -rf *.hex *.bin *.map *~ sine*.csv *.o $(P).elf *.lst
lst: $(P).lst
%.lst: %.elf
$(OBJDUMP) -h -S $< > $@
text: hex bin
hex: $(P).hex
bin: $(P).bin
%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@
%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@
install: $(P).hex
avrdude -p $(AVRDUDE_TARGET) -c $(PROGRAMMER) -P $(PORT) -v -U flash:w:$(P).hex
我担心的是链接器参数的顺序可能不正确?据我所知,他们只是......
我很确定我的代码本身没问题。如果需要,我也可以在这里发布。 另外,感谢您将我的问题转移到这里。不太明白这两者的区别!
这里是源代码。它在 ATmega328P 上运行。这个当前版本正在打印一个常量作为调试,而不是 sinescalc() 的结果,即使我知道该函数正在工作(至少,它应该是,我很确定我曾经使用 avr-gdb 检查过-- 它绝对适用于命令行,也适用于 MSP430)。
#include <avr/io.h>
//#include <util/delay.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
static int uart_putchar(char c, FILE *stream) {
if (c == '\n')
uart_putchar('\r', stream);
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = c;
return 0;
}
void sinescalc(double *sinptr, int cycles, int size) {
double pi = acos(-1);
double step = ((pi * (cycles*2))/ size);
float temp;
double z = step;
int y;
for(y = 0; y<= size; y++) {
temp = sin(z); // calculate the current sine
*sinptr = (double)temp; // pass it into the array from main()
z += step; // add the step value to prepare for next sine
sinptr++; // should move the pointer by correct size of variable
}
}
int main(void) {
unsigned long _fosc = 16000000;
unsigned int _baud = 19200;
unsigned long _myubrr = _fosc/16/_baud-1;
unsigned int array_size = 256;
UBRR0L = (unsigned char)_myubrr;
UCSR0B = (1<<RXEN0)|(1<<TXEN0); //enable receiver and transmitter
stdout = &mystdout;
double sines[array_size];
double *sinepointer = sines; // set sinepointer to first element of sines array
sinescalc(sinepointer, 2, array_size); // calculate two cycles of sine, with 255 data points
int y;
//char msg[6] = ("Sine: ");
char output[40];
for(y = 0; y <= array_size; y++) {
sprintf(output, "Sine:\t %.6f", 1.354462);
printf(output);
printf("\n");
}
return 0;
}
【问题讨论】:
-
非常感谢您阅读此导览。这个问题属于 StackOverflow.com,因为它讨论了 implementation specific or compiler specific 问题。插入指向问题回答者的小代码 sn-ps 也是好的和适当的。我的猜测是您的浮点数正在提升为双精度,并且需要正确设置格式字符串。
-
如果您向我们展示您遇到问题的代码会有所帮助,尤其是您调用 printf 等的地方。另外请说明您正在使用的环境(即哪个编译器)。跨度>
-
我正在使用 avr-gcc,如果需要,我可以向您展示我所有的源代码。实际上,我会将其附加到我上面的问题中。
标签: c