历史上的今天
返回首页

历史上的今天

今天是:2024年10月08日(星期二)

正在发生

2021年10月08日 | STM32笔记 (九)串口通讯USART(串口发送接收编程)

2021-10-08 来源:eefocus

简介

串口USART(Universal Synchronous Asynchronous Receiver and Transmitter)也叫通用同步异步收发器,是单片机与外部进行信息交互的重要通信接口,属于单片机的一种外设,几乎所有单片机都支持使用串口通讯,同时也是单片机程序调试的一种重要手段,对于STM32,串口资源非常丰富,功能也比较齐全,以STM32F103ZET6为例,就提供了5路的串口,我们一般用把串口用来在电脑的串口调试工具上打印调试信息,从而了解程序运行是否正确、如果出错的话也能知道是哪里出了错误。


通讯的有关概念

并行通讯

并行就是采用多条数据线进行通讯

优点是传输速度快,缺点是占用的引脚资源多

在这里插入图片描述

串行通讯

数据按位顺序传输,需要的信号线相比于并行通信来说少了很多,最简单的只需要三根线:RXD,TXD,GND,显然这种通讯方式的优点是占用的引脚资源少,缺点是传输速率不高

在这里插入图片描述

单工

数据传输只支持数据在【一个方向上】传输

在这里插入图片描述

半双工

允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是【一种切换方向】的【单工通信】

在这里插入图片描述

全双工

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

在这里插入图片描述

同步通讯

带【时钟同步信号】传输

如IIC通讯需要两根线,一根是SDA数据线,一根是SCL时钟线


异步通讯

【不带】【时钟同步】信号

也就是发出的信号可以不受时钟线的约束


USART的寄存器

状态寄存器(USART_SR)

数据寄存器(USART_DR)

波特比率寄存器(USART_BRR)

控制寄存器 1(USART_CR1)

控制寄存器 2(USART_CR2)

控制寄存器 3(USART_CR3)

保护时间和预分频寄存器(USART_GTPR)

USART的功能框图

在这里插入图片描述

初始化结构体中的各种参数

typedef struct {

uint32_t USART_BaudRate; // 波特率

uint16_t USART_WordLength; //数据字长

uint16_t USART_StopBits; // 停止位

uint16_t USART_Parity; // 奇偶校验位选择

uint16_t USART_Mode; // USART 模式

uint16_t USART_HardwareFlowControl; // 硬件流控制

} USART_InitTypeDef;


波特率

波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,

单位为波特,指的是一个设备在一秒钟内发送(或接收)了多少码元的数据(码元:又叫码率,单位为波特,一个脉冲信号就是一个码元),这里简单理解为传输数据的速率,波特率的计算有一个固定的公式

在这里插入图片描述

这里的fck是USART的时钟频率,一般是72MHz,USARTDIV是一个与波特率寄存器(USART_BRR)有关的数,波特率寄存器有16个位,前4个位用于配置USARTDIV的小数部分,后12个位用于配置整数部分,我们可以根据所需要配置的波特率从而算出USARTDIV的值,进而配置波特率寄存器的值


数据字长

可以选择8 位或 9 位,具体选择多少位要看后面检验位,如果开启了奇偶校验,那么就选9位,如果没有的话就选8位,也就是一个bit


停止位

串口在传输完数据的时候会有停止信号,这里设置的就是停止信号的长度,可选 0.5 个、 1 个、 1.5 个和 2 个停止位,一般选择1位


奇偶校验位选择

假设传输的数据位:1 1 1 0

那么偶校验位会根据数据位中的 1 的个数是否为偶数来补位(补成偶数个1),如果前面1是三个 那么此时偶校验位为 1 加起来一共有四个 1 是偶数,这时候偶校验位的值就为1

奇校验位的原理则与之相反


USART 模式

模式分为:接收模式,发送模式,如果不设置默认不能接收和发送,一般在设置的时候设置成两种模式都开,也就是收发模式


硬件流控制

很少用到,一般设置成无硬件数据流控制


初始化USART的流程

在这里插入图片描述

其中串口的接收端模式配置成浮空输入,输出端配置成复用推挽输出,为什么这样配置呢?具体怎么配置可以在参考手册的这里找到

使用串口在串口调试助手上输出HELLO WORLD

#include "stm32f10x.h"


void NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}


void USART_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

// 打开串口 GPIO USART1 的时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

//GPIOA_9  USART1 TX 配置为推挽复用模式

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//GPIA_10 USART1_RX 配置为浮空输入模式

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//配置USART1的参数

USART_InitStructure.USART_BaudRate = 115200;// 配置波特率

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 配置硬件流控制

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 配置工作模式,收发一起

