• PY32F003F18串口printf功能


    1、PY32F003F18复用功能总结:

    //GPIOx=GPIOA,Pin=GPIO_PIN_0,alternate=GPIO_AF9_USART2,则将PA0引脚复用为USART2_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_0,alternate=GPIO_AF10_SPI1,则将PA0引脚复用为SPI1_MISO
    //GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF0_SPI1,则将PA1引脚复用为SPI1_SCK
    //GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF9_USART2,则将PA1引脚复用为USART2_RX
    //GPIOx=GPIOA,Pin=GPIO_PIN_1,alternate=GPIO_AF10_SPI1,则将PA1引脚复用为SPI1_MOSI
    //GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF0_SPI1,则将PA2引脚复用为SPI1_MOSI
    //GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF1_USART1,则将PA2引脚复用为USART1_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF4_USART2,则将PA2引脚复用为USART2_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF10_SPI1,则将PA2引脚复用为SPI1_SCK
    //GPIOx=GPIOA,Pin=GPIO_PIN_2,alternate=GPIO_AF12_I2C,则将PA2引脚复用为I2C_SDA
    //GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF1_USART1,则将PA3引脚复用为USART1_RX
    //GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF4_USART2,则将PA3引脚复用为USART2_RX
    //GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF10_SPI1,则将PA3引脚复用为SPI1_MOSI
    //GPIOx=GPIOA,Pin=GPIO_PIN_3,alternate=GPIO_AF12_I2C,则将PA3引脚复用为I2C_SCL
    //GPIOx=GPIOA,Pin=GPIO_PIN_4,alternate=GPIO_AF9_USART2,则将PA4引脚复用为USART2_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_5,alternate=GPIO_AF0_SPI1,则将PA5引脚复用为SPI1_SCK
    //GPIOx=GPIOA,Pin=GPIO_PIN_5,alternate=GPIO_AF9_USART2,则将PA5引脚复用为USART2_RX
    //GPIOx=GPIOA,Pin=GPIO_PIN_6,alternate=GPIO_AF0_SPI1,则将PA6引脚复用为SPI1_MISO
    //GPIOx=GPIOA,Pin=GPIO_PIN_6,alternate=GPIO_AF15_RTCOUT,则将PA6引脚复用为RTC_OUT
    //GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF0_SPI1,则将PA7引脚复用为SPI1_MOSI
    //GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF8_USART1,则将PA7引脚复用为USART1_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF9_USART2,则将PA7引脚复用为USART2_TX
    //GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF10_SPI1,则将PA7引脚复用为SPI1_MISO
    //GPIOx=GPIOA,Pin=GPIO_PIN_7,alternate=GPIO_AF12_I2C,则将PA7引脚复用为I2C_SDA
    //GPIOx=GPIOA,Pin=GPIO_PIN_12,alternate=GPIO_AF0_SPI1,则将PA12引脚复用为SPI1_MOSI
    //GPIOx=GPIOA,Pin=GPIO_PIN_12,alternate=GPIO_AF6_I2C,则将PA12引脚复用为I2C_SDA
    //GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF0_SWJ,则将PA13引脚复用为SWDIO
    //GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF8_USART1,则将PA13引脚复用为USART1_RX,通常不要占用SWDIO
    //GPIOx=GPIOA,Pin=GPIO_PIN_13,alternate=GPIO_AF10_SPI1,则将PA13引脚复用为SPI1_MISO,通常不要占用SWDIO
    //GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF0_SWJ,则将PA14引脚复用为SWCLK
    //GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF1_USART1,则将PA14引脚复用为USART1_TX,通常不要占用SWCLK
    //GPIOx=GPIOA,Pin=GPIO_PIN_14,alternate=GPIO_AF4_USART2,则将PA14引脚复用为USART2_TX,通常不要占用SWCLK
    //GPIOx=GPIOB,Pin=GPIO_PIN_5,alternate=GPIO_AF0_SPI1,则将PB5引脚复用为SPI1_MOSI
    //GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF0_USART1,则将PB6引脚复用为USART1_TX
    //GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF4_USART2,则将PB6引脚复用为USART2_TX
    //GPIOx=GPIOB,Pin=GPIO_PIN_6,alternate=GPIO_AF6_I2C,则将PB6引脚复用为I2C_SCL
    //GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF0_USART1,则将PB7引脚复用为USART1_RX
    //GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF4_USART2,则将PB7引脚复用为USART2_RX
    //GPIOx=GPIOB,Pin=GPIO_PIN_7,alternate=GPIO_AF6_I2C,则将PB7引脚复用为I2C_SDA

    2、PY32F003F18重定义fputc函数

    //重定义fputc函数
    //函数功能:发送ch的值给USART2串口

    int fputc(int ch, FILE *f)
    {
        uint32_t isrflags;

        USART2->DR = (uint8_t)(ch & 0xFFU);
        //将ch写入串口数据寄存器(USART_DR),Send a byte to USART
      while(1)
        {
            isrflags = READ_REG(USART2->SR);//读"串口状态寄存器(USART_SR)"
            if((isrflags & USART_SR_TC) != RESET)//如果TC=1,即串口发送完成
                break;
        }
      return (ch);
    }

    3、测试程序

    1. #include "USART2.h"
    2. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    3. #include "string.h" //使能strcpy(),strlen(),memset()
    4. //PA0 ------> USART2_TX
    5. //PA1 ------> USART2_RX
    6. void USART2_GPIO_Config(void);
    7. void USART2_NVIC_Cpnfig(void);
    8. void USART2_Mode_Config(uint32_t baudrate);
    9. void USART2_Init(uint32_t baudrate);
    10. void USART2_Load_Send_Data(void);
    11. //函数功能:USART2的IO口配置,PA0是为USART2_TX,PA1是USART2_RX
    12. void USART2_GPIO_Config(void)
    13. {
    14. GPIO_InitTypeDef GPIO_InitStructureure;
    15. __HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟
    16. __HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
    17. GPIO_InitStructureure.Pin = GPIO_PIN_0; //选择第0脚,PA0是为USART2_TX
    18. GPIO_InitStructureure.Mode = GPIO_MODE_AF_PP; //复用功能推挽模式
    19. GPIO_InitStructureure.Pull = GPIO_PULLUP; //引脚上拉被激活
    20. GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速
    21. GPIO_InitStructureure.Alternate = GPIO_AF9_USART2; //将引脚复用为USART2
    22. HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);
    23. //根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器
    24. //将PA0初始化为USART2_TX
    25. GPIO_InitStructureure.Pin = GPIO_PIN_1; //选择第1脚,PA1是USART2_RX
    26. GPIO_InitStructureure.Mode = GPIO_MODE_AF_PP; //复用功能推挽模式
    27. GPIO_InitStructureure.Pull = GPIO_PULLUP; //引脚上拉被激活
    28. GPIO_InitStructureure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //引脚速度为最高速
    29. GPIO_InitStructureure.Alternate = GPIO_AF9_USART2; //将引脚复用为USART2
    30. HAL_GPIO_Init(GPIOA, &GPIO_InitStructureure);
    31. //根据GPIO_InitStructureure结构变量指定的参数初始化GPIOA的外设寄存器
    32. //将PA1初始化为USART2_RX
    33. }
    34. //函数功能:设置串口2中断优先级为0x01
    35. void USART2_NVIC_Cpnfig(void)
    36. {
    37. HAL_NVIC_SetPriority(USART2_IRQn, 0x01, 0);
    38. //设置串口2中断优先级为0x01,0无意义.USART2_IRQn表示中断源为串口2
    39. }
    40. //函数功能:波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
    41. void USART2_Mode_Config(uint32_t baudrate)
    42. {
    43. UART_HandleTypeDef UART_HandleStructureure;
    44. HAL_StatusTypeDef retData;
    45. __HAL_RCC_USART2_CLK_ENABLE();//使能USART2外设时钟
    46. UART_HandleStructureure.Instance = USART2; //接口为USART2
    47. UART_HandleStructureure.Init.BaudRate = baudrate; //波特率为115200bps
    48. UART_HandleStructureure.Init.WordLength = UART_WORDLENGTH_8B; //串口字长度为8
    49. UART_HandleStructureure.Init.StopBits = UART_STOPBITS_1; //串口停止位为1
    50. UART_HandleStructureure.Init.Parity = UART_PARITY_NONE; //串口无需奇偶校验
    51. UART_HandleStructureure.Init.HwFlowCtl = UART_HWCONTROL_NONE; //串口无硬件流程控制
    52. UART_HandleStructureure.Init.Mode = UART_MODE_TX_RX; //串口工作模式为发送和接收模式
    53. retData=HAL_UART_Init(&UART_HandleStructureure);
    54. //根据UART_HandleStructureure型结构初始化USART2
    55. if ( retData!= HAL_OK)//串口初始化失败
    56. {
    57. }
    58. // __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_PE);
    59. // //串口接收数据时,使能奇偶校验错误时产生中断,Enable the UART Parity Error Interrup
    60. // __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_ERR);
    61. // //串口接收数据时,使能帧错误、噪音错误和溢出错误时产生中断
    62. // //Enable the UART Error Interrupt: (Frame error, noise error, overrun error)
    63. __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_RXNE);
    64. 开启串口接收中断
    65. //串口接收数据时,使能"接收数据寄存器不为空"则产生中断(位RXNE=1)
    66. //Enable the UART Data Register not empty Interrupt
    67. /在串口中断服务函数中发送数据配置开始//
    68. // __HAL_UART_ENABLE_IT(&UART_HandleStructureure, UART_IT_TXE);
    69. //串口发丝数据时,使能"串口发送数据寄存器为空"产生中断(位TXE=1)
    70. //Enable the UART Transmit data register empty Interrupt
    71. __HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TXE);
    72. //串口发丝数据时,不使能"串口发送数据寄存器为空"产生中断(位TXE=0)
    73. //Disable the UART Transmit Complete Interrupt
    74. // __HAL_UART_ENABLE_IT(&UART_HandleStructureure,UART_IT_TC);
    75. //串口发丝数据时,使能"串口发送完成"产生中断(位TC=1)
    76. //Enable the UART Transmit Complete Interrupt
    77. __HAL_UART_DISABLE_IT(&UART_HandleStructureure,UART_IT_TC);
    78. //串口发丝数据时,不使能"串口发送完成"产生中断(位TC=1)
    79. /在串口中断服务函数中发送数据配置结束//
    80. HAL_NVIC_EnableIRQ(USART2_IRQn);
    81. //使能串口2中断
    82. //USART2_IRQn表示中断源为串口2
    83. }
    84. //函数功能:
    85. //PA0是为USART2_TX,PA1是USART2_RX
    86. //中断优先级为0x01
    87. //波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
    88. void USART2_Init(uint32_t baudrate)
    89. {
    90. USART2_GPIO_Config();//USART2的IO口配置,PA0是为USART2_TX,PA1是USART2_RX
    91. USART2_NVIC_Cpnfig();//设置串口2中断优先级为0x01
    92. USART2_Mode_Config(baudrate);
    93. //波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
    94. }
    95. //重定义fputc函数
    96. //函数功能:发送ch的值给USART2串口
    97. int fputc(int ch, FILE *f)
    98. {
    99. uint32_t isrflags;
    100. USART2->DR = (uint8_t)(ch & 0xFFU);
    101. //ch写入串口数据寄存器(USART_DR),Send a byte to USART
    102. while(1)
    103. {
    104. isrflags = READ_REG(USART2->SR);//"串口状态寄存器(USART_SR)"
    105. if((isrflags & USART_SR_TC) != RESET)//等待TC=1,即等待发送完成
    106. break;
    107. }
    108. return (ch);
    109. }
    110. //函数功能:串口2中断服务程序
    111. void USART2_IRQHandler(void)
    112. {
    113. uint8_t RX_temp;
    114. uint32_t isrflags;
    115. (void)RX_temp;//防止RX_temp不使用而产生警告
    116. isrflags = READ_REG(USART2->SR);
    117. //"串口状态寄存器(USART_SR)"
    118. if( (isrflags & USART_SR_RXNE) != RESET )//接收到新数据
    119. {//在串口状态寄存器中,发现RXNE=1,且串口控制寄存器1允许接收数据
    120. RX_temp = (uint8_t)(USART2->DR & (uint8_t)0x00FF);//读串口数据
    121. //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将ORE位(Overrun错误标志)清零;
    122. //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将NE位(噪声错误标志)清零;
    123. //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将FE位(帧错误标志)清零;
    124. //软件先读"串口状态寄存器(USART_SR)",然后再读"串口数据寄存器USART_DR",就可以将PE位(奇偶校验值错误)清零;
    125. //软件读"串口数据寄存器USART_DR",就可以将RXNE位清零
    126. }
    127. if( (isrflags & UART_IT_TC) != RESET )//Transmission complete interrupt
    128. {
    129. CLEAR_BIT(USART2->CR1, UART_IT_TC);
    130. //"串口控制寄存器1(USART_CR1)中的TCIE位"设置为0
    131. //串口发丝数据时,不使能"串口发送完成"产生中断(位TCIE=0)
    132. //Disable the UART Transmit Complete Interrupt
    133. }
    134. }

     直接用寄存器干了,看上去有点象寄存器工程,因为HALL库的确写的不太友好。不清楚原因。

    1. #include "py32f0xx_hal.h"
    2. #include "SystemClock.h"
    3. #include "USART2.h"
    4. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    5. #include "string.h" //使能strcpy(),strlen(),memset()
    6. #include "delay.h"
    7. #include "LED.h"
    8. const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
    9. int main(void)
    10. {
    11. // HSE_Config();
    12. //初始化"HSI,HSE,LSI振荡器",HSE用作系统时钟(SYSCLK),同时配置"AHB时钟(HCLK)和APB时钟(PCLK)"
    13. delay_init();
    14. HAL_Delay(1000);
    15. USART2_Init(115200);
    16. //PA0是为USART2_TX,PA1是USART2_RX
    17. //中断优先级为0x01
    18. //波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
    19. printf("%s",CPU_Reset_REG);
    20. MCU_LED_Init();
    21. while (1)
    22. {
    23. MCU_LED_Toggle();
    24. delay_ms(500);
    25. printf("\r\n9876543210\r\n");
    26. }
    27. }

    4、测试结果 

  • 相关阅读:
    【C#】vs2022 .net8
    AI:61-基于深度学习的草莓病害识别
    47.【Java 基础之面向对象】
    Kosmos-1: 通用接口架构下的多模态大语言模型
    【山东科技大学OJ】1241 Problem B: 编写函数:比较三个数大小 (Append Code)
    汇编-变量
    linux学习心得范文
    JAVA 学习路线 学习大纲(java 进阶路线)
    Android焦点之SurfaceFlinger的apply
    python中.npy文件转换为.txt或.csv文件
  • 原文地址:https://blog.csdn.net/weixin_42550185/article/details/132739689