c - 使用 usart 重新定义 stdio 的 Printf 无法正确格式化

标签 c atmega atmel usart

我正在使用带有 Atmega328p 微 Controller 的 Arduino Uno,并使用 AVR 引导加载程序和 Atmel Studio。

我已经设置了 USART 通信,它可以成功发送由我的计算机上的终端读取的数据,但使用 printf 时格式不正确。

    /*
 * USART_HelloWorld.c
 *
 * Created: 6/20/2016 4:17:16 PM
 * Author : Kevin
 */ 

#define F_CPU 16000000
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#include <avr/io.h>
#include <stdio.h>

static int USART_Transmit(char, FILE*);
static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit, NULL, _FDEV_SETUP_WRITE);

USART_Init(unsigned int ubrr){
    UCSR0B |= (1<<TXEN0)|(RXEN0);//enables transmitting and receiving
    UCSR0C |= 3<UCSZ00; //8 bit data, 1 stop bit
    UBRR0H |= (unsigned char)(ubrr>>8);  //sets baud rate
    UBRR0L |= (unsigned char)ubrr;//sets baud rate

}
static int USART_Transmit(char data, FILE *stream){
    if(data=='\n') 
        USART_Transmit('\r',stream);
    while(!((UCSR0A)&(1<<UDRE0)));
    UDR0 = data;
    return 0;
}
int main(void)
{
    USART_Init(MYUBRR);
    stdout = &mystdout;
    printf("Server name= 0x%X\nMy name is %s\nThis number is %d!\n", 0xDEADBEEF, "Kevin", 5);
    while (1);
}

我引用的是 this做这个的时候。

我应该得到如下输出:

Server name=0xDEADBEEF
My name is Kevin
This number is 5!

但是我得到:

Server name= 0xBEEF
My name is 
This number is 270!

任何建议

最佳答案

正如 Joachim Pileborg 和 Barmar 指出的那样,我需要将 %X 更改为 %lx 并将十六进制数字更改为 long。完成此操作后,输出大部分是正确的,但输出的某些位将被省略。

事实证明,这是因为按照源示例的建议,所有“\n”传输都转换为“\r”。事实证明,就我而言,这不是我想要的。删除后:

if(data=='\n') 
        USART_Transmit('\r',stream);

Usart_Transmit 函数的输出格式正确。

谢谢大家的帮助。

关于c - 使用 usart 重新定义 stdio 的 Printf 无法正确格式化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37934095/

相关文章:

c - 注释风格会影响二进制大小吗?

c - 编译时asm中不可能的约束

c - AVR C : 8 Bit Counter using button

c - gethostbyaddr() 返回 NULL 但 errno 结果成功

使用 MRuby 编译 Contiki 应用程序

C : error: expected expression before ‘.’ token 中的编译错误

c - 三个条件排列的最快算法是什么?

c - 如何在 C 程序中最好地实现字符串到数字的映射

c - Arduino定时器中断采样

c - ASF4 Microchip API定时器驱动复位函数