OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9269|回复: 23

stm32f429串口中断接收 PC串口工具发送的字符串 会丢失

[复制链接]

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
发表于 2014-6-4 17:44:33 | 显示全部楼层 |阅读模式
5金钱
在接收PC串口工具发来的字符串时  大多会丢失后面的数据  收到的 为连续的数据  而且 奇怪的是  收到多少个字符  实际检测到  接收中断触发的次数就是接收到字符的个数,
中断为什么触发次数不够?中断处理函数很简洁  一点不累赘  无延迟等,哪位大神  能指点迷津

最佳答案

查看完整内容[请看2#楼]

回复【15楼】正点原子: --------------------------------- 感谢版主  问题已解决  谢谢帮助  问题就是上面说的  两个函数都读取CR寄存器 的原因
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-4 17:44:34 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
感谢版主  问题已解决  谢谢帮助  问题就是上面说的  两个函数都读取CR寄存器 的原因
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-4 17:52:14 | 显示全部楼层
不能沉啊   大神快来啊   我顶
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-4 18:01:51 | 显示全部楼层
再顶  大神不来一直顶
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-4 18:17:48 | 显示全部楼层
感觉  板子接收中断响应结束 执行代码时  C的发送中断未执行完,在下一个循环开始时  会补上上次缺少的字符(补的不全,只能补一到两位,剩余丢失,后面接着新的开始)
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-4 22:44:35 | 显示全部楼层
中断次数,等于发送数据个数,说明你的中断接收没有丢失,问题可能出现在传输过程之中,比如数据本身就发生了错误,这种情况,考虑硬件是不是有问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 10:46:59 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
公司两块板子 都一样;老大说  可能是驱动配置有问题(接收几个字符触发一次中断,或是接收到buff里没有读出来),我觉得不合理啊!
429 能设置接收几个字符一次中断吗?有可能接收完了 还存在buff里  我看了 手册  寄存器只说 接收非空触发接收中断  未写明几个字符一次中断啊   也没有写缓存8/16/..../bit的  设置  请问有这设置吗
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 11:07:49 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
亲  能发给串口接收例程给我么  感谢!!!675299413@qq.com
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 17:28:41 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
接收中断结束后,丢失的下一个字符 在DR寄存器中  例如  C串口发送@D6123456   接收到@D61234   接收中断实际响应7次  但这时候读DR寄存器里的值  是字符'5'    也就是下一个字符 寄存器已经收到了  但未触发接收中断   有时候下次循环还能接收到'5'  有时候接收不到    都两天了 一点进展没有  愁死了
回复

使用道具 举报

230

主题

1950

帖子

10

精华

论坛元老

Rank: 8Rank: 8

积分
4562
金钱
4562
注册时间
2010-12-14
在线时间
32 小时
发表于 2014-6-5 18:16:19 | 显示全部楼层
那应该是你的程序逻辑问题吧?
7个中断7次响应,说明没有问题。
我是开源电子网?网站管理员,对网站有任何问题,请与我联系!QQ:389063473Email:389063473@qq.com
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 18:33:12 | 显示全部楼层
回复【9楼】Admin:
---------------------------------
串口发的 是9个字符  应该是9个中断啊  
逻辑程序有问题?能给个接收串口的  接收逻辑代码吗  我现在  什么都怀疑了
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 18:33:25 | 显示全部楼层
回复【9楼】Admin:
---------------------------------
谢谢!!!
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 18:36:45 | 显示全部楼层
回复【9楼】Admin:
--------------------------------
while (USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET);
do
{
     i = comGetChar(COM4,&buff[j]);
     j++;
}while(i&&(j<180));//(buff 大小 180)

uint8_t comGetChar(COM_PORT_E _ucPort, uint8_t *_pByte)
{
UART_T *pUart;

pUart = ComToUart(_ucPort);
if (pUart == 0)
{
return 0;
}

return UartGetChar(pUart, _pByte);
}



static uint8_t UartGetChar(UART_T *_pUart, uint8_t *_pByte)
{
uint16_t usCount;

/* usRxWrite 变量在中断函数中被改写,主程序读取该变量时,必须进行临界区保护 */
DISABLE_INT();
usCount = _pUart->usRxCount;
ENABLE_INT();

/* 如果读和写索引相同,则返回0 */
//if (_pUart->usRxRead == usRxWrite)
if (usCount == 0) /* 已经没有数据 */
{
return 0;
}
else
{
*_pByte = _pUart->pRxBuf[_pUart->usRxRead]; /* 从串口接收FIFO取1个数据 */

/* 改写FIFO读索引 */
DISABLE_INT();
if (++_pUart->usRxRead >= _pUart->usRxBufSize)
{
_pUart->usRxRead = 0;
}
_pUart->usRxCount--;
ENABLE_INT();
return 1;
}
}
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 18:38:32 | 显示全部楼层

下面是 中断处理函数

回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-5 18:40:21 | 显示全部楼层
回复【9楼】Admin:
---------------------------------
*********************************************************************************************************
* 函 数 名: UartIRQ
* 功能说明: 供中断服务程序调用,通用串口中断处理函数
* 形    参: _pUart: 串口设备
* 返 回 值: 无
*********************************************************************************************************
*/
static void UartIRQ(UART_T *_pUart)
{
/* 处理接收中断  */
if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)
           {
                jishu++;
/* 从串口接收数据寄存器读取数据存放到接收FIFO */
_pUart->pRxBuf[_pUart->usRxWrite] = USART_ReceiveData(_pUart->uart);
if (++_pUart->usRxWrite >= _pUart->usRxBufSize)
{
_pUart->usRxWrite = 0;
}
if (_pUart->usRxCount < _pUart->usRxBufSize)
{
_pUart->usRxCount++;
}

                USART_ClearITPendingBit(_pUart->uart,USART_IT_RXNE);//add 2014 6 3
}
        
        /* 处理发送缓冲区空中断 */
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--;
}
}
}
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-6 00:31:45 | 显示全部楼层
回复【8楼】kmjvs:
---------------------------------
这比较奇怪,407的代码就有,429的没用过。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-6 10:33:19 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
我用407的  问题一样   你能发一份你的407的  demon给我么!675299413@qq.com   谢谢
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-6 14:18:00 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
版主  你看是不是这种原因  
串口中断函数里 有判断接收或发送中断  if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET) 
函数读取了CR寄存器中的RXNE 位  
而我写的接收逻辑代码中  在接收串口字符串前 有 while (USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET); 
函数同样读取了CR寄存器中的RXNE位 导致进入中断后  无法进入接收中断  
我实际测了一下  发送9个字符  接收到5个   接收中断响应了5次   而串口中断响应了6次(发送中断已除去),就是后面一次接收中断进入了  但
if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)条件为满足  中断未做任何处理  导致DR寄存器是丢失的第六个字符(查看寄存器得到的),但为接收到;
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-6 14:18:31 | 显示全部楼层
回复【9楼】Admin:
---------------------------------
版主  你看是不是这种原因   
串口中断函数里 有判断接收或发送中断  if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)  
函数读取了CR寄存器中的RXNE 位   
而我写的接收逻辑代码中  在接收串口字符串前 有 while (USART_GetFlagStatus(UART4, USART_FLAG_RXNE) == RESET);  
函数同样读取了CR寄存器中的RXNE位 导致进入中断后  无法进入接收中断   
我实际测了一下  发送9个字符  接收到5个   接收中断响应了5次   而串口中断响应了6次(发送中断已除去),就是后面一次接收中断进入了  但 
if (USART_GetITStatus(_pUart->uart, USART_IT_RXNE) != RESET)条件为满足  中断未做任何处理  导致DR寄存器是丢失的第六个字符(查看寄存器得到的),但为接收到;
回复

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-6-4
在线时间
0 小时
 楼主| 发表于 2014-6-6 15:02:54 | 显示全部楼层
