0

我正在尝试通过 Attiny167 的 uart 以 57600 的波特率在中断模式下获取数据,但是当我调试程序时,我只收到并且没有收到数据CRLF为什么它会在下面的控制器中发生是我的代码:

#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();

    }

请帮忙。

4

1 回答 1

0

你忘了在你的问题中提到一个非常重要的事情。何时调用您的 ISR?您在传入或传出字符上指定了中断,但您没有说明在读取或写入缓冲区时是否调用了 ISR,这确实有助于为您提供一些建议。

也就是说,假设 ISR 用于打印字符,问题似乎就在这里:

buff[i]=LINDAT;

当您的意思可能相反时:

LINDAT=buff[i];

因为这将在寄存器上写入一个字节,并且 tiny 应该在 uart 上自动转发它(在操作期间切换一些位,如 LBUSY 位,以帮助您不会溢出缓冲区)

也就是说,如果您看到打印的任何内容,我会感到惊讶,因为这个计算:

LINBRR = (((CPU_CLOCK_FREQ) / SAMPLES_PER_BIT) / BAUD_RATE) - 1;

给你很多舍入错误。您在这里没有将波特率设置为精确值(我通常在纸上计算值并直接输入精确数字),这可能是您检查是否看到打印出垃圾的下一个点(这意味着 ua​​rt 不是与接收器的时钟同步)。除此之外,波特率、时钟频率和每比特采样数(如果我没记错的话已经默认为 8)并没有经常变化,并且很难实现处理器或 uart 的软件超频(欠频),它完全需要。数据表应该有根据你的时钟计算 LINBRR 的公式。

最后,说几句个人话。57600波特是相当高的频率,你确定接收器能应付吗?速度非常快会使一切运行得非常快,但您也可能会在途中丢失一些角色。还要尽量避免以这种方式赋值:

DRA=0x02;

通常,这是一个更好的选择:

DDRA= (1<< DDA1) | (1<< DDA0 );

它使代码更具可读性和可维护性,以准确了解您正在设置哪些位以及它们的用途(您可以#def DDA1 & DDA0)。

PS如果你愿意缩小到19200,你可以这样做:

LINBRRL = 0x000C;

它在我的情况下确实有效,而且我的时钟频率也为 8MHz

于 2017-12-11T12:11:17.693 回答