鸣蜩伍 2023-09-27 15:32 采纳率: 23.1%
浏览 22
已结题

stm32f103zet6 串口5无法接收数据

stm32f103zet6 串口5无法接收数据
相同配置下串口3和串口1能够收发数据
不能进入中断函数

/* UART3 Buffer Defines */
#define USART5_RX_BUFFER_SIZE 64     /* 2,4,8,16,32,64,128 or 256 bytes */
#define USART5_TX_BUFFER_SIZE 256     /* 2,4,8,16,32,64,128 or 256 bytes */
#define USART5_RX_BUFFER_MASK ( USART5_RX_BUFFER_SIZE - 1 )
#define USART5_TX_BUFFER_MASK ( USART5_TX_BUFFER_SIZE - 1 )


UartRxBuffer  USART5_Rx_Buffer;

void UartInit(void)
{
    UartBufferInit();
    Uart5Init();
    UartNVIC();  
}

void UartBufferInit()
{      
    USART5_Rx_Buffer.buffer = (u8*)malloc(USART5_RX_BUFFER_SIZE);
    memset(USART5_Rx_Buffer.buffer,0,USART5_RX_BUFFER_SIZE);
    USART5_Rx_Buffer.index = 0;
    USART5_Rx_Buffer.maxSize = USART5_RX_BUFFER_SIZE; 
}

void Uart5Init(void)
{
   RCC_APB1PeriphClockCmd(RCC_APB1 Periph_UART5,ENABLE);
    USART_InitTypeDef USART_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(UART5, &USART_InitStructure);    
    USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
      USART_Cmd(UART5, ENABLE);
      USART_ClearFlag(UART5, USART_FLAG_TC);  
}

 void UartNVIC(void)
{    
        NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void UART5_IRQHandler(void)
{
    u8 res;
    if(USART_GetFlagStatus(UART5,USART_FLAG_ORE)==SET)
    {
        USART_ClearFlag(UART5,USART_FLAG_ORE);                         
        res = USART_ReceiveData(UART5);
        if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)
        {
            USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
            USART5_Rx_Buffer.index ++;
        }
    }    
    if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)  
    {
        res =USART_ReceiveData(UART5);    
        if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)
        {
            USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
            USART5_Rx_Buffer.index ++;
        }
    } 
    if(USART_GetITStatus(UART5, USART_FLAG_TC) != RESET)
    {
        return ;
    }
}

void IoInit(void)  
{
    //PORTA
     GPIO_InitTypeDef  GPIO_InitStructure;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOF|
     RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);     
     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);    
    
         
     GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOC, &GPIO_InitStructure);
     
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
     GPIO_Init(GPIOD, &GPIO_InitStructure);
    
}

  • 写回答

