OpenEdv-开源电子网

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

关于串口通信,求大佬,解释一下

[复制链接]

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
发表于 2020-7-17 17:16:18 | 显示全部楼层 |阅读模式
10金钱
程序、串口接收数据如图片,问题:多次发送数据会导致接收数据不对。

捕获.PNG
捕获.PNG1.PNG
捕获.PNG2.PNG
捕获.PNG4.PNG
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

68

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4128
金钱
4128
注册时间
2016-7-22
在线时间
580 小时
发表于 2020-7-17 19:45:29 | 显示全部楼层
不要在接收中断里发送数据,建议使用空闲中断
回复

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4480
金钱
4480
注册时间
2013-4-22
在线时间
337 小时
发表于 2020-7-18 11:26:36 | 显示全部楼层
接收中断发送数据,这是要闹哪样,接收、发送中断要分开写
回复

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2020-7-19 21:41:27 | 显示全部楼层
接收和发送都加缓存
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 08:47:15 | 显示全部楼层
冻结的鱼 发表于 2020-7-17 19:45
不要在接收中断里发送数据,建议使用空闲中断

分开写,发送和接受的数据不一致,不明白
捕获.PNG
捕获.PNG1.PNG
捕获.PNG3.PNG
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 09:13:05 | 显示全部楼层
三叶草 发表于 2020-7-18 11:26
接收中断发送数据,这是要闹哪样,接收、发送中断要分开写

分开写了,但还是发送和接受的数据不一致
捕获.PNG
捕获.PNG1.PNG
捕获.PNG3.PNG
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 09:14:35 | 显示全部楼层
冻结的鱼 发表于 2020-7-17 19:45
不要在接收中断里发送数据,建议使用空闲中断

分开写还是导致发送和接受的不一致
捕获.PNG
捕获.PNG1.PNG
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-7-20 09:30:16 | 显示全部楼层
pace123456 发表于 2020-7-20 09:14
分开写还是导致发送和接受的不一致

你在接收中断设置个标志位flag,当产生中断时,flag=1,然后在主函数中while循环,
if(flag==1){发送接收到的字节,不是数组,因为串口每接收到一个字节都会产生中断,
flag=0;}
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 11:49:11 | 显示全部楼层
liaohaijian 发表于 2020-7-20 09:30
你在接收中断设置个标志位flag,当产生中断时,flag=1,然后在主函数中while循环,
if(flag==1){发送 ...

这样改是吧,但串口一直在返回数
捕获.PNG
捕获.PNG1.PNG
回复

使用道具 举报

2

主题

68

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4128
金钱
4128
注册时间
2016-7-22
在线时间
580 小时
发表于 2020-7-20 14:32:52 | 显示全部楼层
pace123456 发表于 2020-7-20 09:14
分开写还是导致发送和接受的不一致

根据你要接收的数据,接收到数据的最后一位了,置一个标志位,再在主程序里面判断标志位来发送数据。
回复

使用道具 举报

2

主题

68

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4128
金钱
4128
注册时间
2016-7-22
在线时间
580 小时
发表于 2020-7-20 14:34:50 | 显示全部楼层
pace123456 发表于 2020-7-20 11:49
这样改是吧,但串口一直在返回数

flag 不是在每一次接收到数据都要置位,在你接收的数据完成了再置位
主程序判断flag 发送完成后把flag清掉。
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-7-20 15:13:45 | 显示全部楼层
pace123456 发表于 2020-7-20 11:49
这样改是吧,但串口一直在返回数

不是啊,中断服务函数flag=1要放在if(){}内啊,然后主函数if(flag==1){
flag=0;

.....
......
}
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 17:23:23 | 显示全部楼层
冻结的鱼 发表于 2020-7-20 14:34
flag 不是在每一次接收到数据都要置位,在你接收的数据完成了再置位
主程序判断flag 发送完成后把flag清 ...

是这样吗
捕获.PNG
捕获.PNG1.PNG
回复

使用道具 举报

2

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
180
金钱
180
注册时间
2019-10-29
在线时间
47 小时
 楼主| 发表于 2020-7-20 17:24:05 | 显示全部楼层
liaohaijian 发表于 2020-7-20 15:13
不是啊,中断服务函数flag=1要放在if(){}内啊,然后主函数if(flag==1){
flag=0;

是这样吗

捕获.PNG
捕获.PNG1.PNG
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-7-20 17:48:04 | 显示全部楼层

flag=0放到if里面啊
回复

使用道具 举报

34

主题

255

帖子

0

精华

高级会员

Rank: 4

积分
912
金钱
912
注册时间
2019-7-5
在线时间
189 小时
发表于 2020-7-20 17:48:38 | 显示全部楼层

flag为全局变量
回复

使用道具 举报

2

主题

68

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4128
金钱
4128
注册时间
2016-7-22
在线时间
580 小时
发表于 2020-7-20 20:28:33 | 显示全部楼层

不是的,你截图中你的接收是接收到一个数据就置flag,但是你发送的时候发的都是当前的RX_SAT的长度值(每接收一次就加1,不知道你有没有做最大值限制);
你可以这么做,假设你要接收的数据总长度是X  那么你可以if (RX_SAT>X){RX_SAT=0;flag=true},然后再在while里面用FOR发送X的长度,这样就是接收到X长度,发送一次;
回复

使用道具 举报

1

主题

11

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2020-6-23
在线时间
4 小时
发表于 2020-7-20 20:37:14 | 显示全部楼层
数据发送与接收。 STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是
一个双寄存器,包含了 TDR 和 RDR 。当向该寄存器写数据的时候,串口就会自动发送,当收
到 数据 的时候,也是存在该寄存器内的。

所以你一边读值一边写值不出问题才怪。

有两个办法尝试一下:
1. 收,发用不同的串口。如下图, USART2负责收,UART1负责发。我调试芯片的通断就用这个
void USART2_IRQHandler(void)                       
{
        int8_t Res;
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {
                        Res=USART_ReceiveData(USART2);
                        UART1_send_byte(Res);  
        }
}   
2. 如果收,发必须用一个串口,那就错开时间。
   void USART3_IRQHandler(void)                       
{
        int8_t Res;
        if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
        {
                        Res=USART_ReceiveData(USART3);
                        if(RX_STAT <200) RX_BUF(RX_STAT++)=Res//如果收到的程序大于等于200,就停止接收
        }
}     

主程序
while(1)
        {
                        if(RX_STAT >=200)
                          {
                             第一步:重新配置串口,关闭接收功能,和接收中断
                             第二步,发送数据
                            第三部,重新配置串口,打开接收功能,和接收中断
                          第四步, RX_STAT =0;重新开始一轮。
                            }
                       
        }

3. 就是楼上有提到的,用空闲中断,USART_IT_IDLE,开这个中断。当总线空闲了,在执行发送任务。 记得查查怎么用这个中断。
回复

使用道具 举报

0

主题

37

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1161
金钱
1161
注册时间
2018-5-24
在线时间
120 小时
发表于 2020-7-20 23:02:14 | 显示全部楼层
接收中断处理时间太长,电脑端发过来的数据应该溢出了,所以返回不正确。可以像楼上第二种办法用的比较多,接收发送错开时间。还有一种是办法是,建立多个接收缓存区,第一个缓存区用了,就存第二个,在第一个缓存区内容发送的时候用第二个缓存区接收数据,这样接收发送就能同时使用。像CAN的接收邮箱一样有一定的深度。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-11 06:24

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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