开发过程经常需要查看某些特定参数。通常的方法可以使用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, ); // 清除寄存器状态
USART1->CR1 = USART_CR1_REST;
USART1->CR2 = USART_CR2_REST; // 停止位 1
USART1->CR3 = USART_CR3_REST; // 没用控制流 // 防止产生不必要的信息
for (i = ; 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 () {
Delay(); // 太快降低速度方便看结果(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 <stdio.h>
#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, ); // 清除寄存器状态
USART1->CR1 = USART_CR1_REST;
USART1->CR2 = USART_CR2_REST; // 停止位 1
USART1->CR3 = USART_CR3_REST; // 没用控制流 // 防止产生不必要的信息
for (i = ; 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" {
#endif void serial_init(void); #ifdef __cplusplus
}
#endif #endif

串口调试头 Serial.h

STM32调试大法 之 串口通讯的更多相关文章

  1. STM32 + RT Thread OS 串口通讯

    1.   创建项目 a)   禁用Finsh和console b)   默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...

  2. STM32与PC机串口通讯

    有时要将板子的信息输出到电脑上来调试之类的,或者把传感器收集到的数据显示到电脑. 当然了,这只是最基本的串口通信,简单的说,是有一根USB线连着的. mbed上并没有能显示printf的功能.需要自己 ...

  3. STM32—串口通讯详解

    串口通讯目录 物理层 协议层 USART简介 开发板与上位机的连接 代码讲解: 一.初始化结构体 二.NVIC配置中断优先级 三.USART配置函数讲解 四.传输数据的函数: 1.发送一个字节 2.发 ...

  4. stm32串口通讯问题

    stm32串口通讯问题 在串口试验中,串口通讯不正常,则可能会出现以下问题: 1. 配置完成后,串口没有任何消息打印. 原因:1,端口配置有问题,需要重新检查I/O口的配置 2,接线有问题,检查接线是 ...

  5. STM32F10x 学习笔记5(USART实现串口通讯 1)

    STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器.通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间 ...

  6. STM32菜鸟成长记录---RS485通讯协议的应用

    写作原因:近来蛋闲?非也  !  昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...

  7. 第20章 USART—串口通讯

    本章参考资料:<STM32F76xxx参考手册>USART章节. 学习本章时,配合<STM32F76xxx参考手册>USART章节一起阅读,效果会更佳,特别是涉及到寄存器说明的 ...

  8. USART—串口通讯

    本章中主要讲解的是串口异步通讯,异步通讯中由于没有时钟信号, 所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码 . 串口通讯的一个数据包从起始信号开始,直到停止信号结束.数据 ...

  9. 第20章 USART—串口通讯—零死角玩转STM32-F429系列

    第20章      USART—串口通讯 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...

随机推荐

  1. uva 10054 The Necklace 拼项链 欧拉回路基础应用

    昨天做了道水题,今天这题是比较水的应用. 给出n个项链的珠子,珠子的两端有两种颜色,项链上相邻的珠子要颜色匹配,判断能不能拼凑成一天项链. 是挺水的,但是一开始我把整个项链看成一个点,然后用dfs去找 ...

  2. angularjs表格方式显示数据

    <table> <tr ng-repeat="x in names"> <td>{{ x.Name }}</td> <td&g ...

  3. ionic实现双击返回键退出软件

    1.首先要安装cordova插件:插件地址:cordova plugin add https://github.com/EddyVerbruggen/Toast-PhoneGap-Plugin.git ...

  4. Codevs 1287 矩阵乘法&&Noi.cn 09:矩阵乘法(矩阵乘法练手题)

    1287 矩阵乘法  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 小明最近在为线性代数而头疼, ...

  5. backbone.Model 源码笔记

    backbone.Model backbone的model(模型),用来存储数据,交互数据,数据验证,在view里面可以直接监听model来达到model一改变,就通知视图. 这个里面的代码是从bac ...

  6. C#--深入分析委托与事件

    本篇文章将为你介绍一下 Delegate 的使用方式,逐渐揭开 C# 当中事件(Event)的由来,它能使处理委托类型的过程变得更加简单. 还将为您解释委托的协变与逆变,以及如何使用 Delegate ...

  7. 使用OLEDB读取excel和csv文件

    这是我第一次在博客上写东西,简单的为大家分享一个oledb读取文件的功能吧,这两天在做一个文件导入数据库的小demo,就想着导入前先在页面上展示一下,之前调用Microsoft.Office.Inte ...

  8. DWZ (JUI) 教程 根据ID刷新 dialog

    reloadDialog:function(dialogId){ var dialog = $("body").data(dialogId); if(dialog){ $.pdia ...

  9. XML DOM 循环(foreach)读取PHP数据 和 PHP 编写 XML DOM 【转载】

    用 PHP 读取和编写可扩展标记语言(XML)看起来可能有点恐怖.实际上,XML 和它的所有相关技术可能是恐怖的,但是用 PHP 读取和编写 XML 不一定是项恐怖的任务.首先,需要学习一点关于 XM ...

  10. sql修改字段长度

    语法: alter table <表名> alter column <字段名> 新类型名(长度) 示例:假如有名T1,字段名F1,原来F1为varchar(3),现在要改为va ...