Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
[RealTouch例程]串口的基本使用
发布于 2012-09-01 17:15:46 浏览:9912
订阅该版
串口 串口在嵌入式系统中是一个非常重要的外设,它通信方式简单在软件开发阶段常用作调试工具。本示例中我们只实现串口的输出功能,同时还 会实现一个具有printf功能输出接口。这样咱们以后的例程中就有了一个简单的调试工具。 1. STM32串口简介 STM32的串口功能非常丰富,它可以支持双全工异步通信、LIN、IrDA、智能卡协议、单线半双工通信、支持调制解调器操作。 接下来我们将对使用STM32的串口应该进行的哪些设置给予简单说明,并对需要设置的寄存器给予简单介绍。要使用串口除了应对串口的波特率等进行配置外还需要对串口用到I/O进行设置,下面将分步进行介绍: 1) 串口时钟使能 STM32可以对每个外设进行单独的时钟控制,因此配置串口前需要打开串口的时钟。开启时钟前查看一下具体外设在哪个总线上是非常有必要的,通过查看STM32的参考手册第一章的1.2节得知串口1和6(USART1和6)在APB2上其它串口都在APB1上。 2) 设置波特率 串口波特率的设置是在USART_BRR中配置的,寄存器描述如下: 波特率配置寄存器各位描述 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 保留 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 DIV_Mantissa DIV_Fraction STM32的波特率发生器可以使用分数作为分频值,DIV_Fraction表示小数部分DIV_Mantissa表示整数部分。分频值USARTDIV = DIV_Mantissa + DIV_Fraction /(8 * (2 - OVER8))。波特率Baud = APBxCLK / (8 * (2 – OVER8) * USARTDIV)。其中OVER8是USART_CR1中的一位取值0或1(当OVER8为1时只有DIV_Fraction[2:0]有效,DIV_Fraction[3]应设置为0)。举例说明一下这个分频值的计算:假设OVER8为0,USART_BRR为0x1BC则Mantissa = 27,Fraction = 12。分频值为27+12/16 = 27.75。 3) 串口控制 串口控制寄存器1各位描述 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 保留 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 OVER8 - UE M WAKE PCE PS PEIE TXEIE TCIE RXNEIE TCIE TE RE RWU SBK STM32共有三个控制寄存器在这里我们仅对控制寄存器1中要用到的位给予说明。OVER8是设置过采样,1表示8倍过采样0表示16倍过采样。UE为串口使能。M为字长选择,0表示8位数据位1表示9位数据位。PCE为校验控制使能,1表示开启校验0表示无需校验。PS为校验选择,0表示偶校验1表示奇校验。PEIE为校验中断使能。TE为发送使能,1表示允许发送。 4) 数据传输 STM32的数据发送与接收都是通过寄存器USART_DR来实现的。它是一个包含发送(TDR)和接收(RDR)的32位双功能寄存器,但只有9位有效位。 5) 串口状态 串口状态寄存器各位描述 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 保留 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 保留 CTS LBD TXE TC RXNE IDLE ORE NF FE PE 在这里我们只需关注TXE、TC这两个位。串口发送数据时是先把数据放在发送缓冲区,然后再放到移位寄存器中一位一位的将数据发送出去。TXE为1时就表示发送缓冲区TDR为空,TC为1则表示传输完成即移位寄存器中也没有数据。只有当TXE为1时我们才能将下一个数据写到USART_DR中。 2.本例程所用硬件资源介绍 本示例使用了串口3(在扩展板上标有UART字样),PB10对应发送引脚,PB11对应接收引脚但本例程只使用了发送引脚。 3. 例程 代码1 初始化串口 ```/* uart.h */ void uart_init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* 开启GPIO_B的时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /* 开启串口3的时钟 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIOB, &GPIO_InitStructure); /* 将PB10作为复用功能中的USART3通信引脚使用 */ GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx; USART_Init(USART3, &USART_InitStructure); /* 使能串口3 */ USART_Cmd(USART3, ENABLE); } ``` 这里要注意的就是引脚配置为复用功能模式后,还需要选择具体使用哪个复用功能,其余的初始化比较简单就没什么说的了。 代码2 发送数据 ``` /* uart.c */ static void _send(const char *str, unsigned int size) { int pos = 0; while(size) { if (str[pos] == ' ') break; /* 等待缓冲区空 */ while(!(USART3->SR & 0x80)); /* 发送数据 */ USART3->DR = str[pos]; pos ++; size --; } } void debug(const char* fmt,...) { va_list ap; char string[65]; string[64]=' '; va_start(ap,fmt); vsprintf(string,fmt,ap); va_end(ap); _send(string,64); } ``` 在这里我实现了一个可以格式输出的接口在以后的例程中可以把它作为调试工具了。 ![串口的基本使用.pdf](/uploads/88_fb26d3198251bdd244fd3004f78b39eb.pdf) ![RealTouch_uart.zip](/uploads/88_6bea3918e9074336b162335cf6c749ec.zip)
查看更多
8
个回答
默认排序
按发布时间排序
rellay
2012-09-04
这家伙很懒,什么也没写!
STM32F4xx_Libraries\CMSIS\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c(372): error: #20: identifier "PWR_CR_VOS" is undefined 新手求助
bernard
2012-09-04
这家伙很懒,什么也没写!
PWR_CR_VOS未定义,这个应该是和你的工程相关吧
rellay
2012-09-04
这家伙很懒,什么也没写!
恩,就用的这个帖子里的例程呀,不知道哪出问题了
shaolin
2012-09-05
这家伙很懒,什么也没写!
例程本身没有发现有这问题。
bernard
2012-09-05
这家伙很懒,什么也没写!
是否是编译器的问题,提供相关信息吧
grissiom
2012-09-05
这家伙很懒,什么也没写!
>STM32F4xx_LibrariesCMSISSTSTM32F4xxSourceTemplatessystem_stm32f4xx.c(372): error: #20: identifier "PWR_CR_VOS" is undefined >新手求助 --- 感觉很像是用了 MDK 自带的不同版本的 CMSIS 头文件…… 工程文件是 rellay 自己弄的?……
rellay
2012-09-05
这家伙很懒,什么也没写!
感觉很像是用了 MDK 自带的不同版本的 CMSIS 头文件…… 谢谢各位大神! 应该是CMSIS版本有点小问题,换了下STM32F4的‘Libraries’,无报错
撰写答案
登录
注册新账号
关注者
0
被浏览
9.9k
关于作者
shaolin
这家伙很懒,什么也没写!
提问
115
回答
444
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
3
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部