硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2731|回复: 4
收起左侧

[有问必答] 请教硬汉bsp—esp8266,发出数据后等待反馈,有点不灵活

[复制链接]

11

主题

2

回帖

35

积分

新手上路

积分
35
发表于 2019-6-15 20:26:55 | 显示全部楼层 |阅读模式
裸机中,bsp—esp8266,发出数据后等待反馈,有点不灵活,有啥好法么?如系统中有多个while,有啥好法能不用等待,在主循环里查询处理。忘详解。谢谢。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107143
QQ
发表于 2019-6-15 21:59:24 | 显示全部楼层
QQ截图20190615215647.jpg
回复

使用道具 举报

5

主题

201

回帖

216

积分

高级会员

积分
216
发表于 2019-6-16 10:04:08 | 显示全部楼层
跑系统啊,freertos,硬汉代码都支持了。esp8266的任务跑一个单独的线程,等就等呗。
回复

使用道具 举报

3

主题

38

回帖

47

积分

新手上路

积分
47
发表于 2019-6-16 17:34:38 | 显示全部楼层

eric2013,您好!
      这样用还不是完全非阻塞,至少要等待一个timeout的时间,才跳出while循环;我们经过改造,在接收中断增加一个定时几个字符时间,然后封装一个comGetBuf的函数,调用这个函数,可以做到完全非阻塞。

uint16_t comGetBuf(COM_PORT_E _ucPort, uint8_t *_ucaBuf, uint16_t _usLen)
{
        TMR_E tmr_t;
    uint16_t i;
    uint8_t ucData;
   
    if(_ucPort == COM1)
    {
        tmr_t = U1_TMR;
    }
    else if(_ucPort == COM2)
    {
        tmr_t = U2_TMR;
    }
    else if(_ucPort == COM3)
    {
        tmr_t = U3_TMR;
    }
   
    if(bsp_timer_check(tmr_t))
    {
        for(i=0; i<_usLen; i++)
        {
            if(comGetChar(_ucPort, &ucData))
            {
                _ucaBuf = ucData;
            }
            else
            {
                //清空数据
                comClearRxFifo(_ucPort);
                return i;
            }
        }
    }
   
    return 0;
}


static void UartIRQ(UART_T *_pUart)
{
    TMR_E tmr_t;
        /* 处理接收中断  */
        if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
        {
                /* 从串口接收数据寄存器读取数据存放到接收FIFO */
                uint8_t ch;

                ch = USART_ReceiveData(_pUart->uart);
                _pUart->pRxBuf[_pUart->usRxWrite] = ch;
                if (++_pUart->usRxWrite >= _pUart->usRxBufSize)
                {
                        _pUart->usRxWrite = 0;
                }
                if (_pUart->usRxCount < _pUart->usRxBufSize)
                {
                        _pUart->usRxCount++;
                }

                /* 回调函数,通知应用程序收到新数据,一般是发送1个消息或者设置一个标记 */
                //if (_pUart->usRxWrite == _pUart->usRxRead)
                //if (_pUart->usRxCount == 1)
                {
                        if (_pUart->ReciveNew)
                        {
                                _pUart->ReciveNew(ch);
                        }
                }
        
        if(_pUart->uart == USART1)
        {
            tmr_t = U1_TMR;
        }
        else if(_pUart->uart == USART2)
        {
            tmr_t = U2_TMR;
        }
        else if(_pUart->uart == USART3)
        {
            tmr_t = U3_TMR;
        }
        
        bsp_timer_star_once(tmr_t, 30);
        }

        /* 处理发送缓冲区空中断 */
        if (USART_GetITStatus(_pUart->uart, USART_IT_TXE) != RESET)
        {
                //if (_pUart->usTxRead == _pUart->usTxWrite)
                if (_pUart->usTxCount == 0)
                {
                        /* 发送缓冲区的数据已取完时, 禁止发送缓冲区空中断 (注意:此时最后1个数据还未真正发送完毕)*/
                        USART_ITConfig(_pUart->uart, USART_IT_TXE, DISABLE);

                        /* 使能数据发送完毕中断 */
                        USART_ITConfig(_pUart->uart, USART_IT_TC, ENABLE);
                }
                else
                {
                        /* 从发送FIFO取1个字节写入串口发送数据寄存器 */
                        USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
                        if (++_pUart->usTxRead >= _pUart->usTxBufSize)
                        {
                                _pUart->usTxRead = 0;
                        }
                        _pUart->usTxCount--;
                }

        }
        /* 数据bit位全部发送完毕的中断 */
        else if (USART_GetITStatus(_pUart->uart, USART_IT_TC) != RESET)
        {
                //if (_pUart->usTxRead == _pUart->usTxWrite)
                if (_pUart->usTxCount == 0)
                {
                        /* 如果发送FIFO的数据全部发送完毕,禁止数据发送完毕中断 */
                        USART_ITConfig(_pUart->uart, USART_IT_TC, DISABLE);

                        /* 回调函数, 一般用来处理RS485通信,将RS485芯片设置为接收模式,避免抢占总线 */
                        if (_pUart->SendOver)
                        {
                                _pUart->SendOver();
                        }
                }
                else
                {
                        /* 正常情况下,不会进入此分支 */

                        /* 如果发送FIFO的数据还未完毕,则从发送FIFO取1个数据写入发送数据寄存器 */
                        USART_SendData(_pUart->uart, _pUart->pTxBuf[_pUart->usTxRead]);
                        if (++_pUart->usTxRead >= _pUart->usTxBufSize)
                        {
                                _pUart->usTxRead = 0;
                        }
                        _pUart->usTxCount--;
                }
        }
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107143
QQ
发表于 2019-6-17 08:47:32 | 显示全部楼层
也许在明天 发表于 2019-6-16 17:34
eric2013,您好!
      这样用还不是完全非阻塞,至少要等待一个timeout的时间,才跳出while循环;我们 ...

谢谢分享。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-20 10:49 , Processed in 0.248943 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表