OpenEdv-开源电子网

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

小白求助大神:STM32多串口互发数据失败!!!

[复制链接]

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2021-6-25
在线时间
50 小时
发表于 2021-6-27 00:01:36 | 显示全部楼层 |阅读模式
1金钱
具体实现是这样子的:1、串口调试助手发送数据给USART1,USART1收到数据后,将其发送给USART2。
2、USART2收到数据后,再将数据发送回USART1,也就是再返回串口调试助手显示。

但是现在存在问题:串口调试助手没有显示接收到的数据。调试程序设置断点,发现USART1的中断服务程序可以进入,并接收串口调试助手的数据。但是USART2的中断服务程序无法进入,从而不能实现第二步(USART2接收 → USART1发送)。请问各位大神这是什么原因呢?

贴上主要代码~~~~

void USART1_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        // 打开串口GPIO的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
       
        // 打开串口外设的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

        // 将USART Tx的GPIO配置为推挽复用模式
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        // 将USART Rx的GPIO配置为浮空输入模式
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        // 配置串口的工作参数
        // 配置波特率
        USART_InitStructure.USART_BaudRate = 115200;
        // 配置 针数据字长
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        // 配置停止位
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        // 配置校验位
        USART_InitStructure.USART_Parity = USART_Parity_No ;
        // 配置硬件流控制
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        // 配置工作模式,收发一起
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        // 完成串口的初始化配置
        USART_Init(USART1, &USART_InitStructure);
       
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
      /* 配置USART为中断源 */
      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
      /* 抢断优先级*/
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
      /* 子优先级 */
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      /* 使能中断 */
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      /* 初始化配置NVIC */
      NVIC_Init(&NVIC_InitStructure);


        // 使能串口接收中断
      USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
      USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);       
       
        // 使能串口
      USART_Cmd(USART1, ENABLE);            
}
//-----------------------------------------------------------------------------//
void USART2_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        // 打开串口GPIO的时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
       
        // 打开串口外设的时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

        // 将USART Tx的GPIO配置为推挽复用模式
        GPIO_InitStructure.GPIO_Pin = DEBUG2_USART_TX_GPIO_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(DEBUG2_USART_TX_GPIO_PORT, &GPIO_InitStructure);

        // 将USART Rx的GPIO配置为浮空输入模式
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        // 配置串口的工作参数
        // 配置波特率
        USART_InitStructure.USART_BaudRate = 115200;
        // 配置 针数据字长
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        // 配置停止位
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        // 配置校验位
        USART_InitStructure.USART_Parity = USART_Parity_No ;
        // 配置硬件流控制
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        // 配置工作模式,收发一起
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        // 完成串口的初始化配置
        USART_Init(USART2, &USART_InitStructure);
       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        /* 配置USART为中断源 */
       NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
       /* 抢断优先级*/
       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
       /* 子优先级 */
       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
       /* 使能中断 */
       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
       /* 初始化配置NVIC */
       NVIC_Init(&NVIC_InitStructure);

        // 使能串口接收中断
       USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
       USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);       
       
        // 使能串口
       USART_Cmd(USART2, ENABLE);            
}

//-----------------------------------------------------------------------------//
// 串口中断服务函数
void USART1_IRQHandler(void)
{
        if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
        {       
        //接收一帧数据量在设定范围内
        if( RX1_CNT < RX1_MAX_LENG )
        {
            //接收数据存入数组
            RX1_BUF[ RX1_CNT++ ] = USART_ReceiveData(USART1);
            USART_ClearITPendingBit( USART1, USART_IT_RXNE );
        }
        }


    if( USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET )
    {
        //将一帧数据发送给USART2
        Usart_SendArray( USART2, RX1_BUF, RX1_CNT);
        RX1_CNT = 0;

        //清除空闲中断
        USART1->SR;
        USART1->DR;  
        USART_ClearITPendingBit( USART1, USART_IT_IDLE );      
    }         
}
//-----------------------------------------------------------//
// 串口中断服务函数
void USART2_IRQHandler(void)
{
        if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
        {       
        //接收USART1发送来的数据
        if( RX2_CNT < RX2_MAX_LENG )
        {
            RX2_BUF[ RX2_CNT++ ] = USART_ReceiveData(USART2);
            USART_ClearITPendingBit( USART2, USART_IT_RXNE );
        }
        }


    if( USART_GetITStatus(USART2,USART_IT_IDLE)!=RESET )
    {
        //USART2再将一帧数据返回USART1(串口助手)
        Usart_SendArray( USART1, RX2_BUF, RX2_CNT);
        RX2_CNT = 0;

        //清除空闲中断
        USART2->SR;
        USART2->DR;
        USART_ClearITPendingBit( USART2, USART_IT_IDLE );
    }
}

//-----------------------------------------------------------//
/****************** 发送数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{
        uint8_t i;
       
        for(i=0; i<num; i++)
       {
            /* 发送一个字节数据到USART */
            Usart_SendByte(pUSARTx,array[i]);       

       }
        /* 等待发送完成 */
        while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
}



最佳答案

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

USART1和串口助手连接了,收到数据以后,你的USART1中断函数里是将USART1接收的缓存数据通过USART2发出,不是串口1发给串口2。串口1也不可能发给串口2,除非你在外部将两者物理连接。这种串口通信是一对一的,你也不可能将好几个串口连到一起。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

821

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3369
金钱
3369
注册时间
2011-11-10
在线时间
207 小时
发表于 2021-6-27 00:01:37 来自手机 | 显示全部楼层
USART1和串口助手连接了,收到数据以后,你的USART1中断函数里是将USART1接收的缓存数据通过USART2发出,不是串口1发给串口2。串口1也不可能发给串口2,除非你在外部将两者物理连接。这种串口通信是一对一的,你也不可能将好几个串口连到一起。
回复

使用道具 举报

3

主题

808

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3878
金钱
3878
注册时间
2017-3-7
在线时间
1692 小时
发表于 2021-6-27 17:12:37 | 显示全部楼层
硬件上1的发送和2的接收有没有连在一起,而且本质上uart是不支持先与的
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2021-6-25
在线时间
50 小时
 楼主| 发表于 2021-6-29 17:37:11 | 显示全部楼层
a5820736 发表于 2021-6-27 17:12
硬件上1的发送和2的接收有没有连在一起,而且本质上uart是不支持先与的

谢谢,我明白了。
其实我是想完成以下数据转发过程:
1、串口助手1发数据给USART1,USART1接收,接收到的数据由USART2发给串口助手2显示。
2、反过来,串口助手2发数据给USART2,USART2接收,接收到的数据由USART1发给串口助手2显示。
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2021-6-25
在线时间
50 小时
 楼主| 发表于 2021-6-29 17:38:48 | 显示全部楼层
1和2硬件上没有连在一起
我上面的描述错了
其实我是想完成以下数据转发过程:
1、串口助手1发数据给USART1,USART1接收,接收到的数据由USART2发给串口助手2显示。
2、反过来,串口助手2发数据给USART2,USART2接收,接收到的数据由USART1发给串口助手2显示
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2021-6-30 02:16:56 | 显示全部楼层
Martin17050041 发表于 2021-6-29 17:38
1和2硬件上没有连在一起
我上面的描述错了
其实我是想完成以下数据转发过程:

那就是串口对发咯
论坛我记得有网友发过代码,可以搜索参考下
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2021-6-25
在线时间
50 小时
 楼主| 发表于 2021-6-30 09:21:47 | 显示全部楼层
正点原子 发表于 2021-6-30 02:16
那就是串口对发咯
论坛我记得有网友发过代码,可以搜索参考下

&#128076;
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-23 02:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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