AVR이 직렬 포트를 통해 대화 할 수 있도록이 코드를 수정하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/846206

  •  21-08-2019
  •  | 
  •  

문제

나는 최근에 내 머리카락을 꺼내어 STK200에서 ATMEGA162를 얻으려고 RS232를 통해 컴퓨터와 대화하려고 노력했습니다. STK200에 MAX202CPE 칩이 포함되어 있는지 확인하고 확인했습니다.

칩을 내부 8MHz 시계를 사용하도록 구성하고 8로 나누었습니다.

데이터 시트에서 코드를 복사하려고했지만 (컴파일러가 불만을 제기 한 곳을 변경했지만) 아무 소용이 없습니다.

내 코드는 아래에 있습니다. 누군가 내가 가지고있는 문제를 해결하는 데 도움이 될 수 있습니까?

직렬 포트가 다른 장치에서 작동하고 결함이 없음을 확인했습니다.

감사!

#include <avr/io.h>
#include <avr/iom162.h>

#define BAUDRATE 4800

void USART_Init(unsigned int baud)
{
    UBRR0H = (unsigned char)(baud >> 8);
    UBRR0L = (unsigned char)baud;

    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    UCSR0C = (1 << URSEL0) | (1 << USBS0) | (3 << UCSZ00);
}

void USART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1 << UDRE0)));

    UDR0 = data;
}

unsigned char USART_Receive()
{
    while(!(UCSR0A & (1 << RXC0)));

    return UDR0;
}

int main()
{

    USART_Init(BAUDRATE);

    unsigned char data;

    // all are 1, all as output
    DDRB = 0xFF;

    while(1)
    {
        data = USART_Receive();

        PORTB = data;

        USART_Transmit(data);


    }
}
도움이 되었습니까?

해결책 4

데이터 시트를 좀 더 철저하게 읽은 후에는 보드 레이트를 잘못 설정했습니다. ATMEGA162 데이터 시트에는 BAUD 속도와 해당 오류에 대해 클록 주파수 차트가 표시되었습니다.

4800 보드 속도와 1MHz 시계 주파수의 경우 오차는 0.2%로 허용되었습니다. 트릭은 12를 4800 대신 USART_INIT () 함수로 전달했습니다.

이것이 다른 사람을 도울 수 있기를 바랍니다!

다른 팁

Greg의 답변에 대해 언급했지만 한 가지 더 추가하고 싶습니다. 이런 종류의 문제에 대해서는 골드 표준 디버깅 방법이 먼저 이해하다 비동기 직렬 통신, 오실로스코프를 얻고 라인에서 무슨 일이 일어나고 있는지 확인하십시오. 캐릭터가 교환 중이고 보드 레이트 문제 일 뿐이라면보고있는 보드 레이트를 계산 한 다음 그에 따라 제수를 조정할 수 있으므로 특히 도움이됩니다.

다음은 매우 빠른 입문서입니다. 의심 할 여지없이 Wikipedia 나 다른 곳에서 훨씬 더 포괄적 인 것을 찾을 수 있습니다.

8 비트, 패리티 없음, 1 스톱 비트 (가장 일반적인 설정)를 가정 해 봅시다. 그런 다음 전송되는 캐릭터가 0x3f (= ascii '?')라고 말하면 선이 다음과 같이 보입니다.

...--+   +---+---+---+---+---+---+       +---+--...
     | S | 1   1   1   1   1   1 | 0   0 | E
     +---+                       +---+---+

높이는 칩에서 +5V이고 RS232 레벨로 변환 한 후 -12V입니다.

낮은 (0) 레벨은 칩에서 0V이고 RS232 레벨로 변환 한 후 +12V입니다.

S는 시작 비트입니다.

그런 다음 8 개의 데이터 비트가 있고 가장 먼저 중요합니다. 여기 00111111 = 0x3f = '?'.

e는 정지 (e for End) 비트입니다.

오실로스코프 디스플레이와 마찬가지로 시간이 왼쪽에서 오른쪽으로 진행됩니다. Baudrate가 4800 인 경우 각 비트가 1/4800 인 경우 (1/4800) 초 (1/4800) = 0.21 밀리 초 (약).

수신기는 라인을 샘플링하고 하락 가장자리를 찾아 작동합니다 (정지 선은 항상 논리적 인 '1'입니다). 수신기는 보드 레이트와 시작 비트 수 (1)를 알고 있으므로 하락 가장자리에서 1.5 비트 시간을 측정하여 시작 비트의 중간을 찾은 다음 그 후 8 비트를 연속으로 샘플링하여 수집합니다. 데이터 비트. 그런 다음 수신기는 한 번 더 기다렸다 (정지 비트를 통해 절반까지) 다른 시작 비트 (즉, 하락 가장자리)를 찾기 시작합니다. 한편 캐릭터 읽기는 나머지 시스템에서 사용할 수 있습니다. 송신기는 정지 비트가 완료 될 때까지 다음 하락 가장자리가 시작되지 않도록 보장합니다. 송신기는 항상 더 오래 기다릴 수 있도록 프로그래밍 할 수 있지만 (추가 스톱 비트로) 레거시 문제이므로 추가 스톱 비트는 매우 느린 하드웨어 및/또는 소프트웨어 설정으로 만 필요했습니다.

나는 참조 자료가 편리하지 않지만 Baud Rate Register UBRR에는 일반적으로 원하는 Baud 속도 자체가 아닌 Divisor 값이 포함되어 있습니다. ㅏ 빠른 Google 검색 4800 Baud의 올바른 디바이저 값은 239 명일 수 있음을 나타냅니다. 따라서 시도하십시오.

divisor = 239;
UBRR0H = (unsigned char)(divisor >> 8);
UBRR0L = (unsigned char)divisor;

이것이 작동하지 않으면 올바른 제수 계산 공식에 대한 특정 칩에 대한 참조 문서에 확인하십시오.

UART 커뮤니케이션을 디버깅하기 위해서는 두 가지 유용한 일이 있습니다.

1) 커넥터에서 루프백을하고 쓰는 내용을 다시 읽을 수 있는지 확인하십시오. 캐릭터를 보내고 정확하게 다시 가져 오면 하드웨어가 올바르게 연결되어 있고 최소한 UART 레지스터 구성 세트가 올바른다는 것을 알고 있습니다.

2) 캐릭터 0x55 ( "U")를 반복적으로 전송 - 바이너리 비트 패턴 01010101을 사용하면 오실로스코프의 비트 너비를 빠르게 볼 수 있으므로 속도 설정이 올바른지 확인할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top