你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32调试大法 之 串口通讯

[复制链接]
STMCU小助手 发布时间:2022-1-29 15:01
开发过程经常需要查看某些特定参数。通常的方法可以使用paintf进行打印输出,观察具体的变量值。STM32内部集成有USART的串口功能,可以通过串口直接输出到电脑(上位机)。使用非常方便,基本不需要不需要写代码,只要配置一下就可以使用。

032329582356362.gif

简单设置就可以看到上面的效果

配置方法:
  1、重定向printf的输出函数 int fputc(int ch, FILE *f)
  2、配置STM32F10x的USART串口

重定向方法 stdio.h 的输出内容
  1. int fputc(int ch, FILE *f)
  2. {
  3.   // 等待USART1 数据发送完成(发送区域空)
  4.   while (!(USART1->SR & USART_SR_TXE));
  5.   // 填充发送寄存器,数据 + 校验位 最多9位
  6.   USART1->DR = (ch & 0x1FF);
  7.   
  8.   return (ch);
  9. }
复制代码

启动STM32的 USART1 串口
    1、使能 复用功能
    2、使能 A引脚(USART1 在 PA9,PA10)
    3、使能 USART1
    4、设置 PA9(TX)复用推挽输出
    5、设置 PA10(RX)输入浮空
    6、 设置串口参数:波特率、数据位、校验、停止位、流控制
    7、使能串口、使能输入、使能输出
    OK
  1. void serial_init(void)
  2. {
  3.   //
  4.   //  设置串口调试
  5.   //   
  6.   //     输  出: USART1
  7.   //     引  脚: PA9(TX), PA10(RX)
  8.   //     波特率: 9600
  9.   //     数据位: 8 bit (default)  (CR1)
  10.   //     校  验: none  (default)  (CR1)
  11.   //     停止位: 1 bit (default)  (CR2)
  12.   //     流控制: none  (default)  (CR3)
  13.   //
  14.   // 清除设置后上面配置为系统默认状态
  15.   
  16.   int i;
  17.   /// 使能复用功能,使能GPIOA,使能USART1
  18.   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
  19.   // 关闭映射,确保USART使用 PA9,PA10
  20.   AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP;
  21.   
  22.   // 清除PA9,PA10状态
  23.   GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 |
  24.                    GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
  25.   // 设置PA9 发送 为复用推挽输出 2MHz
  26.   GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 );
  27.   // 设置PA10接收 为复用上拉下拉模式
  28.   GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
  29.   

  30.   // 设置波特率为 9600
  31.   // 计算方法
  32.   //          系统时钟 / (16分频 * 波特率)
  33.   //   Baud = 72,000,000 / (16 * 9600) = 468.75
  34.   //   整数部分 << 4 + 取整(小数部分 * 16)
  35.   //   468 << 4 + 0.75 * 16
  36.   USART1->BRR = __USART_BRR(SystemCoreClock, 9600);
  37.   
  38.   // 清除寄存器状态
  39.   USART1->CR1 = USART_CR1_REST;
  40.   USART1->CR2 = USART_CR2_REST;           // 停止位 1
  41.   USART1->CR3 = USART_CR3_REST;           // 没用控制流
  42.   
  43.   // 防止产生不必要的信息
  44.   for (i = 0; i < 0x1000; i++) __NOP();
  45.   
  46.   // USART1 使能, 使能输出,使能输入
  47.   USART1->CR1 =  USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
  48.   
  49. }
复制代码

整个过程中关键的输出定向主要用到了2个寄存器:
   一个状态寄存器,检查发送是否为空(USART_ST_TXE)
  一个数据寄存器,用于发送数据
  1. int main(void)
  2. {
  3.   uint8_t ud = 'a';
  4.   Delay_init();
  5.   // 初始化串口调试
  6.   serial_init();
  7.   
  8.   // 使用寄存器直接 输出 a~z
  9.   while (ud <= 'z') {
  10.     while (!(USART1->SR & USART_SR_TXE));
  11.     USART1->DR = ud;
  12.     ud++;
  13.   }
  14.    
  15.   // 使用打印重定向输出字符串
  16.   printf("\ntest!\n");
  17.   printf("USART1 使能, 使能输出,使能输入\n");
  18.   
  19.   ud = 'a';
  20.   while (1) {  
  21.     Delay(20); // 太快降低速度方便看结果(200ms延迟)
  22.     // 使用寄存器直接输出
  23.     while (!(USART1->SR & USART_SR_TXE));
  24.     USART1->DR = ud;
  25.     ud++;   
  26.    
  27.     // 使用打印输出换行
  28.     if (ud > 'z') {
  29.       ud = 'a';
  30.       printf("\n");  
  31.     }
  32.   };      
  33.   
  34. }
复制代码

具体的配置寄存器可以查看《参考手册》

