STM32F103mini教程学习总结与心得(二)---->串口通信
关注同名微信公众号“混沌无形”,有趣好文!
一、串口原理
1.处理器与外部设备通信的两种方式:并行通信(速度快,占用资源多)+串行通信(反之)
2.串行通信(按照数据传送方向分类):
(1)单工:数据传输只支持数据在一个方向上传输
(2)半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信
(3)全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立 的接收和发送能力。
4.STM32的串口通信接口
(1)UART:通用异步收发器
(2)USART:通用同步异步收发器
分数波特率发生器系统,提供精确的波特率(波特率决定数据传输速度)。
-发送和接受共用的可编程波特率,最高可达4.5Mbits/s
可编程的数据字长度(8位或者9位);
可配置的停止位(支持1或者2位停止位);
可配置的使用DMA多缓冲器通信。
单独的发送器和接收器使能位。
检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志
多个带标志的中断源。触发中断。
其他:校验控制,四个错误检测标志。
6.串口异步通信需要定义的参数:
数据位(8位或者9位)
奇偶校验位(第9位)--->偶校验:如果数据位8位中,1的个数为偶数,则校验位为0,反之为1;奇校验相反
停止位(1,15,2位)
波特率设置---->点击打开链接
void USART_Cmd();//使能串口
void USART_ITConfig();//使能相关中断
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
SR寄存器操作:
void USART_ClearFlag();//清除状态标志位
ITStatus USART_GetITStatus();//获取中断状态标志位
void USART_ClearITPendingBit();//清除中断状态标志位
二、实际串口寄存器操作
1.miniSTM32板载2个串口:
(1)USB串口(CH340:USB转串口芯片):与电脑通信
(2)RS232串口:异步传输标准接口---STM32内带的USB接口
(3)术语区分:1)串口、COM口是指的物理接口形式(硬件)【COM口即串行通讯端口,简称串口】,而TTL、RS-232、RS-485是指的电平标准(电信号--通信协议)
2)TTL标准是低电平为0,高电平为1(+5V电平)。RS-232标准是正电平为0,负电平为1(±15V电平) 详见点击打开链接
2.串口设置步骤:
(1)串口时钟,GPIO时钟使能-->RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
(2)串口复位--->void USART_DeInit(USART_TypeDef* USARTx);--USART_DeInit(USART1); //复位串口 1
(3)GPIO端口模式设置-->GPIO_Init(); 模式设置为GPIO_Mode_AF_PP----【端口复用和重映射很不一样-点击打开链接--------区别:点击打开链接】
(4)串口参数初始化--->void USART_Init(USART_TypeDef* USARTx,USART_InitTypeDef*USART_InitStruct);
1)USART_InitTypeDef 类型的结构体指针:
USART_InitStructure.USART_BaudRate = bound; //波特率;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_None; //无硬件数据流控制,用于两个uart模块之间传输数据
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
2)串口数据收发:
USART_DR寄存器发送数据函数:void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
第二个入口参数很重要:RXNE(读数据寄存器非空)以及TC(发送完成)
判断发送是否完成(TC),操作库函数:USART_GetFlagStatus(USART1, USART_FLAG_TC);
(5)开启中断并且初始化NVIC-->NVIC_Init();(如果需要开启中断才需要这个步骤)
1)使能串口中断函数:void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,FunctionalState NewState)
*****接收数据的时候产生中断:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断【RXNE位被置位。它表明移位寄存器的内容被转移到RDR。换句话说,数据已经被接收并且可以被读出(包括与之有关的错误标志)------>*如果RXNE=1,上一个有效数据还在接收寄存器RDR上,可以被读出.;;如果RXNE=0,这意味着上一个有效数据已经被读走, RDR已经没有东西可读。当上一个有效数据在RDR中被读取的同时又接收到新的(也就是丢失的)数据时,此种情况可能发生。 】
发送数据结束时(TC,发送完成)产生中断:USART_ITConfig(USART1, USART_IT_TC, ENABLE);
******USART中断请求--标志说明
**TXE---->发送数据寄存器空
**CTS--->CTS标志
**TC--->发送完成
**TXNE--->接收数据就绪可读
**ORE--->检测到数据溢出
**IDLE--->检测到空闲线路
**PE--->奇偶检验错
**LBD--->断开标志
**NE或ORT或FE--->噪声标志,多缓冲通信中的溢出错误和帧错误
2)获取相应的中断状态(判断是哪个中断产生的):ITStatusUSART_GetITStatus(USART_TypeDef*USARTx, uint16_t USART_IT)
例:判断到底是否是串口发送完成中断 --->USART_GetITStatus(USART1, USART_IT_TC)
(6)编写中断处理函数--->USARTx_IRQHandler();
(7)串口数据收发:void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
(8)串口传输状态获取:FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
在主函数中编写UART1串口通信:
#include "stm32f10x.h"//必须加上,不然不能识别时钟函数等宏定义
#include "LED.h"void USART1_IRQHandler(void)//USART_IT_RXNE:接收到数据,就执行中断服务函数
{//在stm32f10x_usart.c文件中查找功能函数if(USART_GetITStatus(USART1,USART_IT_RXNE/*中断标志是什么,此处就应该写什么*/)){uint16_t res = USART_ReceiveData(USART1); //从串口接收到数据USART_SendData(USART1,res);//将数据从串口发出去LED0 = ~LED0;}
}
void my_uart_init(void)
{//参数结构定义--->应该写在函数开头处GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART1_para;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//PA9,PA10//端口重映射//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);USART_DeInit(USART1);//串口复位//GPIO端口模式设置GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//推免输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//USART1_TXGPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//USART1_RX//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//串口参数设置USART1_para.USART_BaudRate = 9600;USART1_para.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART1_para.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;USART1_para.USART_Parity = USART_Parity_No;USART1_para.USART_StopBits = USART_StopBits_1;USART1_para.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART1_para);//使能串口USART_Cmd(USART1,ENABLE);//中断配置USART_ITConfig(USART1,USART_IT_RXNE/*接收到数据 就出发中断*/,ENABLE);//触发中断标志//开启中断并初始化NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//串口中断函数NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//优先级NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//子优先级NVIC_Init(&NVIC_InitStruct);
}int main(void)
{LED_init();LED0 = 1;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组my_uart_init();while(1);}
//在stm32f10x_usart.c文件中查找功能函数if(USART_GetITStatus(USART1,USART_IT_RXNE/*中断标志是什么,此处就应该写什么*/)){uint16_t res = USART_ReceiveData(USART1); //从串口接收到数据USART_SendData(USART1,res);//将数据从串口发出去LED0 = ~LED0;}
}
void my_uart_init(void)
{//参数结构定义--->应该写在函数开头处GPIO_InitTypeDef GPIO_InitStruct;USART_InitTypeDef USART1_para;NVIC_InitTypeDef NVIC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//PA9,PA10//端口重映射//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);USART_DeInit(USART1);//串口复位//GPIO端口模式设置GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//推免输出GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;//USART1_TXGPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;//USART1_RX//GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//串口参数设置USART1_para.USART_BaudRate = 9600;USART1_para.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART1_para.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;USART1_para.USART_Parity = USART_Parity_No;USART1_para.USART_StopBits = USART_StopBits_1;USART1_para.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART1_para);//使能串口USART_Cmd(USART1,ENABLE);//中断配置USART_ITConfig(USART1,USART_IT_RXNE/*接收到数据 就出发中断*/,ENABLE);//触发中断标志//开启中断并初始化NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//串口中断函数NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//优先级NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//子优先级NVIC_Init(&NVIC_InitStruct);
}int main(void)
{LED_init();LED0 = 1;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组my_uart_init();while(1);}
回车:0x0d;换行:0x0a
使用串口2源代码:点击打开链接
printf("\r\n\r\n");---->将内容发送到主串口-【可在usart.c中修改】
如果喜欢的话,可以关注同名微信公众号“混沌无形”,有趣好文!
STM32F103mini教程学习总结与心得(二)---->串口通信相关推荐
- STM32F103mini教程学习总结与心得(五)---->通用定时器
关注同名微信公众号"混沌无形",有趣好文! 一.通用定时器的基本原理 1.三种STM32定时器区别 2.通用定时器功能特点描述 (1)STM32 的通用 TIMx (TIM2.TI ...
- STM32F103mini教程学习总结与心得(四)---->看门狗
关注同名微信公众号"混沌无形",有趣好文! 一.独立看门狗概述 1.看门狗的作用 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞, ...
- STM32F103mini教程学习总结与心得(三)---->中断
关注同名微信公众号"混沌无形",有趣好文! 1. NVIC中断优先级分组 (1)CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断 ...
- STM32F103mini教程学习总结与心得(一)
关注同名微信公众号"混沌无形",有趣好文! 1.引脚是否兼容5V的判断:引脚表中PF表示5V,原理图中有ADC的引脚为3.3V 2.PT:容忍5V,没有PT标示,就不能 3. 每组 ...
- 嵌入式系统 实验二 串口通信实验
实验二 串口通信实验 一.实验目的 1.)了解 USART 的基本特性: 2.)掌握用库函数操作 USART 的方法: 3.)掌握如何使用 STM32 的串口发送和接收数据. 二.实验环境 1.)硬件 ...
- 【蓝桥杯】单片机学习(7)——UART串口通信
UART串口通信 一.基础知识介绍 1.通信方式的分类 2.RS232通信接口 3.UART模块介绍 (1)串口控制寄存器SCON(可位寻址) (2)电源控制寄存器PCON(不可位寻址) (3)辅助寄 ...
- 树莓派学习笔记(五)串口通信
观看学习上官可编程陈立臣老师的树莓派视频, 在其过程中所记录的学习笔记 一.串口通信概念 1.串口通信用于多机通信 2.串口通信属于全双工通信,即双方可以同时进行交流 ...
- ESP32学习记录<三>串口通信
ESP32学习记录<三>串口通信 文章目录 ESP32学习记录<三>串口通信 前言 一.通过串口打印出数据 1.初始化串口 2.打印数据 二.串口控制LED亮灭 1.接收串口发 ...
- AutoLeaders控制组——51单片机学习笔记(定时器、串口通信)
本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...
最新文章
- 微服务架构之「 服务注册 」
- springboot:SpringBoot项目启动成功,但无法访问且提示404
- atlas单机模式代码_生存游戏竞争太大怎么办?在海盗游戏《ATLAS》也可佛系生存...
- c语言编程 float p,C语言编程经典例题
- 【Java】函数式编程思想-Lambda表达式
- 深度学习(三十)贪婪深度字典学习
- matlab三维货位图,遗传算法求三维立体仓库货位优化MATLAB源码
- php 网络是否通,测试网络连通性的命令是什么?
- Kubernetes 小白学习笔记(30)--kubernetes云原生应用开发-service mesh介绍
- mysql的填充因子_SQL SERVER中,什么是填充因子?
- dw常用标签_Dreamweaver代码大全DW常用代码
- 一文了解啤酒、葡萄酒、黄酒的种类
- 《九日集训》打卡第二天
- 算法---斐波那契思想
- Java面试知识学习(持续更新)
- 苹果汽车已上路测试,预计将于明年推出
- java入门—第二节(1)(数据类型)
- 我打碎了夕阳开头...
- 移动硬盘部分分区不能识别解决方法
- HNUST-OJ-2295:嘉嘉的队伍配置
热门文章
- vue 判断移动端、pc端
- Python接口测试之moco
- 嵌入式成长轨迹52 【Zigbee项目】【CC2430基础实验】【在PC用串口收数并发数】...
- pku2192(并查集+枚举)
- 授权MySQL账户访问指定数据库
- Elasticsearch数据迁移工具elasticdump工具
- 本地与服务器连接,更改连接使用的用户名,再次登录;如何操作.
- 提高对邮件的认识,两类邮件都要重视!!(不光有和客户的邮件工作方面的,还有单位的邮件一些联系事项),还有要自己看清楚邮件的全部内容,不要丢三落四!!
- 【数据仓库】数据集市
- 【Oracle】手工建库时启动到nomount状态时错误ORA-09925,ORA-01017