• stm32中如何进行printf重定向用于串口调试输出


    1 在main中包含stdio.h 文件

    2 Target选项框里选Use MicroLib 选项

    3 在main中添加UART1_Configuration()初始化的代码

    Uart1初始化,
    void UART1_Configuration(void)
    {
              USART_InitTypeDef USART_InitStructure;
            USART_ClockInitTypeDef  USART_ClockInitStructure;
            
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 |RCC_APB2Periph_USART1, ENABLE  );
            
            USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;                        // 时钟低电平活动
            USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;                                // 时钟低电平
            USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                // 时钟第二个边沿进行数据捕获
            USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;                // 最后一位数据的时钟脉冲不从SCLK输出
            /* Configure the USART1 synchronous paramters */
            USART_ClockInit(USART1, &USART_ClockInitStructure);                                        // 时钟参数初始化设置
                                                                                                                                                     
            USART_InitStructure.USART_BaudRate =9600;                                                  // 波特率为:115200
            USART_InitStructure.USART_WordLength = USART_WordLength_8b;                          // 8位数据
            USART_InitStructure.USART_StopBits = USART_StopBits_1;                                  // 在帧结尾传输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;                  // 发送使能+接收使能
            /* Configure USART1 basic and asynchronous paramters */
            USART_Init(USART1, &USART_InitStructure);
                
              /* Enable USART1 */
            USART_ClearFlag(USART1, USART_IT_RXNE);                         //清中断,以免一启用中断后立即产生中断
            USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);                //使能USART1中断源
            USART_Cmd(USART1, ENABLE);                                                        //USART1总开关:开启

    }
    4 子函数代码添加,  可以也加在main函数后面,也可以单独写一个uart.h,然后包含在main中。(亲测不加入这两个函数也可以printf重定向输出


    //int fputc(int ch, FILE *f)
    //{
    // /* 发送一个字节数据到USART1 */
    // USART_SendData(USART1, (u8) ch);
    //
    // /* 等待发送完毕 */
    // while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    //
    // return (ch);
    //}
    //
    ///// 重定向c库函数scanf到USART1
    //int fgetc(FILE *f)
    //{
    // /* 等待串口1输入数据 */
    // while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    //
    // return (int)USART_ReceiveData(USART1);
    //}
    //


    这个是printf函数调用串口输出字符的
    5 添加串口中断程序,在stm32XX_it.c中,先定义几个用到的变量
    #define TxBufferSize   (countof(TxBuffer) - 1)
    #define RxBufferSize   0x20

    /* Private macro -------------------------------------------------------------*/
    #define countof(a)   (sizeof(a) / sizeof(*(a)))

    /* Private variables ---------------------------------------------------------*/
    u8 TxBuffer[] = " USART Hyperterminal Interrupts Example: USART-Hyperterminal
    communication using Interrupt ";
    u8 RxBuffer[RxBufferSize];
    u8 NbrOfDataToTransfer = TxBufferSize;
    u8 NbrOfDataToRead = RxBufferSize;
    u8 TxCounter = 0; 
    u16 RxCounter = 0;

    然后是中断程序
    /*******************************************************************************
    * Function Name  : USART1_IRQHandler
    * Description    : This function handles USART1 global interrupt request.
    * Input          : None
    * Output         : None
    * Return         : None
    *******************************************************************************/
    void USART1_IRQHandler(void)
    {
      if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
      {
        /* Read one byte from the receive data register */
        RxBuffer[RxCounter++] = (USART_ReceiveData(USART1) & 0x7F);
       if(RxCounter == NbrOfDataToRead)
        {
          /* Disable the USART Receive interrupt */
              RxCounter = 0;
          //USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
        }
      }

      if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
      {   
        /* Write one byte to the transmit data register */
        USART_SendData(USART1, TxBuffer[TxCounter++]);                    

       if(TxCounter == NbrOfDataToTransfer)
        {
          /* Disable the USART1 Transmit interrupt */
          USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
        }    
      }           
    }

    这部分不加好像也可以实现,有待我后续验证。
    6上边ok之后,就可以随便printf()输出了,软件debug,
    就可以在MDK自带的模拟串口中看到激动人心的输出了,本人亲测, 串口函数部分有些不同

    串口调试非常实用的

  • 相关阅读:
    曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)
    曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)
    曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)
    曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)
    期货
    手机像素密度的计算公式
    线性代数第一讲 行列式01
    matlab找出某个元素的位置序号
    《树先生》影评
    当你的才华还不足以支撑起你的野心时,你就该静下心来学习
  • 原文地址:https://www.cnblogs.com/caolinsummer/p/5640509.html
Copyright © 2020-2023  润新知