在ISR()内将UART1与UART2中继(PIC24H)

时间:2015-03-25 14:53:42

标签: c microcontroller pic

我正在编写PIC24H系列的微控制器并使用xc16编译器。

我正在main()内将U1RX数据转发给U2TX,但是当我在ISR中尝试它时它不起作用。

我正在向U1RX发送命令,ISR()在下面。在U2RX,有数据库不断进入,我想用U1TX中继其中的500个。结果是U1TX正在从U2RX中继前4个数据字节,然后一遍又一遍地重新发送第4个字节。

当我将下面的for循环复制到我的main()时,一切正常。在ISR()中,它类似于U2RX的相应FIFO缓冲区在读取时不会清零,因此缓冲区溢出并停止将更多输入数据读取到U2RX。如果有人能告诉我如何解决这个问题,我真的很感激。变量tmpcommand是全局声明的。

void __attribute__((__interrupt__, auto_psv, shadow)) _U1RXInterrupt(void)
{
    command = U1RXREG;
    if(command=='d'){
        for(i=0;i<500;i++){
            while(U2STAbits.URXDA==0);
            tmp=U2RXREG;
            while(U1STAbits.UTXBF==1); //
            U1TXREG=tmp;
           }
    }
}

编辑:我在ISR()中添加了第一行。

2 个答案:

答案 0 :(得分:2)

试图从各种评论中得出答案。

如果main()没有其他任何事情可做,并且没有其他中断,那么您可能能够&#34;逃避&#34;在第一次中断发生后,在中断时将所有500个字符从一个UART修补到另一个UART,这可能是一个很有用的练习。

但那不是你应该如何使用中断。如果你在main()中有其他任务,并且优先级相同或更低,那么这个中断需要相对较长的时间(500个字符,9600波特=半秒)将使处理器被称为&#34 ;中断绑定&#34;,即其他进程被冻结。

由于您的项目变得复杂,您不希望将main()限制为此任务,并且在设置UART和IRQ之后根本不需要参与该任务。之后,如果您愿意,可以无限制地计算π

我对你的操作顺序感到有点困惑。从U1收到命令'd',告诉您从U2到U1修补500个字符。

我建议解决这个问题的一种方法(也有很多)看到你真的想要使用中断,就是等到从U1收到命令 - 在main()中。然后,在U2上为RXD配置和启用中断。

然后,ISR的工作是从U2接收数据并通过U1传输。如果两个UARTS具有相同的时钟和相同的波特率,则不应存在同步问题,因为UART通常在内部进行缓冲:一旦开始发送,TXD寄存器就可以保存另一个字符,因此任何停滞都是ISR应该是最小的。

我无法为您编写实际代码,因为它应该可以正常工作,但这里有一些非常伪代码,而且我没有PIC方便(或希望研究其运作细节)。

ISR
    has been invoked because U2 has a char RXD
    you *might* need to check RXD status as a required sequence to clear the interrupt
    read the RXD register, which also might clear the interrupt status
    if not, specifically clear the interrupt status
    while (U1 TXD busy);
    write char to U1
    if (chars received == 500)
        disable U2 RXD interrupt
    return from interrupt

答案 1 :(得分:1)

如果有希望跟上UART上的缓冲区,那么ISR的必须保持精益和意味着代码变得超高效。尝试使用BAUD率只是为了找到代码可以跟上的点,以帮助发现正确的启发式方法,并了解您实现目标的距离。

成功可能取决于您的微控制器的速度,以及它运行的任务数量。如果微控制器理论上具有内置UART,则应该能够管理保持FIFO不溢出。另一方面,如果您将UART与功率不足的微控制器配对,您可能无法优化解决问题的方法。

除了建议将较低优先级的工作卸载到主线程并保持ISR快速(在评论中有人制作)之外,您还需要仔细查看所有代码行的时间并尝试每个书中的技巧让他们跑得更快。一个昂贵的指令可能会破坏你的一整天,所以在找到节省时间的方法时,真正的创意。

编辑:要考虑的另一件事 - 查看C编译器创建的汇编语言。一个好的编译器应该允许您内联汇编语言指令,以允许您针对特定情况进行超级优化。通常在ISR中,您只需要查找和实施少量指令。

编辑2:如果您正确编码并选择快速振荡器或晶振并以良好的时钟速率运行芯片,则PIC 24系列应足够快。还要考虑UART可能用于实现其速率与PIC时钟速率的除数。可以想象(对我而言)可以通过移位在内部完成的均匀划分优于需要数学的划分。