我试图通过utin of Attiny167获取数据,在波特率为57600的中断模式下但是当我调试程序时我只收到CR
& LF
我收到的没有数据为什么在下面的控制器中发生的是我的代码:
#define CPU_CLOCK_FREQ 8000000UL
#define SAMPLES_PER_BIT 8
#define BAUD_RATE 57600
ISR(LIN_TC_vect)
{
cli();
temp=LINDAT;
buff[i]=temp;
i++;
sei();
}
void USARTInit()
{
DDRA = 0x02; // Port A Rx / Tx as input / output for PIN0 and PIN1
/* Set PORTB as input from FACS MAin BOX on PIN0 and PIN1 , initially high */
DDRB = 0x00;
PORTB= 0xFF;
/* Set samples per bit and UART baud */
LINBTR = (1 << LDISR) | SAMPLES_PER_BIT;
LINBRR = (((CPU_CLOCK_FREQ) / SAMPLES_PER_BIT) / BAUD_RATE) - 1;
/* Configure LIN UART in UART mode */
LINCR = (1 << LENA) | (1 << LCMD0) | (1 << LCMD1) | (1 << LCMD2);
// enable transmit and recieve interrupts for LIN/UART transfer
LINENIR = (1 << LENRXOK);
sei();
}
请帮忙。
答案 0 :(得分:0)
你忘了在你的问题中提到一件非常重要的事情。你的ISR被叫?您在传入或传出的字符上指定了中断,但是您没有说在读取或写入缓冲区时是否调用了ISR,这对您提供一些建议非常有帮助。
也就是说,假设ISR用于打印字符,问题似乎就在这里:
buff[i]=LINDAT;
当你可能意味着相反时:
LINDAT=buff[i];
因为这将在寄存器上写入一个字节,而tiny应该在uart上自动转发它(在操作期间切换一些位,比如LBUSY,以帮助你不要溢出缓冲区)
那就是说,如果你会看到任何印刷品,我会感到惊讶,因为这个计算:
LINBRR = (((CPU_CLOCK_FREQ) / SAMPLES_PER_BIT) / BAUD_RATE) - 1;
给你很多舍入错误。您没有在这里将波特率设置为精确值(我通常在纸上计算值并直接输入精确数字),这可能是您检查是否看到垃圾打印出来的下一个点(这意味着uart不是与接收器的时钟同步)。除此之外,波特率,时钟频率和每位采样(如果我没记错的话,已经默认为8)不会频繁变化,并且难以实现处理器或uart的软件超时(欠)时钟,它完全需要。数据表应该有基于你的时钟计算LINBRR的公式。
最后,一些个人言论。 57600波特是一个相当高的频率,你确定接收器能够应付吗?快速运行使一切运行得非常快,但在途中也可能会丢失一些字符。还要尽量避免以这种方式分配值:
DRA=0x02;
通常情况下,这是一个更好的选择:
DDRA= (1<< DDA1) | (1<< DDA0 );
它使代码更具可读性和可维护性,以确切地知道您正在设置哪些位以及它们应该做什么(您可以#def DDA1&amp; DDA0)。
PS如果你愿意缩小到19200,你可以这样做:
LINBRRL = 0x000C;
它确实在我的情况下工作,我也在8MHz时钟