7条回答 默认 最新

  • 专家-赤兔[在线] 2023-09-27 15:35
    关注

    引自免费微信小程序-皆我百晓生,希望对题主有所帮助,如有帮助,还望采纳。


    在你提供的代码中,我发现了一些问题。

    首先,你没有在代码中实现串口数据的发送功能。在你的UartBufferInit()函数中,你只初始化了接收缓冲区,但没有初始化发送缓冲区。你需要添加以下代码来初始化发送缓冲区:

    UartTxBuffer USART5_Tx_Buffer;
    
    void UartBufferInit()
    {      
        USART5_Rx_Buffer.buffer = (u8*)malloc(USART5_RX_BUFFER_SIZE);
        memset(USART5_Rx_Buffer.buffer, 0, USART5_RX_BUFFER_SIZE);
        USART5_Rx_Buffer.index = 0;
        USART5_Rx_Buffer.maxSize = USART5_RX_BUFFER_SIZE; 
    
        USART5_Tx_Buffer.buffer = (u8*)malloc(USART5_TX_BUFFER_SIZE);
        memset(USART5_Tx_Buffer.buffer, 0, USART5_TX_BUFFER_SIZE);
        USART5_Tx_Buffer.index = 0;
        USART5_Tx_Buffer.maxSize = USART5_TX_BUFFER_SIZE; 
    }
    

    然后,你的中断服务程序中有一些错误。当USART5_Rx_Buffer.index等于USART5_Rx_Buffer.maxSize时,你不应该继续接收数据,否则可能会导致缓冲区溢出。你需要添加一个条件来检查缓冲区是否已满,并在缓冲区满时停止接收数据。你可以按照以下代码修改你的中断服务程序:

    void UART5_IRQHandler(void)
    {
        u8 res;
        if(USART_GetFlagStatus(UART5,USART_FLAG_ORE)==SET)
        {
            USART_ClearFlag(UART5,USART_FLAG_ORE);                         
            res = USART_ReceiveData(UART5);
            if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)
            {
                USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
                USART5_Rx_Buffer.index ++;
            }
        }    
        if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET && USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)  
        {
            res = USART_ReceiveData(UART5);    
            USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
            USART5_Rx_Buffer.index ++;
        } 
        if(USART_GetITStatus(UART5, USART_FLAG_TC) != RESET)
        {
            return ;
        }
    }
    

    此外,由于UartNVIC()函数中没有包含NVIC_InitStructure的定义和初始化,你需要在该函数之前添加以下代码:

    NVIC_InitTypeDef NVIC_InitStructure;
    

    最后,你需要在你的main()函数中调用UartInit()IoInit()函数来初始化串口和IO口。

    评论
  • Leodong. 2023-09-27 15:39
    关注

    该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
    如果您需要修改代码以解决无法发送和接收数据的问题,请按照以下步骤操作:
    1、 首先,检查USART5的初始化配置。确保波特率、字长、停止位、奇偶校验和硬件流控制等参数与您的硬件设备匹配。例如,您可以将USART_InitStructure.USART_BaudRate设置为115200,以匹配您的STM32F103ZET6开发板的时钟速度。

    USART_InitStructure.USART_BaudRate = 115200;
    

    2、 接下来,检查USART5中断配置。确保NVIC_InitStructure中的IRQChannel和IRQChannelSubPriority参数分别设置为UART5_IRQn和0。同时,请确保在中断服务程序中正确处理了接收和发送数据的相关操作。

    NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
    
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    

    3、 然后,检查USART5缓冲区溢出问题。根据您的需求,可以增加缓冲区的大小(例如将USART5_RX_BUFFER_SIZE设置为256),或者在接收数据时检查缓冲区是否已满,如果已满则等待缓冲区空闲。

    #define USART5_RX_BUFFER_SIZE 256
    
    ...
    
    void Uart5_IRQHandler(void)
    
    {
    
        u8 res;
        if(USART_GetFlagStatus(UART5,USART_FLAG_ORE)==SET)
        {
            USART_ClearFlag(UART5,USART_FLAG_ORE);                         
            res = USART_ReceiveData(UART5);
            if(USART5_Rx_Buffer.index < USART5_RX_BUFFER_SIZE)
            {
                USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
                USART5_Rx_Buffer.index ++;
            }
        }    
        ...
    }
    

    4、 最后,确保使用的GPIO引脚正确。在IoInit函数中,您需要根据实际情况正确配置GPIO引脚。例如:

    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);    
    
    GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    

    完成上述修改后,重新编译和烧录程序到STM32F103ZET6开发板上,观察是否能正常发送和接收数据。如有任何问题,请随时提问。


    如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

    评论 编辑记录
  • CSDN-Ada助手 CSDN-AI 官方账号 2023-09-27 18:03
    关注

    【相关推荐】




    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论
  • 心梓知识 2023-09-27 18:07
    关注

    结合GPT给出回答如下请题主参考
    首先,请确认串口5的引脚配置与串口1和串口3相同。如果引脚配置正确,可以按照以下步骤排查问题:

    1. 确认串口5的时钟源已经开启,以及波特率等配置正确。

    2. 确认发送和接收的数据格式正确,如数据位、停止位、校验位等。

    3. 检查串口5的中断是否开启,如果是使用中断方式进行收发数据,可能需要检查是否有中断优先级冲突等问题。

    4. 尝试使用轮询方式进行收发数据,检查是否能够正常工作。

    以下是一个简单的示例代码,演示如何使用STM32F103系列的USART5进行收发数据:

    #include "stm32f10x.h"
    
    void USART5_Init(void)
    {
        /* 配置USART5的GPIO引脚 */
        GPIO_InitTypeDef GPIO_InitStruct;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_2;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStruct);
        
        /* 配置USART5 */
        USART_InitTypeDef USART_InitStruct;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
        USART_InitStruct.USART_BaudRate = 9600;
        USART_InitStruct.USART_WordLength = USART_WordLength_8b;
        USART_InitStruct.USART_StopBits = USART_StopBits_1;
        USART_InitStruct.USART_Parity = USART_Parity_No;
        USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
        USART_Init(UART5, &USART_InitStruct);
        USART_Cmd(UART5, ENABLE);
    }
    
    void USART5_SendData(uint8_t data)
    {
        while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
        USART_SendData(UART5, data);
    }
    
    uint8_t USART5_ReceiveData(void)
    {
        while (USART_GetFlagStatus(UART5, USART_FLAG_RXNE) == RESET);
        return USART_ReceiveData(UART5);
    }
    
    int main(void)
    {
        USART5_Init();
        while (1)
        {
            USART5_SendData('A');
            uint8_t data = USART5_ReceiveData();
        }
    }
    

    注意:以上示例代码仅供参考,具体实现可能需要根据具体的应用场景进行调整。

    评论
  • 独处东汉 2023-09-27 18:33
    关注

    你好,你的问题代码中有些小bug,你用的代码有些乱,下边的代码给你改好了,你可以试一下跑一下,希望能帮助到你~~

    #include <string.h>
    #include <stdlib.h>
    /* UART3 Buffer Defines */
    #define USART5_RX_BUFFER_SIZE 64     /* 2,4,8,16,32,64,128 or 256 bytes */
    #define USART5_TX_BUFFER_SIZE 256     /* 2,4,8,16,32,64,128 or 256 bytes */
    #define USART5_RX_BUFFER_MASK ( USART5_RX_BUFFER_SIZE - 1 )
    #define USART5_TX_BUFFER_MASK ( USART5_TX_BUFFER_SIZE - 1 )
     
    typedef struct{
        u8 * buffer;
        u16 index;
        u16 maxSize;
    }UartRxBuffer;
     
    UartRxBuffer  USART5_Rx_Buffer;
     
    void Uart5Init(void)
    {
          USART_InitTypeDef USART_InitStructure;
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
            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(UART5, &USART_InitStructure);    
            USART_ITConfig(UART5, USART_IT_TC, ENABLE);  /*如果删除,程序不进入中断函数但能够从单片机发送数据不能接收数据,加上程序会反复进入中断函数*/
            USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
            USART_Cmd(UART5, ENABLE);
            USART_ClearFlag(UART5, USART_FLAG_TC);  
    }
    
    void UartNVIC(void)
    {    
            NVIC_InitTypeDef NVIC_InitStructure; // 添加
        NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
     
    void UartBufferInit()
    {      
        USART5_Rx_Buffer.buffer = (u8*)malloc(USART5_RX_BUFFER_SIZE);
        memset(USART5_Rx_Buffer.buffer,0,USART5_RX_BUFFER_SIZE);
        USART5_Rx_Buffer.index = 0;
        USART5_Rx_Buffer.maxSize = USART5_RX_BUFFER_SIZE; 
    }
    
    void UartInit(void)
    {
        UartBufferInit();
        Uart5Init();
        UartNVIC();  
    }
    
    void UART5_IRQHandler(void)
    {
        u8 res;
        if(USART_GetFlagStatus(UART5,USART_FLAG_ORE)==SET)
        {
            USART_ClearFlag(UART5,USART_FLAG_ORE);                         
            res = USART_ReceiveData(UART5);
            if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)
            {
                USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
                USART5_Rx_Buffer.index ++;
            }
        }    
        if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)  
        {
            res =USART_ReceiveData(UART5);    
            if(USART5_Rx_Buffer.index < USART5_Rx_Buffer.maxSize)
            {
                USART5_Rx_Buffer.buffer[USART5_Rx_Buffer.index] = res;
                USART5_Rx_Buffer.index ++;
            }
        } 
        if(USART_GetITStatus(UART5, USART_FLAG_TC) != RESET)
        {
            return ;
        }
    }
     
    void IoInit(void)  
    {
        //PORTA
         GPIO_InitTypeDef  GPIO_InitStructure;
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOG|RCC_APB2Periph_GPIOF|
         RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);     
         GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);    
        
             
         GPIO_InitStructure.GPIO_Pin= GPIO_Pin_12;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_Init(GPIOC, &GPIO_InitStructure);
         
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
         GPIO_Init(GPIOD, &GPIO_InitStructure);
        
    }
     
    
    
    评论
  • 数据大魔王 2023-09-27 21:56
    关注

    用STM32CubeMX软件来生成正确的引脚配置。然后时钟源配置正确。就好了

    评论
  • yy64ll826 2023-09-28 11:10
    关注
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月4日
  • 修改了问题 9月28日
  • 修改了问题 9月28日
  • 修改了问题 9月28日
  • 展开全部

悬赏问题

  • ¥30 哈夫曼编码译码器打印树形项目
  • ¥20 求完整顺利登陆QQ邮箱的python代码
  • ¥15 怎么下载MySQL,怎么卸干净原来的MySQL
  • ¥15 网络打印机Ip地址自动获取出现问题
  • ¥15 求局部放电案例库,用于预测局部放电类型
  • ¥100 QT Open62541
  • ¥15 stata合并季度数据和日度数据
  • ¥15 谁能提供rabbitmq,erlang,socat压缩包,记住版本要对应
  • ¥15 Vue3 中使用 `vue-router` 只能跳转到主页面?
  • ¥15 用QT,进行QGIS二次开发,如何在添加栅格图层时,将黑白的矢量图渲染成彩色