完整代码

  1. #define GPIO_CR_RESET                 (uint32_t)0x44444444
  2. #define GPIO_CR_MODE_INPUT            (uint32_t)0x00000000
  3. #define GPIO_CR_MODE_2MHz             (uint32_t)0x22222222
  4. #define GPIO_CR_MODE_10MHz            (uint32_t)0x11111111
  5. #define GPIO_CR_MODE_50MHz            (uint32_t)0x33333333

  6. #define GPIO_CR_GP_PUSHPULL           (uint32_t)0x00000000
  7. #define GPIO_CR_GP_OPENDRAIN          (uint32_t)0x44444444
  8. #define GPIO_CR_OUT_PP2MHz            (GPIO_CR_MODE_2MHz | GPIO_CR_GP_PUSHPULL)
  9. #define GPIO_CR_OUT_PP50MHz           (GPIO_CR_MODE_50MHz | GPIO_CR_GP_PUSHPULL)

  10.    
  11. #define GPIO_CR_AFO_PUSHPULL           (uint32_t)0x88888888
  12. #define GPIO_CR_AFO_OPENDRAIN          (uint32_t)0xcccccccc

  13. #define GPIO_CR_AFOUT_PP2MHz          (GPIO_CR_MODE_2MHz | GPIO_CR_AFO_PUSHPULL)  // 复用推挽输出,2MHz
  14. #define GPIO_CR_AFIN_FLOAT            (uint32_t)0x44444444  // 复用开漏输入
  15. #define GPIO_CR_AFIN_PULLDOWN         (uint32_t)0x88888888  // 复用上拉下拉输入


  16. #define USART_CR1_REST                (uint32_t)0x00000000
  17. #define USART_CR2_REST                (uint32_t)0x00000000
  18. #define USART_CR3_REST                (uint32_t)0x00000000

复制代码
  1. /**
  2.   ********************************************************************
  3.   *
  4.   * @file     serial.c
  5.   * @author   fpack
  6.   * @version  v1.0
  7.   * @date     2014-9-1
  8.   * @brief    小穆妹纸串口调试
  9.   *
  10.   ********************************************************************
  11.   **/

  12. #include <stdio.h>
  13. #include "armsis.h"

  14. /*----------------------------------------------------------------------------
  15. Define  Baudrate setting (BRR) for USART
  16. *----------------------------------------------------------------------------*/
  17. #define __DIV(__PCLK, __BAUD)       ((__PCLK*25)/(4*__BAUD))
  18. #define __DIVMANT(__PCLK, __BAUD)   (__DIV(__PCLK, __BAUD)/100)
  19. #define __DIVFRAQ(__PCLK, __BAUD)   (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) * 16 + 50) / 100)
  20. #define __USART_BRR(__PCLK, __BAUD) ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F))


  21. //struct __FILE { int handle; /* Add whatever you need here */ };
  22. //FILE __stdout;
  23. //FILE __stdin;

  24. int fputc(int ch, FILE *f)
  25. {
  26.   // 等待USART1 数据发送完成(发送区域空)
  27.   while (!(USART1->SR & USART_SR_TXE));
  28.   USART1->DR = (ch & 0x1FF);
  29.   
  30.   return (ch);
  31. }


  32. void serial_init(void)
  33. {
  34.   //
  35.   //  设置串口调试
  36.   //   
  37.   //     输  出: USART1
  38.   //     引  脚: PA9(TX), PA10(RX)
  39.   //     波特率: 9600
  40.   //     数据位: 8 bit (default)  (CR1)
  41.   //     校  验: none  (default)  (CR1)
  42.   //     停止位: 1 bit (default)  (CR2)
  43.   //     流控制: none  (default)  (CR3)
  44.   //
  45.   // 清除设置后上面配置为系统默认状态
  46.   
  47.   int i;
  48.   /// 使能复用功能,使能GPIOA,使能USART1
  49.   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
  50.   // 关闭映射,确保USART使用 PA9,PA10
  51.   AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP;
  52.   
  53.   // 清除PA9,PA10状态
  54.   GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 |
  55.                    GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
  56.   // 设置PA9 发送 为复用推挽输出 2MHz
  57.   GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 );
  58.   // 设置PA10接收 为复用上拉下拉模式
  59.   GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
  60.   

  61.   // 设置波特率为 9600
  62.   // 计算方法
  63.   //          系统时钟 / (16分频 * 波特率)
  64.   //   Baud = 72,000,000 / (16 * 9600) = 468.75
  65.   //   整数部分 << 4 + 取整(小数部分 * 16)
  66.   //   468 << 4 + 0.75 * 16
  67.   USART1->BRR = __USART_BRR(SystemCoreClock, 9600);
  68.   
  69.   // 清除寄存器状态
  70.   USART1->CR1 = USART_CR1_REST;
  71.   USART1->CR2 = USART_CR2_REST;           // 停止位 1
  72.   USART1->CR3 = USART_CR3_REST;           // 没用控制流
  73.   
  74.   // 防止产生不必要的信息
  75.   for (i = 0; i < 0x1000; i++) __NOP();
  76.   
  77.   // USART1 使能, 使能输出,使能输入
  78.   USART1->CR1 =  USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
  79.   
  80. }

复制代码
  1. /**
  2.   ********************************************************************
  3.   *
  4.   * @file     serial.h
  5.   * @author   fpack
  6.   * @version  v1.0
  7.   * @date     2014-9-1
  8.   * @brief    小穆妹纸串口调试
  9.   *
  10.   ********************************************************************
  11.   **/


  12. #ifndef __SERIAL_H__
  13. #define __SERIAL_H__

  14. #ifdef __cplusplus
  15.   extern "C" {
  16. #endif

  17. void serial_init(void);


  18. #ifdef __cplusplus   
  19.   }
  20. #endif

  21. #endif   

复制代码




收藏 评论0 发布时间:2022-1-29 15:01

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版