2015-01-26 4 views
0

ATmega328P로 구동되는 Arduino Uno가 있습니다. 그리고 저는 도서관에서 멀리 떨어져서 학습 목적으로 레벨의 모든 것을하고 싶었습니다. 그러나 내가 제대로 작동하는 UART를 얻을 수 없다, 그것은 장치에 보낼 때만 작동합니다. 수령하면 기적이 인쇄 할 수없는 이상한 쓰레기가 반환됩니다.UART는 한 방향으로 만 올바르게 작동합니다 (ATmega328p)

#define BAUDRATE (((F_CPU/(BAUD * 16UL))) - 1) 
void init_uart() 
{ 
    UBRR0H = BAUDRATE >> 8; // set high baud 
    UBRR0L = BAUDRATE; //set low baud 
    UCSR0B = _BV(TXEN0) | _BV(RXEN0); //enable duplex 
    UCSR0C = _BV(UCSZ00) | _BV(UCSZ01) | _BV(USBS0); //8-N-1 
} 

void putchar_uart(char c, FILE* stream) 
{ 
    loop_until_bit_is_set(UCSR0A, UDRE0); //wait till prev char is read 
    UDR0 = c; 
} 

char getchar_uart(FILE* stream) 
{ 
    loop_until_bit_is_set(UCSR0A, RXC0); //wait if there is data 
    return UDR0; 
} 

//^ actually is in a seperate file which gets linked 

int main() 
{ 
    DDRD |= PIN_LED; 
    PORTD |= PIN_LED; 

    stdout = &mystdout; 
    stdin = &mystdin; 

    char buf[0xFF]; 

    init_uart(); 
    while (1) 
    { 
     char c = getchar_uart(NULL); 
     if (c == 'a') 
     { 
      PIND = PIN_LED; 
      printf("%s\n", "Hallo"); 
     } 
    } 
} 

저는 Ubuntu 14.04 LTS를 실행 중이고 통신을 위해 minicom을 사용하고 있습니다. 그래서

avr-gcc -Wall -Os -mmcu=atmega328p -DF_CPU=16000000UL -DBAUD=115200 -std=c99 -L/home/joel/avr-libs/lib -I/home/joel/avr-libs/inc -o firmware.o main.c -luart 

가 어떻게 하나의 방법 일 것을 알고 : 어느 설치 될 때 : 그것은 컴파일됩니다 115200 8N1 (물론 올바른 시리얼 장치.)

? 왜냐하면 led는 'a'를 타이핑 할 때만 토글됩니다. 그러나 응답은 유효하지 않은 문자입니다. 16 진수 :

+0

기본적으로 보내는 내용을 수신하고 있으며, 비트 7이 잘못 설정되어 있습니다. 이것은 데이터 비트 또는 정지 비트 또는 패리티의 수에 대한 불일치를 제시 할 수있다. 설정과의 비교를 위해 UART 설정 레지스터 값을 덤프하는 빠른 Arduino 스케치를 고려하십시오. –

+0

@ChrisStratton 필자가 쓴 모든 레지스터 (USCR0A 포함)를 덤프하는 간단한 스케치를 만들었습니다. 특별한 것은 아니 었습니다. 유일한 차이점은 Arduino가 UCSR0B 레지스터에서 RXCIE, UDRIE 비트를 설정하고 UCSR0A에서 U2X 비트를 설정한다는 것입니다. 그래서 기본적으로 인터럽트와 더블 모드를 사용합니다. 작동한다면 더블 모드를 테스트 할 것입니다 .. – joell

답변

1

USBS 비트를 설정하면 두 번째 정지 비트가 지정됩니다.

이것은 수신 데이터가 0x80과 OR 연산을 일으키지 않을 때 컴퓨터가 실수로 MSB (마지막 데이터 비트)가 설정되었다고 생각하는 것처럼 보입니다.

이것은 프레이밍 오류를 유발하지만 잘못된 MSB의 원인이 아닐 수도 있습니다. 2x 모드로 전환하는 것에 대한 자신의 답변 (따라서 보율을보다 정확하게 추정)이 솔루션의 핵심입니다.하지만이를 수정해야합니다.

+0

데이터 시트를 오해 한 것 같습니다. 고마워요 :) – joell

+0

당신은 분명히 USBS를 원하지 않지만, 이것이 데이터를 손상시키고있는 전송 속도 오류인지 아니면 잘 모르겠습니다. –

+0

2x 모드를 활성화 할 때도 작동했는데 이유는 무엇입니까? 아니면 우연 이었습니까? – joell

1

Chris가 Arduino에서 사용하는 구성 레지스터를 인쇄 할 때 문제가 수정되어 이중 모드를 사용한다는 것을 알았습니다. 나는 미니 콤으로 구성 할 수 없었습니다. 아마 그런 모드를 사용하는 것이 기본값입니다. 어쨌든 이제는 작동합니다.

avr-libc는 올바른 baud rate를 자동으로 계산하는 util/setbaud.h라는 헤더를 제공한다는 것도 알게되었습니다. UBRRL_VALUE 및 UBRRH_VALUE 필드.

+0

더블 모드는 직렬 워드의 속성이 아니라 UART의 구성입니다. 특정 클럭/타겟 보드 상태에 대해 더 큰 타이밍 정확도로 이어질 수 있습니다. 보이스 레이트 오류로 인해 MSB의 평가 창에 스톱 비트가 떨어질 수 있습니다. –

+0

숫자를 실행할 때 보통 모드에서 사용할 수있는 가장 가까운 숫자는 125kbaud입니다. 2x 모드는 117.6 kbaud에서 훨씬 좋은 근사값을 얻을 수 있습니다. 그래서 나는 실수로 인한 MSB가 보오 오류로 인한 것 같아요. –

관련 문제