Atiny167控制器中的Uart问题

时间:2017-11-08 06:35:36

标签: embedded avr uart attiny

我试图通过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();

    }

请帮忙。

1 个答案:

答案 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时钟