2014-04-06 3 views
0

포맷 된 출력을 USART 0 및 3으로 보내려면 ATmega2560 용 codevision AVR로 작성된 코드가 있어야합니다. USART 3은 RS232 인터페이스이고 USART 3은 지그비 인터페이스입니다. 간단한 테스트 프로그램으로 지그비 인터페이스를 테스트했을 때 지그비에 문제가 없어야 했으니까요. 이것을 사용할 때, USART 0은 아무런 문제없이 문자열을 사용하지만 USART 3에는 문제가있어서 여기에 무엇이 잘못되었는지를 알기 위해 여기에 게시하기로 결정했습니다.avr에서 sprintf의 비정상적인 동작

#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 초 간격으로 3 USART 0으로 표시하는 코드이다.

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

전송률 제수 설정에서 볼 수있는 것은 16MHz 클럭입니다. 115200 보드 속도와 8의 제수 설정에 대해 3.7 %의 오차를 보일 것입니다. 이것은 상당히 한계가 있습니다. ZibBee 모듈 중 일부는 보드 속도와 관련이 있다는 것을 발견했습니다.

한 가지 해결 방법은 14.7456MHz와 같은보다 "전송 속도 친화적 인"클럭 속도를 사용하는 것이지만 크리스탈을 선택하는 데 유용한 WormFood's AVR Baud Rate Calculator을 찾을 수 있습니다. 모듈에 대한 설명서를 확인해야하지만 다른 솔루션은 9600 또는 38400과 같이 16MHz에서 낮은 오류가있는 보드에 전송 속도를 떨어 뜨리는 것입니다.