OpenEdv-开源电子网

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

串口1接收到数据转发到串口2,串口2接收到数据转发到串口1

[复制链接]

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
发表于 2016-12-13 16:53:31 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 ssssssssssss 于 2016-12-15 20:22 编辑

我想实现: 串口同步转发                串口1接收到数据转发到串口2,串口2接收到数据转发到串口1,
            具体是这样的,串口2控制着一个蓝牙模块,但是我想用串口1来配置蓝牙模块,考虑到速度,我希望串口2接收到数据串口1可以立马发出来,串口1接收到数据串口2可以立马发出去,最好没有时间间隔,可以实现吗?           我实验了一下,采用dma转发会有丢数据和乱码的情况出现,比如发送20个字节可能会有三四个数据漏发或者错误!请问大神们有办法吗?
void USART1_IRQHandler(void)
{        


        if(USART1->SR&BIT5)                                                        //接收到数据
        {        
            USART1_NUM++;           
        //        UsartRx(USART1->DR);
           // DMAbuffer1[0]=USART1->DR;        
                if((DMA1->ISR&(1<<25)))
                {
                    USART2DMA_Enable(DMA1_Channel7,1);
               
                }                 
                USART1->SR &= ~BIT5;               
        }               
}



void USART2_IRQHandler(void)
{//        

         
        if(USART2->SR&BIT5)                                                        //接收到数据
        {        
                   USART2_NUM++;
        //        DMAbuffer1[0]=USART2->DR;
        
                if((DMA1->ISR&(1<<13)))
                {               
                      DMA1_MEM_LEN=1;                                //清除通道4传输完成标志
               MYDMA_Enable(DMA1_Channel4);
        
                }

            USART2->SR &= ~BIT5;
        
         //  usart2TxLen++;
         //  GetSPace=0;
        }
}




最佳答案

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

找到原因了 ,我用的是gd32是国产的芯片,有丢数据的现象,我换了stm32就可以实现串口数据转发了,gd的可以用异步的方式去转发
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-13 16:53:32 | 显示全部楼层
本帖最后由 ssssssssssss 于 2016-12-21 16:24 编辑
yaxeff 发表于 2016-12-21 11:33
我觉得你对DMA的理解出错了,DMA并不能提高串口的速度,串口速
度只跟波特率有关,DMA主要是为了只能提高CP ...

找到原因了 ,我用的是gd32是国产的芯片,有丢数据的现象,我换了stm32就可以实现串口数据转发了,gd的可以用异步的方式去转发
回复

使用道具 举报

44

主题

225

帖子

0

精华

高级会员

Rank: 4

积分
660
金钱
660
注册时间
2013-11-22
在线时间
131 小时
发表于 2016-12-13 17:46:30 | 显示全部楼层
void USART1_IRQHandler(void)              
{
        u8 Res;

        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   
        {
                Res =USART_ReceiveData(USART1);         
                USART_SendData( USART2, Res);
                while(USART_GetFlagStatus(USART2, USART_FLAG_TC)!=SET);
      }
}
回复

使用道具 举报

109

主题

