硬汉嵌入式论坛

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

[有问必答] 硬汉的uart的fifo程序疑惑

[复制链接]

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
发表于 2018-8-28 14:10:46 | 显示全部楼层 |阅读模式
为什么在读取数据个数,还有数据拷贝的时候要关掉中断?
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: UartSend
  4. *        功能说明: 填写数据到UART发送缓冲区,并启动发送中断。中断处理函数发送完毕后,自动关闭发送中断
  5. *        形    参:  无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen)
  10. {
  11.         uint16_t i;

  12.         for (i = 0; i < _usLen; i++)
  13.         {
  14.                 /* 如果发送缓冲区已经满了,则等待缓冲区空 */
  15.         #if 0
  16.                 /*
  17.                         在调试GPRS例程时,下面的代码出现死机,while 死循环
  18.                         原因: 发送第1个字节时 _pUart->usTxWrite = 1;_pUart->usTxRead = 0;
  19.                         将导致while(1) 无法退出
  20.                 */
  21.                 while (1)
  22.                 {
  23.                         uint16_t usRead;

  24.                         DISABLE_INT();
  25.                         usRead = _pUart->usTxRead;
  26.                         ENABLE_INT();

  27.                         if (++usRead >= _pUart->usTxBufSize)
  28.                         {
  29.                                 usRead = 0;
  30.                         }

  31.                         if (usRead != _pUart->usTxWrite)
  32.                         {
  33.                                 break;
  34.                         }
  35.                 }
  36.         #else
  37.                 /* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */
  38.                 while (1)
  39.                 {
  40.                         __IO uint16_t usCount;

  41. <font color="#ff0000">                        DISABLE_INT();
  42.                         usCount = _pUart->usTxCount;
  43.                         ENABLE_INT();</font>

  44.                         if (usCount < _pUart->usTxBufSize)
  45.                         {
  46.                                 break;
  47.                         }
  48.                 }
  49.         #endif

  50.                 /* 将新数据填入发送缓冲区 */
  51.                 _pUart->pTxBuf[_pUart->usTxWrite] = _ucaBuf[i];

  52. <font color="#ff0000">                DISABLE_INT();
  53.                 if (++_pUart->usTxWrite >= _pUart->usTxBufSize)
  54.                 {
  55.                         _pUart->usTxWrite = 0;
  56.                 }
  57.                 _pUart->usTxCount++;
  58.                 ENABLE_INT();</font>
  59.         }

  60.         USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE);
  61. }
复制代码

回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-8-28 14:11:35 | 显示全部楼层
本帖最后由 ssssssss 于 2018-8-28 14:13 编辑

DISABLE_INT();
usRead = _pUart->usTxRead;
ENABLE_INT();


                DISABLE_INT();
                if (++_pUart->usTxWrite >= _pUart->usTxBufSize)
                {
                        _pUart->usTxWrite = 0;
                }
                _pUart->usTxCount++;
                ENABLE_INT();

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
发表于 2018-8-28 14:12:56 | 显示全部楼层
因为串口中断里面也要操作到。
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-8-28 14:25:11 | 显示全部楼层
本帖最后由 ssssssss 于 2018-8-28 14:27 编辑
eric2013 发表于 2018-8-28 14:12
因为串口中断里面也要操作到。

在发送一帧数据的时候,USART_IT_TXE中断是关闭的,不可能去操作啊
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
发表于 2018-8-28 14:28:12 | 显示全部楼层
ssssssss 发表于 2018-8-28 14:25
在发送一帧数据的时候,USART_IT_TXE中断是关闭的,不可能去操作啊

比如你当前发送一批数据,发送空中断肯定是开启的,

如果你此时往FIFO里面添加新的数据,就会出冲突问题。
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-8-28 14:32:16 | 显示全部楼层
本帖最后由 ssssssss 于 2018-8-28 14:44 编辑
eric2013 发表于 2018-8-28 14:28
比如你当前发送一批数据,发送空中断肯定是开启的,

如果你此时往FIFO里面添加新的数据,就会出冲突问 ...

1那应该每个串口应该再加一个标志位,是否发送完成,或者装数据前检测一下_pUart->usTxCount,是否等于0.

2./* 当 _pUart->usTxBufSize == 1 时, 下面的函数会死掉(待完善) */
这个问题还有吗?



回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
发表于 2018-8-28 14:44:41 | 显示全部楼层
ssssssss 发表于 2018-8-28 14:32
1那应该每个串口应该再加一个标志位,是否发送完成,或者装数据前检测一下_pUart->usTxCount,是否等于0. ...

1、加标志位判断是否完成就失去了FIFO的意义。
2、这个没事,保证发送的数据量别超过FIFO大小即可。
回复

使用道具 举报

96

主题

297

回帖

585

积分

金牌会员

123

积分
585
 楼主| 发表于 2018-9-3 17:28:42 | 显示全部楼层
本帖最后由 ssssssss 于 2018-9-3 17:39 编辑
eric2013 发表于 2018-8-28 14:44
1、加标志位判断是否完成就失去了FIFO的意义。
2、这个没事,保证发送的数据量别超过FIFO大小即可。

static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen)
在发送数据的时候,先把数据放到发送缓冲区,然后 USART_ITConfig(_pUart->uart, USART_IT_TXE, ENABLE);打开了发送中断,但是此时没有给DR寄存器给数据,之后似乎不能产生TXE中断啊,非常疑惑,数据放到缓冲区就可以发送出来了吗?
难道是打开TXE后就立刻回产生一个中断,触发后面的发送?、


找到答案了
同时TXE或者TC,根据资料和测试的结果,TXE在复位后就是置1的,即在执行USART_ITConfig(USART1, USART_IT_TXE,  ENABLE)后会立即产生中断请求。因此这造成一个麻烦的问题:如果没有真正的发送数据,TXE中断都会发生,而且没有休止,这将占用很大部分的CPU时间,甚至影响其他程序的运行! 因此建议的是在初始化时不好启用TXE中断

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106997
QQ
发表于 2018-9-4 01:11:35 | 显示全部楼层
ssssssss 发表于 2018-9-3 17:28
static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen)
在发送数据的时候,先把数 ...

发送空中断,只有在有要发送的数据时才会开启,发送完毕后关闭。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-13 19:47 , Processed in 0.174826 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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