STM32调试大法 之 串口通讯
开发过程经常需要查看某些特定参数。通常的方法可以使用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调试大法 之 串口通讯的更多相关文章
- STM32 + RT Thread OS 串口通讯
1. 创建项目 a) 禁用Finsh和console b) 默认情况下,项目文件包含了finsh,它使用COM1来通讯,另外,console输出(rt_kprintf)也使用了COM1.因 ...
- STM32与PC机串口通讯
有时要将板子的信息输出到电脑上来调试之类的,或者把传感器收集到的数据显示到电脑. 当然了,这只是最基本的串口通信,简单的说,是有一根USB线连着的. mbed上并没有能显示printf的功能.需要自己 ...
- STM32—串口通讯详解
串口通讯目录 物理层 协议层 USART简介 开发板与上位机的连接 代码讲解: 一.初始化结构体 二.NVIC配置中断优先级 三.USART配置函数讲解 四.传输数据的函数: 1.发送一个字节 2.发 ...
- stm32串口通讯问题
stm32串口通讯问题 在串口试验中,串口通讯不正常,则可能会出现以下问题: 1. 配置完成后,串口没有任何消息打印. 原因:1,端口配置有问题,需要重新检查I/O口的配置 2,接线有问题,检查接线是 ...
- STM32F10x 学习笔记5(USART实现串口通讯 1)
STM32F10x 系列单片机中都包含了USART 模块,所谓USART,就是通用同步异步收发器.通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间 ...
- STM32菜鸟成长记录---RS485通讯协议的应用
写作原因:近来蛋闲?非也 ! 昨天一同事合作的项目代码出现的bug-----他的上位机每200ms给我发送命令向我这边下位机读取一些数据,在此过程会按下按键做一些另外操作并给他返回数据:(通信是通 ...
- 第20章 USART—串口通讯
本章参考资料:<STM32F76xxx参考手册>USART章节. 学习本章时,配合<STM32F76xxx参考手册>USART章节一起阅读,效果会更佳,特别是涉及到寄存器说明的 ...
- USART—串口通讯
本章中主要讲解的是串口异步通讯,异步通讯中由于没有时钟信号, 所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码 . 串口通讯的一个数据包从起始信号开始,直到停止信号结束.数据 ...
- 第20章 USART—串口通讯—零死角玩转STM32-F429系列
第20章 USART—串口通讯 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fi ...
随机推荐
- IQueryable与IEnumberable的区别
IEnumerable接口 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代.也就是说:实现了此接口的object,就可以直接使用foreach遍历此object: IQueryable 接口 ...
- NDK编译FFMpeg[Linux]
最近在研究视频直播相关的技术,了解到了FFmpeg,就在网上查看如何将FFmpeg移植到Android中,查了几天,看的东西不少,就是没有一个可以完全移植成功的,最后通过产看各种资料,结合网上的资料, ...
- 转:从三层架构到MVC-MVP
当然这种架构模式本身的一些问题也会在接下来的内容就加以介绍,另外就是如果大家有什么不同观点的话,欢迎拍砖(只要不打脸就行,呵呵). 一. MVC是谁提出的 模型-视图-控制器(MVC)是Xerox P ...
- 手机app(功能)测试重点
在手机客户端进行查看的测试重点:1.“点击加载更多”的分页处理技术,是否有重复的数据,数据显示是否完整,到达最后一页后是否还有数据进行显示2.数据的排序方式2.界面跳转是否正确3.出现异常情况是否有提 ...
- css3 transfrom使用以及其martix(矩阵)属性与其它属性的关系
写法 其属性martix与skew .scale .translate之间的关系 兼容性 : IE9+ : -ms-transform : IE9只支持2D转换 fire ...
- Javascript之动画1
我们来做一个小球运动的例子:在这个demo中,我们要求连续多次点击小球“开始”按钮,小球运动速度就越来越快.但是还是不完美存在BUG的,经过多次点击“开始”按钮再点击"停止"按钮就 ...
- SQL里IN的用法以及优化
1.in后条件不多,可以考虑主表建索引,或用union all 代替 2. in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查 ...
- HTML+CSS学习笔记 (13) - CSS代码缩写,占用更少的带宽
标签:HTML+CSS 盒模型代码简写 还记得在讲盒模型时外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左.具体应用在m ...
- c 语言时间的输出和比较
time_t The most basic representation of a date and time is the type time_t. The value of a time_t va ...
- hdu 1686 Oulipo KMP匹配次数统计
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1686 分析:典型的KMP算法,统计字符串匹配的次数. 用Next数组压缩时间复杂度,要做一些修改. / ...