回复【9楼】Admin:
--------------------------------
感谢版主  问题已解决  谢谢帮助  问题就是上面说的  两个函数都读取CR寄存器 的原因
回复

使用道具 举报

81

主题

1002

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1876
金钱
1876
注册时间
2014-9-10
在线时间
208 小时
发表于 2015-9-5 15:05:27 | 显示全部楼层
楼主怎么解决的?
小小蜗牛
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2016-4-17
在线时间
0 小时
发表于 2016-4-17 07:36:46 | 显示全部楼层
看一看
回复

使用道具 举报

3

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2016-7-15
在线时间
25 小时
发表于 2017-3-17 12:49:58 | 显示全部楼层
好奇怪,楼主能发一份串口中断接收字符串的代码给我吗?751191958@qq.com谢谢
我的情况很奇怪,这么写
oid USART1_IRQHandler(void)
{

  uint8_t ch;

        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//2úéú&#214;D&#182;&#207;
        {

   
    ch=(USART_ReceiveData(USART1))&0XFF;                                                                                        //&#182;áè&#161;êy&#190;Y&#214;ách
   
               
    j=j+1;//êy×é&#207;&#194;±ê
               
  }
        BFT[j-1]=ch;
        printf("%c",BFT[j-1]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
回复

使用道具 举报

3

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2016-7-15
在线时间
25 小时
发表于 2017-3-17 12:52:50 | 显示全部楼层
751191958 发表于 2017-3-17 12:49
好奇怪,楼主能发一份串口中断接收字符串的代码给我吗?谢谢
我的情况很奇怪,这么写
oid USART1_IRQHand ...

我尝试着从pc发数据,然后通过中断返回将PC接收到的数据存进数组里,并且输出,结果是正确的,我发什么,中断接收返回什么,
但是后来我在主函数判断数据帧的却出现这种情况

我第一次从PC发的数据正确了,第二帧就没用了,根本就没存进数组里面去,返回输出的结果跟第一次从PC发存进数组的数据一样
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 21:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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