博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32调试大法 之 串口通讯
阅读量:5217 次
发布时间:2019-06-14

本文共 6443 字,大约阅读时间需要 21 分钟。

开发过程经常需要查看某些特定参数。通常的方法可以使用paintf进行打印输出,观察具体的变量值。STM32内部集成有USART的串口功能,可以通过串口直接输出到电脑(上位机)。使用非常方便,基本不需要不需要写代码,只要配置一下就可以使用。

 

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

 

配置方法:

  1、重定向printf的输出函数 int fputc(int ch, FILE *f)

  2、配置STM32F10x的USART串口

 

重定向方法 stdio.h 的输出内容

int fputc(int ch, FILE *f){  // 等待USART1 数据发送完成(发送区域空)  while (!(USART1->SR & USART_SR_TXE));  // 填充发送寄存器,数据 + 校验位 最多9位  USART1->DR = (ch & 0x1FF);    return (ch);}

启动STM32的 USART1 串口

    1、使能 复用功能

    2、使能 A引脚(USART1 在 PA9,PA10)

    3、使能 USART1

    4、设置 PA9(TX)复用推挽输出

    5、设置 PA10(RX)输入浮空

    6、 设置串口参数:波特率、数据位、校验、停止位、流控制

    7、使能串口、使能输入、使能输出

    OK

void serial_init(void){  //  //  设置串口调试  //     //     输  出: USART1  //     引  脚: PA9(TX), PA10(RX)  //     波特率: 9600  //     数据位: 8 bit (default)  (CR1)  //     校  验: none  (default)  (CR1)  //     停止位: 1 bit (default)  (CR2)  //     流控制: none  (default)  (CR3)  //  // 清除设置后上面配置为系统默认状态    int i;  /// 使能复用功能,使能GPIOA,使能USART1  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;  // 关闭映射,确保USART使用 PA9,PA10  AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP;    // 清除PA9,PA10状态  GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 |                    GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );  // 设置PA9 发送 为复用推挽输出 2MHz  GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 );  // 设置PA10接收 为复用上拉下拉模式  GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );    // 设置波特率为 9600  // 计算方法  //          系统时钟 / (16分频 * 波特率)  //   Baud = 72,000,000 / (16 * 9600) = 468.75  //   整数部分 << 4 + 取整(小数部分 * 16)  //   468 << 4 + 0.75 * 16  USART1->BRR = __USART_BRR(SystemCoreClock, 9600);    // 清除寄存器状态  USART1->CR1 = USART_CR1_REST;  USART1->CR2 = USART_CR2_REST;           // 停止位 1  USART1->CR3 = USART_CR3_REST;           // 没用控制流    // 防止产生不必要的信息  for (i = 0; i < 0x1000; i++) __NOP();    // USART1 使能, 使能输出,使能输入  USART1->CR1 =  USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;  }

 

整个过程中关键的输出定向主要用到了2个寄存器:

   一个状态寄存器,检查发送是否为空(USART_ST_TXE)

  一个数据寄存器,用于发送数据

int main(void){  uint8_t ud = 'a';  Delay_init();  // 初始化串口调试  serial_init();    // 使用寄存器直接 输出 a~z  while (ud <= 'z') {    while (!(USART1->SR & USART_SR_TXE));    USART1->DR = ud;    ud++;  }      // 使用打印重定向输出字符串  printf("\ntest!\n");  printf("USART1 使能, 使能输出,使能输入\n");    ud = 'a';  while (1) {      Delay(20); // 太快降低速度方便看结果(200ms延迟)    // 使用寄存器直接输出    while (!(USART1->SR & USART_SR_TXE));    USART1->DR = ud;    ud++;            // 使用打印输出换行    if (ud > 'z') {      ud = 'a';      printf("\n");      }  };         }

 

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

 

完整代码

#define GPIO_CR_RESET                 (uint32_t)0x44444444 #define GPIO_CR_MODE_INPUT            (uint32_t)0x00000000#define GPIO_CR_MODE_2MHz             (uint32_t)0x22222222#define GPIO_CR_MODE_10MHz            (uint32_t)0x11111111#define GPIO_CR_MODE_50MHz            (uint32_t)0x33333333#define GPIO_CR_GP_PUSHPULL           (uint32_t)0x00000000#define GPIO_CR_GP_OPENDRAIN          (uint32_t)0x44444444 #define GPIO_CR_OUT_PP2MHz            (GPIO_CR_MODE_2MHz | GPIO_CR_GP_PUSHPULL)#define GPIO_CR_OUT_PP50MHz           (GPIO_CR_MODE_50MHz | GPIO_CR_GP_PUSHPULL)   #define GPIO_CR_AFO_PUSHPULL           (uint32_t)0x88888888#define GPIO_CR_AFO_OPENDRAIN          (uint32_t)0xcccccccc #define GPIO_CR_AFOUT_PP2MHz          (GPIO_CR_MODE_2MHz | GPIO_CR_AFO_PUSHPULL)  // 复用推挽输出,2MHz#define GPIO_CR_AFIN_FLOAT            (uint32_t)0x44444444  // 复用开漏输入#define GPIO_CR_AFIN_PULLDOWN         (uint32_t)0x88888888  // 复用上拉下拉输入#define USART_CR1_REST                (uint32_t)0x00000000#define USART_CR2_REST                (uint32_t)0x00000000#define USART_CR3_REST                (uint32_t)0x00000000
常量定义
/**  ********************************************************************  *  * @file     serial.c  * @author   fpack  * @version  v1.0  * @date     2014-9-1  * @brief    小穆妹纸串口调试  *  ********************************************************************  **/#include 
#include "armsis.h"/*---------------------------------------------------------------------------- Define Baudrate setting (BRR) for USART *----------------------------------------------------------------------------*/#define __DIV(__PCLK, __BAUD) ((__PCLK*25)/(4*__BAUD))#define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100)#define __DIVFRAQ(__PCLK, __BAUD) (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) * 16 + 50) / 100)#define __USART_BRR(__PCLK, __BAUD) ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F))//struct __FILE { int handle; /* Add whatever you need here */ };//FILE __stdout;//FILE __stdin;int fputc(int ch, FILE *f){ // 等待USART1 数据发送完成(发送区域空) while (!(USART1->SR & USART_SR_TXE)); USART1->DR = (ch & 0x1FF); return (ch);}void serial_init(void){ // // 设置串口调试 // // 输 出: USART1 // 引 脚: PA9(TX), PA10(RX) // 波特率: 9600 // 数据位: 8 bit (default) (CR1) // 校 验: none (default) (CR1) // 停止位: 1 bit (default) (CR2) // 流控制: none (default) (CR3) // // 清除设置后上面配置为系统默认状态 int i; /// 使能复用功能,使能GPIOA,使能USART1 RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN; // 关闭映射,确保USART使用 PA9,PA10 AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP; // 清除PA9,PA10状态 GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_MODE10 ); // 设置PA9 发送 为复用推挽输出 2MHz GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 ); // 设置PA10接收 为复用上拉下拉模式 GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 ); // 设置波特率为 9600 // 计算方法 // 系统时钟 / (16分频 * 波特率) // Baud = 72,000,000 / (16 * 9600) = 468.75 // 整数部分 << 4 + 取整(小数部分 * 16) // 468 << 4 + 0.75 * 16 USART1->BRR = __USART_BRR(SystemCoreClock, 9600); // 清除寄存器状态 USART1->CR1 = USART_CR1_REST; USART1->CR2 = USART_CR2_REST; // 停止位 1 USART1->CR3 = USART_CR3_REST; // 没用控制流 // 防止产生不必要的信息 for (i = 0; i < 0x1000; i++) __NOP(); // USART1 使能, 使能输出,使能输入 USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; }
整理后的串口配置代码 Serial.c
/**  ********************************************************************  *  * @file     serial.h  * @author   fpack  * @version  v1.0  * @date     2014-9-1  * @brief    小穆妹纸串口调试  *  ********************************************************************  **/#ifndef __SERIAL_H__#define __SERIAL_H__#ifdef __cplusplus  extern "C" {#endifvoid serial_init(void);#ifdef __cplusplus      }#endif#endif
串口调试头 Serial.h

 

转载于:https://www.cnblogs.com/gleam/p/3954220.html

你可能感兴趣的文章
AJAX
查看>>
sqlserver同一个局域网内,把服务器数据库备份到客户端
查看>>
tcp服务的测试程序开源
查看>>
MySQL基础:安装
查看>>
简练网软考知识点整理-项目资源优化、资源平衡及资源平滑
查看>>
三.使用字符串
查看>>
(Gorails)vuejs系列视频: Webpacker/vue-resource(不再为官方推荐)。
查看>>
JavaScript Transpilers: 为什么需要用它们?Babel的使用介绍。
查看>>
六、Hadoop学习笔记————调优之操作系统以及JVM
查看>>
EDM营销之电子邮件的长度和宽度讲解
查看>>
react-native中的scrollables
查看>>
Spring IOC (构造器注入)
查看>>
c++面试
查看>>
servlet文件上传
查看>>
Nginx的location配置
查看>>
将图片文件转成BASE64格式
查看>>
JS最佳实践
查看>>
spring boot 在SpringMVC中使用Jackson并格式化时间
查看>>
无法安装Java,以下开关中存在错误:“0”
查看>>
spring PROPAGATION
查看>>