2013-10-20 55 views
2

我在stk500开发板上使用串行电缆连接到ubuntu上的atmega162芯片。 在atmega上,我初始化usart并写入一些字节。在Ubuntu端,东西出来的管道,但它绝对不是什么被发送...从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('!'); 

我用简单的python接收数据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

据我所知(在评论中已被怀疑),波特率计算是错误的。
尝试

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

什么

UBRR = 47 

结果为9600 @ 7372800MHz。

+0

问题不在于公式本身(我在avr库中发现它,所以我非常肯定它没关系),但转换为16位int。事实上,经过长时间的投入,我得到了47,一切正常。 – Bob

+0

@Bob:你说得对,演员是问题,但你的方程中的(8 *(long int)baud))部分是错误的。然而,这不是一个问题,因为它只是导致47.5,由于整数除法,它变成了47。 –

+0

就像我说过的:我在avr库中看到了这个技巧 - 它显然用于将结果四舍五入到最接近的整数值。换句话说,它是圆的(ubrr)而不是floor(ubrr)。 (事实上​​,当使用usart友好的时钟速率时,无论如何都没关系) – Bob