2014-04-06 38 views
0

我有一个用codevision AVR写的代码,用于ATmega2560发送格式化输出到USART 0和3.我的USART 0连接的是RS232接口,而USART 3是zigbee接口。当我用简单的测试程序测试zigbee接口时,它是可以的,所以zigbee应该没有问题。当使用这个时,USART 0接收字符串没有任何问题,但是USART 3有问题,所以我决定在这里发布它以知道这里有什么问题。上述sprintf在avr中的奇怪行为

#include <mega2560.h> 
#include <stdio.h> 
#include <string.h> 
#define BUFF_SIZE  200 

unsigned char out_buf[BUFF_SIZE]; 

void USART0_init(void) /*************** USART 0 ***********************/ 
{  
    UCSR0A = 0x00; 
    UCSR0B |= (1<<RXEN0)|(1<<TXEN0); 
    UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);   
    UBRR0H=0x00; 
    UBRR0L=103; //baud rate 9600 
} 

void USART0_putc(unsigned char data) 
{ 
    while(!(UCSR0A & (1<<UDRE0))); 
    UDR0=data; 
} 

void USART0_puts(unsigned char* str){ 
    while(*str) {USART0_putc(*str++);} 
} 
void USART3_init(void) /*************** USART 3 ***********************/ 
{  
    UCSR3A = 0x00; 
    UCSR3B |= (1<<RXEN3)|(1<<TXEN3); 
    UCSR3C |= (1<<UCSZ31)|(1<<UCSZ30);   
    UBRR3H=0x00; 
    UBRR3L=8; //baud rate 115200; 
} 

void USART3_putc(unsigned char data) 
{ 
    while(!(UCSR3A & (1<<UDRE3))); 
    UDR3=data; 
} 

void USART3_puts(unsigned char* str){ 
    while(*str) {USART3_putc(*str++);} 
} 

该代码可用于USART 0和3 每60秒在通过USART 0和3中显示的代码是在这里。

if (tick_60sec == 60){  
    tick_60sec = 0; 
    axis_store();axis_disp();     
    sens_avg_call(); 

    t3_l = 1; t6_l = 1; 
    t9_l = 1; t12_l = 1; 
    t15_l = 1; t17_l = 1; 
    t19_l = 1; 
} 

void sens_avg_call(void) 
{ 
    sprintf(out_buf,"wind current avg: %d",(windc_av/3));  
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"wind voltage avg: %d",(windv_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"solar current avg: %d",(solc_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"solar voltage avg: %d",(solv_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"led current avg: %d",(ledc_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"battery voltage avg: %d",(battv_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
    sprintf(out_buf,"temperature avg: %d",(temp_av/3)); 
    USART3_puts(out_buf); 
    USART0_puts(out_buf); 
} 
+0

您无法获得任何使用速度二进制文字超过'_BV()'调用。 –

+0

我已经编辑了上面的寄存器设置。 –

回答

0

从你的波特率除数设置我可以看到你使用的是16 MHz时钟。对于115200波特率和8的除数设置,你将会有3.7%的误差,这是相当有限的,我发现一些ZibBee模块特别关注波特率。

一个解决方案是使用更“波特率友好”的时钟速度,例如14.7456 Mhz,您可能会发现WormFood's AVR Baud Rate Calculator可用于选择晶振。您需要检查模块的文档,但另一种解决方案是降低波特率,使其在16 MHz处具有较低的错误,例如9600或38400.