首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在全双工功能中使用usart

在全双工功能中使用usart
EN

Stack Overflow用户
提问于 2015-03-02 18:55:18
回答 1查看 391关注 0票数 1

我想使用我的Atxmega-µC的USART-functionality。因此,我研究了usart-example作为第一步。它的设计目的是获取一个char,然后再将其发送回来。

代码语言:javascript
复制
while (true) {
        received_byte = usart_getchar(USART_SERIAL_EXAMPLE);
        if (received_byte == '\r') {
            for (i = 0; i < tx_length; i++) {
                usart_putchar(USART_SERIAL_EXAMPLE, tx_buf[i]);
            }
        } else
            usart_putchar(USART_SERIAL_EXAMPLE, received_byte);
    }

我想知道这是不是一个并行进程(看起来不是),如果我想要真正并行地发送和接收数据,我应该如何重构这段代码,而不是按顺序显示在上面的示例代码中。

理论上(到目前为止还没有测试)将其分成几个线程不会改善这种情况,因为µC只是“单核”。有没有其他方法可以通过USART并行发送和接收数据?

EN

回答 1

Stack Overflow用户

发布于 2015-04-20 07:49:41

你不能实现真正的并行性。我使用Atmel UC3做了一个类似的设计,但我从一个随机的XMega数据表中提取,以确认它们至少看起来很相似,但没有太多细节。没有单独的缓冲区用于读取和写入。查看寄存器描述:

发送和接收共享数据寄存器。话虽如此,仍然可以使用中断和FIFO将全双工设计为“接近”并行。请看下面的代码:

代码语言:javascript
复制
static void usart_int_handler(void)
{
    int result;
    while (PS_USART->csr & RX_READY)
    {
        result = fifo_push_byte(&PS_FIFO, PS_USART->rhr);
        if (result == FIFO_ERROR_OVERFLOW)
        {
            fifo_flush(&PS_FIFO);
            break;
        }
    }
    int parity_error = usart_parity_error(PS_USART);
    int framing_error = usart_framing_error(PS_USART);
    int overrun_error = usart_overrun_error(PS_USART);
    if ( parity_error || framing_error || overrun_error )
    {
        // Clear out FIFO and reset errors.
        // Then exit out and let calling object
        // timeout.
        while (PS_USART->csr & RX_READY)
        {
            result = PS_USART->rhr;
        }
        fifo_flush(&PS_FIFO);
        usart_reset_status(PS_USART);
        return;
    }
}

可以轮询FIFO,也可以设置中断,表明FIFO已达到数据阈值。我以这种方式处理传输:

代码语言:javascript
复制
void write_ps_serial (volatile avr32_usart_t *usart, const unsigned char *string, int size)
{
    // When using this - we needed a software workaround
    // to set and reset RTS pin.  Operation of RTS is not
    // correct.
    Disable_global_interrupt();
    gpio_set_pin_high(PS_RTS_PIN);
    for (int index = 0 ; index < size ; index++)
    {
        usart_putchar(usart, string[index]);
    }
    while ( (PS_USART->csr & TX_EMPTY) == 0 )
    {
        // Sit here waiting for the channel
        // status register to indicate TX_EMPTY
        // has gone high which means we can shut
        // off RTS.
    }
    gpio_clr_gpio_pin(PS_RTS_PIN);  
    Enable_global_interrupt();
}

我仍然认为硬件中有一些东西可以防止冲突。尽管我检查了错误,但我让模拟器开了3天,同时不断地与总线通信,从未收到过一次错误。但您肯定需要对自己的协议进行编码,以处理丢弃的数据包或使用更严格的RS232控制(此代码用于全双工485)。我有更多的代码,如果你愿意。我希望这能帮到你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28808026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档