USART_InitStructure.USART_Parity = USART_Parity_No;//配置校验位

USART_InitStructure.USART_StopBits = USART_StopBits_1;//配置停止位

USART_InitStructure.USART_WordLength = USART_WordLength_8b;//配置数据字长

USART_Init(USART1, &USART_InitStructure);// 完成串口的初始化配置

NVIC_Config();//配置NVIC

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能接收中断

USART_Cmd(USART1, ENABLE);// 使能串口

}


//发送一个Byte

void Usart_SendByte( USART_TypeDef * USARTx, uint8_t ch)

{

USART_SendData(USARTx,ch); //发送一个字节数据到 USART

while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);//等待发送数据寄存器为空

}


//发送一个字符串

void USART_SendStr(USART_TypeDef *USARTx,uint8_t *str)

{

uint8_t i = 0;

do

{

Usart_SendByte(USART1,*(str+i));

i++;

}while( *(str+i) != '');

//等待发送完成

while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);

}


int main(void)

{

USART_Config();

USART_SendStr(USART1,"HELLO WORLD!");

while(1)

{

}

}


void USART1_IRQHandler(void)

{

uint8_t ucTemp;

if (USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) 

{

ucTemp |= USART_ReceiveData( USART1 );

}

USART_SendStr(USART1,"n收到!");

}


在STM32中使用printf,putchar,scanf,getchar等函数

我们知道这几个函数是在C语言头文件stdio.h中的,由于我们使用的是运行于STM32的C语言,所以这几个函数并不能使用,但是现在我们会使用串口,而串口可以在串口调试工具中输出调试信息,出于习惯我们如果想使用这几个函数必须重定向这几个函数,具体步骤如下:


声明头文件

#include “stdio.h”


使用以下函数对这四个函数进行重定向

//发送数据

int fputc(int ch, FILE *f) 

USART_SendData(USART1, (unsigned char)ch);// USART1 可以换成 USART2 等其他串口 

while( !USART_GetFlagStatus(USART1,USART_FLAG_TXE) ); //等待数据被转移到移位寄存器。

return (ch); 

}

 

// 接收数据 

int GetKey (void)  

{  

while( !USART_GetFlagStatus(USART1,USART_FLAG_RXNE) ); //等待读数据寄存器接收到数据

return ((int)(USART1->DR & 0x1FF)); //数据寄存器有9位,这里取出9位

 } 


在工程属性的 “Target" > “Code Generation” 选项中勾选 “Use MicroLIB”

在这里插入图片描述

如何在打印出数据后换行

在字符串后面加上rn即可换行,即


printf("字符串rn");

推荐阅读

史海拾趣

Hitano Enterprise Corp公司的发展小趣事

机顶盒,全称为数字视频变换盒,是现代家庭娱乐不可或缺的重要设备之一。它作为连接电视与外部信号源的桥梁,不仅实现了传统模拟电视向数字电视的跨越,还极大地丰富了电视节目的选择和观看体验。

从专业角度来看,机顶盒的主要功能是接收数字电视信号,并将其转换成适合在电视机上播放的格式。无论是来自有线电缆、卫星天线、宽带网络还是地面广播的信号,机顶盒都能有效接收并解码,从而呈现出高清甚至超高清的画质和震撼的音效。此外,机顶盒还具备网络交互功能,用户可以通过它连接到互联网,享受在线购物、观看网络视频、玩游戏等多元化服务。

从科普层面讲,机顶盒的出现极大地改变了人们的电视观看方式。它不再局限于单向接收信息,而是成为了一个能够与用户进行互动的智能终端。通过机顶盒,观众可以自由选择观看的节目,甚至参与到节目的互动中,极大地提升了观看的参与感和乐趣。同时,机顶盒还提供了丰富的增值服务,如电子节目指南、因特网网页浏览等,进一步满足了用户的多样化需求。

综上所述,机顶盒以其强大的功能和广泛的应用场景,成为了现代家庭娱乐的重要组成部分。随着技术的不断进步和消费者需求的日益多样化,机顶盒的功能和应用场景也将不断扩展和丰富。

Burr-Brown公司的发展小趣事

2000年,Burr-Brown被著名的美国德州仪器公司(Texas Instruments)收购,成为其高性能模拟器件部门的一部分。这一收购为Burr-Brown提供了更强大的资源和支持,使其能够继续专注于模拟器件(如ADC、DAC等)的生产和创新。在德州仪器的引领下,Burr-Brown持续保持技术领先,为全球电子行业的发展做出了重要贡献。

这五个故事共同展现了Burr-Brown公司从创立到发展壮大的历程,以及其在电子行业中的卓越成就和持续创新的精神。通过不断适应市场变化和技术进步,Burr-Brown成功地在竞争激烈的电子行业中脱颖而出,成为一家备受尊敬的企业。

