2013-10-20 7 views
2

시리얼 케이블로 우분투에 연결된 stk500 dev 보드에 atmega162 칩이 있습니다. atmega에서 usart를 초기화하고 몇 바이트를 씁니다. 우분투 측에서는 무언가가이 파이프에서 나옵니다.하지만 정확히 무엇이 보내 졌는지는 알 수 없습니다.AVR USART 전송에서 깨진 데이터 읽기

더 정확하게 말하면, 전송 된 각 바이트에 대해 각각 약 6 또는 7 바이트의 일련 번호를 갖습니다. 0x00 또는 0xC0 값을가집니다. 내 코드의

관련 조각 :

컴파일 플래그 :

CFLAGS = -g 
CFLAGS += -mmcu=atmega162 
CFLAGS += -W -Wall -Wshadow 
CFLAGS += -Os 
CFLAGS += -mcall-prologues 
CFLAGS += -finline-limit=10 
CFLAGS += -mno-interrupts 
CFLAGS += -ffunction-sections 
CFLAGS += -DF_CPU=7372800ULL 

USART 기능 :

void Serial0Init(int baud) 
{ 
     unsigned int ubrr; 

     ubrr = ((F_CPU+8*baud)/(16*baud))-1; 
     // Baud rate 
     UBRR0H = (unsigned char)(ubrr>>8); 
     UBRR0L = (unsigned char)ubrr; 
     UCSR0A &= ~(1 << U2X0); // U2X off 
     // Transmission settings 
     UCSR0C = (1<<URSEL0)|(3<<UCSZ00);  // 8N1 
     UCSR0B = (1<<RXEN0)|(1<<TXEN0); 
} 

unsigned char Serial0CheckTxReady() 
{ 
     return (UCSR0A&_BV(UDRE0));  // nonzero if transmit register is ready to receive new data. 
} 

void Serial0Write(unsigned char data) 
{ 
     while (Serial0CheckTxReady()==0)  // while NOT ready to transmit 
       {} 
     UDR0 = data; 
} 

주요 코드 : 나는 간단한 파이썬으로 데이터를 수신

Serial0Init(9600); 
Serial0Write('!'); 

scr ipt :

import serial 
import os 

port = serial.Serial('/dev/ttyS0', 9600) 

print 'Reading from serial...' 
while True: 
    c = port.read() 
    print c, ord(c) 

두 번 확인 된 바이트 크기 설정과 전송 속도 계산은 모두 괜찮은 것 같습니다. 어떤 아이디어가 잘못 되었나요?

+1

이 문제는 확실히 전송 속도 문제와 유사합니다. MCU가 7.372 MHz로 실행되고 있습니까? 클럭 소스의 퓨즈 설정을 확인하는 것이 좋습니다. 외부 오실레이터가 클럭 소스로 선택되면 설정도 확인해야합니다 (예 : STK500 클럭 생성기 주파수). 또한 Atmega161 호환 퓨즈를 점검하십시오. Atmega162 용으로 컴파일하는 동안 부작용을 방지하기 위해 호환 모드를 비활성화해야합니다. –

+1

또한'ubrr' 계산에 사용 된 표현식을 확인하십시오. sizeof (int) == 2로 계산하면 오버플로가 발생하여 잘못된 결과가 발생할 수 있습니다. 테스트 목적으로 'UBRR0'값을 하드 코딩하는 것이 좋습니다. –

+0

자, 힌트가 도움이되었습니다. 나는 그 문제를 발견했다. 참으로 전송 속도 계산이었습니다. 고정 공식은 다음과 같습니다 : ubrr = ((F_CPU + 8 * (long int) baud)/(16 * (long int) baud)) - 1; – Bob

답변

1

내가 말할 수있는 한 (그리고 의견에서 이미 의심 스러웠다.) 전송 속도 계산은 잘못되었다.
는 7372800MHz @ 9600에 대한

UBRR = 47 

에서

UBRR = ((fOSC/(16 * BAUD)) - 1 

어떤 결과를보십시오.

+0

문제는 수식 자체와 관련이 없습니다 (나는 avr 라이브러리에서 찾았으므로 괜찮 았음).하지만 16 비트 정수로 변환하면 문제가되지 않습니다. 그리고 실제로, long int로 캐스팅 한 후에, 나는 47을 얻었고 모든 것이 잘 작동합니다. – Bob

+0

@Bob : 캐스트가 문제이지만, 방정식의 (8 * (long int) 보)) 부분이 잘못되었습니다. 그러나 이것은 47.5로 끝나기 때문에 문제가되지 않습니다. 정수 나누기 때문에 47이됩니다. –

+0

내가 말했듯이, avr 라이브러리에서이 트릭을 보았습니다. 결과를 가장 가까운 정수 값으로 반올림하는 데 분명히 사용되었습니다. 즉, 바닥 (ubrr) 대신 라운드 (ubrr)를 수행합니다. (실제로 usart 친화적 인 클럭 속도를 사용하면 어쨌든 중요하지 않습니다.) – Bob