关注同名微信公众号“混沌无形”,有趣好文!

一、串口原理

1.处理器与外部设备通信的两种方式:并行通信(速度快,占用资源多)+串行通信(反之)

2.串行通信(按照数据传送方向分类):

(1)单工:数据传输只支持数据在一个方向上传输

(2)半双工:允许数据在两个方向上传输,但在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信

(3)全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立 的接收和发送能力。

串行通信三种传送方式
3.串行通信的通信方式
(1)同步通信:带时钟同步信号传输--->SPI,IIC通信 【时钟线+数据线】
(2)异步通信:不带时钟通信信号------>UART(通用异步收发器),单总线 【约定波特率】
常见的串行通信接口

4.STM32的串口通信接口

(1)UART:通用异步收发器
(2)USART:通用同步异步收发器

UART异步通信方式引脚连接方法
STM32F10X的串口对应针脚
5.UART异步通信方式特点:
全双工异步通信。
分数波特率发生器系统,提供精确的波特率(波特率决定数据传输速度)。
-发送和接受共用的可编程波特率,最高可达4.5Mbits/s
可编程的数据字长度(8位或者9位);
可配置的停止位(支持1或者2位停止位);
可配置的使用DMA多缓冲器通信。
单独的发送器和接收器使能位。
检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志
多个带标志的中断源。触发中断。
其他:校验控制,四个错误检测标志。
串口通信过程

6.串口异步通信需要定义的参数:

起始位
数据位(8位或者9位)
奇偶校验位(第9位)--->偶校验:如果数据位8位中,1的个数为偶数,则校验位为0,反之为1;奇校验相反
停止位(1,15,2位)
波特率设置---->点击打开链接

通信位
7.常用的串口相关寄存器
(1)USART_SR状态寄存器
(2)USART_DR数据寄存器
(3)USART_BRR波特率寄存器
8.串口操作函数(省略入口参数)
void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能
void USART_Cmd();//使能串口
void USART_ITConfig();//使能相关中断
DR寄存器操作:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
SR寄存器操作:
FlagStatus USART_GetFlagStatus();//获取状态标志位
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);

USART_DR寄存器读取串口接收到的数据函数:uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
3)串口状态读取:
*RXNE(读数据寄存器非空),当该位被置1的时候,就是提示已经有数据被接收到。
*TC(发送完成),当该位被置位的时候,表示USART_DR内的数据已经被发送完成。如果设置了这个位的中 断,则会产生中断。
 
*读取串口状态的函数:FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
第二个入口参数很重要:RXNE(读数据寄存器非空)以及TC(发送完成)
判断读寄存器是否非空(RXNE),操作库函数:USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
判断发送是否完成(TC),操作库函数:USART_GetFlagStatus(USART1, USART_FLAG_TC);
4)串口使能----->USART_Cmd(USART1, ENABLE);

(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教程学习总结与心得(二)---->串口通信相关推荐

  1. STM32F103mini教程学习总结与心得(五)---->通用定时器

    关注同名微信公众号"混沌无形",有趣好文! 一.通用定时器的基本原理 1.三种STM32定时器区别 2.通用定时器功能特点描述 (1)STM32 的通用 TIMx (TIM2.TI ...

  2. STM32F103mini教程学习总结与心得(四)---->看门狗

    关注同名微信公众号"混沌无形",有趣好文! 一.独立看门狗概述 1.看门狗的作用 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞, ...

  3. STM32F103mini教程学习总结与心得(三)---->中断

    关注同名微信公众号"混沌无形",有趣好文! 1. NVIC中断优先级分组 (1)CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断 ...

  4. STM32F103mini教程学习总结与心得(一)

    关注同名微信公众号"混沌无形",有趣好文! 1.引脚是否兼容5V的判断:引脚表中PF表示5V,原理图中有ADC的引脚为3.3V 2.PT:容忍5V,没有PT标示,就不能 3. 每组 ...

  5. 嵌入式系统 实验二 串口通信实验

    实验二 串口通信实验 一.实验目的 1.)了解 USART 的基本特性: 2.)掌握用库函数操作 USART 的方法: 3.)掌握如何使用 STM32 的串口发送和接收数据. 二.实验环境 1.)硬件 ...

  6. 【蓝桥杯】单片机学习(7)——UART串口通信

    UART串口通信 一.基础知识介绍 1.通信方式的分类 2.RS232通信接口 3.UART模块介绍 (1)串口控制寄存器SCON(可位寻址) (2)电源控制寄存器PCON(不可位寻址) (3)辅助寄 ...

  7. 树莓派学习笔记(五)串口通信

    观看学习上官可编程陈立臣老师的树莓派视频, 在其过程中所记录的学习笔记 一.串口通信概念 1.串口通信用于多机通信 2.串口通信属于全双工通信,即双方可以同时进行交流                  ...

  8. ESP32学习记录<三>串口通信

    ESP32学习记录<三>串口通信 文章目录 ESP32学习记录<三>串口通信 前言 一.通过串口打印出数据 1.初始化串口 2.打印数据 二.串口控制LED亮灭 1.接收串口发 ...

  9. AutoLeaders控制组——51单片机学习笔记(定时器、串口通信)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

最新文章

  1. 微服务架构之「 服务注册 」
  2. springboot:SpringBoot项目启动成功,但无法访问且提示404
  3. atlas单机模式代码_生存游戏竞争太大怎么办?在海盗游戏《ATLAS》也可佛系生存...
  4. c语言编程 float p,C语言编程经典例题
  5. 【Java】函数式编程思想-Lambda表达式
  6. 深度学习(三十)贪婪深度字典学习
  7. matlab三维货位图,遗传算法求三维立体仓库货位优化MATLAB源码
  8. php 网络是否通,测试网络连通性的命令是什么?
  9. Kubernetes 小白学习笔记(30)--kubernetes云原生应用开发-service mesh介绍
  10. mysql的填充因子_SQL SERVER中,什么是填充因子?
  11. dw常用标签_Dreamweaver代码大全DW常用代码
  12. 一文了解啤酒、葡萄酒、黄酒的种类
  13. 《九日集训》打卡第二天
  14. 算法---斐波那契思想
  15. Java面试知识学习(持续更新)
  16. 苹果汽车已上路测试,预计将于明年推出
  17. java入门—第二节(1)(数据类型)
  18. 我打碎了夕阳开头...
  19. 移动硬盘部分分区不能识别解决方法
  20. HNUST-OJ-2295:嘉嘉的队伍配置

热门文章

  1. vue 判断移动端、pc端
  2. Python接口测试之moco
  3. 嵌入式成长轨迹52 【Zigbee项目】【CC2430基础实验】【在PC用串口收数并发数】...
  4. pku2192(并查集+枚举)
  5. 授权MySQL账户访问指定数据库
  6. Elasticsearch数据迁移工具elasticdump工具
  7. 本地与服务器连接,更改连接使用的用户名,再次登录;如何操作.
  8. 提高对邮件的认识,两类邮件都要重视!!(不光有和客户的邮件工作方面的,还有单位的邮件一些联系事项),还有要自己看清楚邮件的全部内容,不要丢三落四!!
  9. 【数据仓库】数据集市
  10. 【Oracle】手工建库时启动到nomount状态时错误ORA-09925,ORA-01017