Allianc公司的发展小趣事

在XXXX年,Allianc公司迎来了一次重大的技术突破。公司研发团队成功开发出了一款具有领先性能的新型电子产品,该产品不仅具有更高的性能和更低的能耗,还具备更好的用户体验。这一技术突破使得Allianc公司在市场上迅速脱颖而出,赢得了大量客户的青睐。随着产品销量的不断攀升,公司的知名度和影响力也逐渐扩大。

AVX公司的发展小趣事

AVX一直致力于绿色技术的研发与应用。在数十年的深入研发支持下,AVX的产品为各种绿色技术提供了关键的支持,如风能、太阳能和水力发电等领域。这些技术的应用旨在节省现有能源并创建可靠、价格合理的电子系统,为可持续发展做出了积极贡献。AVX在这一领域的持续投入和创新,使其在绿色技术领域取得了显著成果。

CIF公司的发展小趣事

C公司是一家专注于电子产品贸易的CIF公司。为了降低成本、提高效率,C公司积极整合全球供应链资源,与多家优质的电子产品生产商建立了长期合作关系。通过优化采购、生产和物流等环节,C公司成功降低了运营成本,提高了市场竞争力。

DAYA公司的发展小趣事

大雅智能,一家以智能厨电产品为主的电子科技公司,自创立之初就致力于技术研发和创新。在电子行业竞争激烈的今天,大雅智能凭借其独特的智能控制技术,成功打造了一系列具有市场竞争力的产品。从最初的智能电饭煲到如今的智能厨房生态系统,大雅智能通过技术创新,不断满足消费者对智能生活的追求,逐渐在电子行业中崭露头角。

问答坊 | AI 解惑

网上挂单(开关电源高手请进)

本人由于某项产品开发试制,需要如下高频功率源,请有制作能力的高手帮忙制作一个,不甚感激!银子已经为您准备,具体请发邮件到obfyz@yahoo.com.cn详谈.一,输入:220V工频电压二,输出:  1.频率:1MHZ  2.波形:类正弦波  3. ...…

查看全部问答>

质量流量计原理

第一节 概 述 目前广泛应用的流量计,无论是差压式、靶式、涡轮、电磁或容积等型式,从原理上看都足测量容积流量的。由于流体的容积大小受其温度、压力等参数的影响,当被测流体的温度、压力坐化时,应把所测量的容积流量换算成标准状态 ...…

查看全部问答>

我也来玩玩多线程(终结篇)-LPC1114

前两个帖子里分别以不同的方式实现的LED的闪烁,今天再以信号量的方式来实现LED的闪烁。程序里一共用到了两个信号量,分别为io_sem和delay_sem,这两个信号量就类似一个互斥的变量,使得程序交替运行延时和IO反转的进程。下面上传源代码,同样附件 ...…

查看全部问答>

讨论下热电偶测温差的问题

讨论下用热电偶测温差的问题,有的书上介绍可以用热电偶反向串联变送器测温差,我的问提是  热电偶反向串联不是线性的,变送器处理的mv值是不等的.例如100度温差,在500度与400度时是4.058mv,而1000度与900度是3.98mv;变送器如何处理????????…

查看全部问答>

求cmos摄像头数据采集和视频压缩等方面的教程和资料~~~~~

我最近想用FPGA开发一个视频采集,需要查找cmos摄像头的采集的数据的格式,视频压缩算法,不知道哪位高人有这方面的开发经验或者有相关的资料或者教程,我的邮箱是xyg1985109@163.com。。。。 不胜感激!!…

查看全部问答>

SST Flash Sector 擦除问题(没多少分了)

为什么我的SST Flash的Block擦除都能够实现,但是不能实现Sector 擦除! 这是什么原因?我用的是SST 39VF6401B       我的代码:          Top[0x555] = 0x00aa;      &nbs ...…

查看全部问答>

NS2

谁有NS2的安装包,麻烦大家给我传一个吧,谢谢…

查看全部问答>

关于新唐cortex-m0 nano100系列的学习讨论

关于新唐cortex-m0 nano100系列的学习讨论 有哪位朋友在学习,我们可以共同学习哈,…

查看全部问答>

超声波测距程序,各位大神帮忙看看,谢谢了!

超声波程序       #include #define uint unsigned int #define uchar unsigned char uchar flag0 = 0;  //单片机发出10个脉冲标志位 uchar flag1 ;  //测量标志位 long time;     ...…

查看全部问答>

固定衰减器

本帖最后由 dontium 于 2015-1-23 11:22 编辑 很实用的东西 …

查看全部问答>