1606

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2222
金钱
2222
注册时间
2011-12-15
在线时间
37 小时
发表于 2016-12-13 21:11:31 | 显示全部楼层
没玩过,一般考虑稳定性,都会加结束符这些。
专业制作STM32 物联网通信模块板,模块交流群:369840039。
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-14 11:02:56 | 显示全部楼层
zhp 发表于 2016-12-13 17:46
void USART1_IRQHandler(void)              
{
        u8 Res;

请问您有没有试验过呢?我需要实现发送接收都可以哦
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-14 11:03:48 | 显示全部楼层
ST-FAE-SALE 发表于 2016-12-13 21:11
没玩过,一般考虑稳定性,都会加结束符这些。

如果您要实现这个功能,您会怎么处理呢?有没有好的方案呢?
回复

使用道具 举报

0

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-2-23
在线时间
23 小时
发表于 2016-12-14 11:55:20 | 显示全部楼层
就按二楼的做法就行了,在接收中断里面发送,MCU的发送速度比串口快太多,不用考虑间隔问题
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-14 17:07:38 | 显示全部楼层
yaxeff 发表于 2016-12-14 11:55
就按二楼的做法就行了,在接收中断里面发送,MCU的发送速度比串口快太多,不用考虑间隔问题

按照二楼的做法,我写程序实验了一下,我开始用串口发送,数据丢失很严重,之后我采用在中断中用dma发送,数据还是有丢失但不是很严重,该怎么处理才能不丢数据呢?
回复

使用道具 举报

0

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-2-23
在线时间
23 小时
发表于 2016-12-15 16:05:31 | 显示全部楼层
ssssssssssss 发表于 2016-12-14 17:07
按照二楼的做法,我写程序实验了一下,我开始用串口发送,数据丢失很严重,之后我采用在中断中用dma发送 ...

不应该啊,串口转发我试过很大数据量的,蓝牙数据量也不大啊.
查看一下是否在中断做了复杂处理.
实在不行就DMA接收吧
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-15 20:09:49 | 显示全部楼层
本帖最后由 ssssssssssss 于 2016-12-15 20:12 编辑
yaxeff 发表于 2016-12-15 16:05
不应该啊,串口转发我试过很大数据量的,蓝牙数据量也不大啊.
查看一下是否在中断做了复杂处理.
实在不行 ...

我中断中没有复杂程序,我贴出来您帮看看,能不能上传您的代码呢?我参考一下void USART1_IRQHandler(void)
{       


        if(USART1->SR&BIT5)                                                        //接收到数据
        {       
            USART1_NUM++;          
        //        UsartRx(USART1->DR);
           // DMAbuffer1[0]=USART1->DR;       
                if((DMA1->ISR&(1<<25)))
                {
                    USART2DMA_Enable(DMA1_Channel7,1);
               
                }                
                USART1->SR &= ~BIT5;               
        }               
}



void USART2_IRQHandler(void)
{//       

         
        if(USART2->SR&BIT5)                                                        //接收到数据
        {       
                   USART2_NUM++;
        //        DMAbuffer1[0]=USART2->DR;
       
                if((DMA1->ISR&(1<<13)))
                {               
                      DMA1_MEM_LEN=1;                                //清除通道4传输完成标志
               MYDMA_Enable(DMA1_Channel4);
       
                }

            USART2->SR &= ~BIT5;
       
         //  usart2TxLen++;
         //  GetSPace=0;
        }
}

回复

使用道具 举报

0

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-2-23
在线时间
23 小时
发表于 2016-12-16 10:04:50 | 显示全部楼层
ssssssssssss 发表于 2016-12-15 20:09
我中断中没有复杂程序,我贴出来您帮看看,能不能上传您的代码呢?我参考一下void USART1_IRQHandler(voi ...

给你一些意见:
1.你的程序思路有点问题,必须在进入串口中断的时候,DMA已经发送完成了,才不会丢数.
2.我仍然觉得直接发送就可以.(我之前用来做每秒8K数据量的转发,完全没有问题)
[mw_shl_code=c,true]if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
          {   
        u8Value = USART_ReceiveData(USART2);
        USART_SendData(USART3,u8Value);
          }[/mw_shl_code]

回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-20 18:44:24 | 显示全部楼层
yaxeff 发表于 2016-12-16 10:04
给你一些意见:
1.你的程序思路有点问题,必须在进入串口中断的时候,DMA已经发送完成了,才不会丢数.
2.我 ...

我看您这个函数也没有判断啊?
回复

使用道具 举报

0

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-2-23
在线时间
23 小时
发表于 2016-12-20 22:01:58 | 显示全部楼层
ssssssssssss 发表于 2016-12-20 18:44
我看您这个函数也没有判断啊?

以上是直接转发的代码,当然没有其他处理,就蓝牙那点数据量完全可行.
而如果你一定要使用DMA接收的话需要两个中断配合,串口空闲中断和DMA传输完成中断
回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-21 09:49:14 | 显示全部楼层
yaxeff 发表于 2016-12-20 22:01
以上是直接转发的代码,当然没有其他处理,就蓝牙那点数据量完全可行.
而如果你一定要使用DMA接收的话需要 ...

我只是采用了dma发送,我的试验结果如下:
当pc给串口1发送:
abcdefghigklmnopqrstuvwxyzabcdefghigklmnopqrstuvwxyz
串口2接收到并且发送出来的数据为:
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnoprstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstvwxyzabcdeghigklmnoprstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
abcdefghigklmnopqrstuwxyzabcdefhigklmnopqstuvwxyz
总是特定的位会丢失!程序中也做了相应的判断,不知道那里出了问题?



回复

使用道具 举报

160

主题

967

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2097
金钱
2097
注册时间
2014-3-7
在线时间
491 小时
 楼主| 发表于 2016-12-21 09:52:43 | 显示全部楼层
yaxeff 发表于 2016-12-20 22:01
以上是直接转发的代码,当然没有其他处理,就蓝牙那点数据量完全可行.
而如果你一定要使用DMA接收的话需要 ...

void USART1_IRQHandler(void)
{       

        if(USART1->SR&BIT5)                                                        //接收到数据
        {       
            DMA1->IFCR|=(1<<25); //清除通道4传输完成标志          
            DMAbuffer2[0]=USART1->DR;       
            USART2DMA_Enable(DMA1_Channel7,1);                       
            Uart2ClearDmaFlag();                                
            USART1->SR &= ~BIT5;               
        }               
}

void Uart1ClearDmaFlag(void)
{
  while(1)
  {
    if(DMA1->ISR&(1<<13))//等待通道4传输完成
        {
                DMA1->IFCR|=(1<<13); //清除通道4传输完成标志
                break;
    }
  }
}
void Uart2ClearDmaFlag(void)
{
while(1)
{
    if(DMA1->ISR&(1<<25))//等待通道4传输完成
        {
                DMA1->IFCR|=(1<<25); //清除通道4传输完成标志
                        break;
    }
}
}
回复

使用道具 举报

0

主题

14

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2016-2-23
在线时间
23 小时
发表于 2016-12-21 11:33:34 | 显示全部楼层
ssssssssssss 发表于 2016-12-21 09:52
void USART1_IRQHandler(void)
{       

我觉得你对DMA的理解出错了,DMA并不能提高串口的速度,串口速
度只跟波特率有关,DMA主要是为了只能提高CPU的效率.

而你在串口RXNE中断里等待DMA事件,那如果DMA没有传输完成的话,
你的CPU就不能干其他事了,假如这个时候有串口数据,你也接收不到.

然后我还是给你重申一遍直接把串口1接收到的通过串口2直接发送,
串口2接收到的串口1直接发送就行了.数据量那么小.我想出不行的理由.

当然如果你一定要用DMA收发的话,请使用串口IDLE中断和TC中断配合
DMA传输完成中断来使用,具体可以参考下别人的代码.
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 03:49

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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