STM32-(08):USART通信基础
上一篇:STM32-(07):串行通信基础(164芯片) | 下一篇:STM32-(09):USART库函数方式编程 |
---|
USART通信
通用同步异步收发器<Universal Synchronous/Asynchronous Receiver/Transmitter>( USART )提供了一种灵活的方法来与使用工业标准 NRZ 异步串行数据格式的外部设备之间进行全双工数据交换。 USART 利用分数波特率发生器提供宽范围的波特率选择。
它支持同步单向通信和半双工单线通信。它也支持 LIN(局部互联网),智能卡协议和 irDA (红外数据组织 )SIRENDEC 规范,以及调制解调器( CTX / RTS )操作。它还允许许多处理器通信。
用于多缓冲器配置的 DMA 方式,可以实现高速数据通信。
• 全双工的异步通信
• 单线半双工通信
• 使用 DM A 的可配五的多緩冲通信
• 单独的犮送器和接收器使能位
• 检测标志
接 收 缓 冲 器 满
发 送 缓 冲 器 空
传 输 结 束 标 志
• 校验控制
发 送 校 验 位
对 接 收 数 据 进 行 校 验
• 四个饼误检測标志
• 10个带标志的中断源
引脚介绍
任何USART通信,需要用到2个对外连接的引脚:RxD、TxD:
RxD是输入引脚,用于串行数据接收;
TxD是输出引脚,用于串行数据发送。
SCLK:发送器时钟输出。(同步模式用到)
在 lrDA 模式里需要下列引脚:
lrDA_RDI:lrDA模式下的数据输入。
lrDA_TDO:lrDA模式下的数据输出。
调制解调器模式中需要:
nCTS:清除发送
nRTS:发送请求
数据的接收过程示意图
数据串行输入到移位寄存器(一般8位),寄存器满了之后一次性全部送到输入数据缓冲器,缓冲器中设置一些标志量,一些控制信号,内核就可以通过中断的信号把数据读进来,如果内核用的是PMA,就回自动决定数据往哪个内存中放,实现数据的接收。
数据的发送过程示意图
异步串行通信协议
异步串行通信协议需要定义以下5个内容:
1.起始位
2.数据位(8、9)一般8位,9位是带奇偶校验
3.奇偶校验值(9位包含)
4.停止位(1、1.5、2个周期)
5.波特率设置(速度)
范例如图:
一般可以应用到如下一些场合:
1.芯片间的近距离通信
2.与PC机之间的通信(下图中的RS232只是电平的转换)
3.模块之间的远距离通信
RS-485通信电路示意图
RS-485接口的最大传输距离可以达3000米,最高传输速率10Mbps,且抗噪声干扰性好。
RS-485的电气特性:逻辑“1”以两线间的电压差为 +2V ~ +6V 表示:逻辑“0”以两线间的电压差为 -2 ~ -6V 表示。接口信号电平比 RS-232-C 降低了,该电平与TTL 电平兼容,柯方便与TTL电路连接。
数据发送过程
1.通过在USART_CR1寄存器上置位UE来激活USART
2.编程USART_CR1的M位来定义字长。
3.在USART_CR2中编程停止位的位数。
4.如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。
5.设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。
6.利用USART_BRR寄存器选择要求的波特率。
7.把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。
数据接收过程
1.将 USART_CR1寄存器的 UE 置1来激活 USART 。
2.编程 USART_CR1的 M 位定义字长
3.在 USART_CR2中编写停止位的个竣
4.如果需多缓冲器通信,选择 USART2_CR3中的 DMA 使能位( DMAT )。按多缓冲器通信所要求两配置 DMA 寄存器。
5.利用波特率寄存器 USART_ BRR 选择希望的波特率。
6.设置 USART_CR1的 RE 位。激活接收器,使它开始寻找起始位。
当一字符被接收到时:
RXNE 位被置位。它表明移位寄存器的内容被转移到 RDR 。
如果 RXNEIE 位被设置,产生中断。
在接收期间如果检测到帧错误,噪音或溢出错误,错 误标志将被置起.
涉及到的主要寄存器寄存器
1 | 2 | 2 | |
---|---|---|---|
1.状态寄存器 (Status register) |
|||
2.数据寄存器 | |||
3.波特率寄存器 | |||
4.控制寄存器1 | |||
5.控制寄存器2 | |||
6.控制寄存器3 |
代码
//main.c//----------------头文件声明--------------------
#include"stm32f10x_lib.h" //包含所有的头文件
#include<stdio.h>
//----------------函数声明--------------------
void Delay_MS(u16 dly);
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(u32 BaudRate);#define PA1 GPIOA->BSRR
#define PA0 GPIOA->BRR#define GPIOA_ODR_A (GPIOA_BASE+0x0C)
#define GPIOA_IDR_A (GPIOA_BASE+0x08)
#define GPIOB_ODR_A (GPIOB_BASE+0x0C)
#define GPIOB_IDR_A (GPIOB_BASE+0x08)
#define GPIOC_ODR_A (GPIOC_BASE+0x0C)
#define GPIOC_IDR_A (GPIOC_BASE+0x08)
#define GPIOD_ODR_A (GPIOD_BASE+0x0C)
#define GPIOD_IDR_A (GPIOD_BASE+0x08)
#define GPIOE_ODR_A (GPIOE_BASE+0x0C)
#define GPIOE_IDR_A (GPIOE_BASE+0x08)#define BitBand(Addr,BitNum) *((volatile unsigned long *)((Addr&0xF0000000)+0x2000000+((Addr&0xfffff)<<5)+(BitNum<<2)))#define PAout(n) BitBand(GPIOA_ODR_A,n)
#define PAin(n) BitBand(GPIOA_IDR_A,n)
#define PBout(n) BitBand(GPIOB_ODR_A,n)
#define PBin(n) BitBand(GPIOB_IDR_A,n)
#define PCout(n) BitBand(GPIOC_ODR_A,n)
#define PCin(n) BitBand(GPIOC_IDR_A,n)
#define PDout(n) BitBand(GPIOD_ODR_A,n)
#define PDin(n) BitBand(GPIOD_IDR_A,n)
#define PEout(n) BitBand(GPIOE_ODR_A,n)
#define PEin(n) BitBand(GPIOE_IDR_A,n)
/*******************************************************************************
* Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
int main(void)
{float Div;u16 M,F;u32 Bound,BRR;u8 data='A';//这里的两个函数都是利用库函数进行编程,下一篇文章会详细讲到RCC_Configuration(); //系统时钟设置GPIO_Configuration(); //GPIO设置,主要是TX,RX的引脚复用// 第一步:USART1模块的设置(参照手册一共有三个)://UE位使能、M位来定义字长、停止位的位数、TE位、BRR寄存器选择要求的波特率USART1->CR1 |= (1<<13); //USART_CR1的第13位为UE位,置1使能USART1->CR1 &= ~(1<<12); //USART_CR1的第13位为UE位,清0是 一个起始位,8个数据位,n个停止位USART1->CR2 &= ~(3<<12); //USART_CR2的第12、13位为停止位,置00 是表示1个停止位USART1->CR1 |= (1<<3); //USART_CR1的第3位为TE位,置1发送使能//关于波特率的设置,查看手册或者上方截图Bound = 9600;Div = (float)(72*1000*1000)/(Bound*16); //外设时钟为72MhzM = Div; //获取F = (Div-M)*16;BRR = M<<4|F;USART1->BRR = BRR; //第二步:发送一个字符‘A’到USART1的DRfor(F=0;F<30;F++){USART1->DR = data;data++;//USART_SR状态寄存器的第6位表示发送完成,为1表示发送完成,这里判断是否为0,为0继续等待while((USART1->SR & (1<<6))==0) ; }}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : Configures the different system clocks.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{//----------使用外部RC晶振-----------RCC_DeInit(); //初始化为缺省值RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟 while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer//FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait stateRCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLKRCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLKRCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZRCC_PLLCmd(ENABLE); //Enable PLLCLKwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is readyRCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clockwhile(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source//---------打开相应外设时钟--------------------RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外设的GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); //使能APB2外设的GPIOC的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE); }/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : 初始化GPIO外设
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* Configure USARTx_Tx as alternate function push-pull */ //第9脚复用为上拉GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure USARTx_Rx as input floating */ //第9脚复用为浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);}void USART_Configuration(u32 BaudRate)
{USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = BaudRate; 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_Mode_Rx; USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}
上一篇:STM32-(07):串行通信基础(164芯片) | 下一篇:STM32-(09):USART库函数方式编程 |
---|
STM32-(08):USART通信基础相关推荐
- STM32串行通信USART解说笔记
STM32串行通信USART程序例举链接:http://blog.csdn.net/dragon12345666/article/details/24883111 1.STM32串行通信USART的相 ...
- STM32用USART发送字符串,以USART_FLAG_TXE和USART_FLAG_TC怎么用
STM32用USART发送字符串,以USART_FLAG_TXE和USART_FLAG_TC怎么用 一:STM32用USART发送字符串 void UART_Send_Message(u8 *Data ...
- stm32之USART/UART应用实例(详细)
硬件:STM32F103VCT6 开发工具:Keil uVision4 下载调试工具:ARM仿真器 USART与UART的区别: usart:全双工通用同步/异步串行收发器 uart:全双工通用异步串 ...
- STM32的USART串口通讯程序(查询方式)
STM32的USART串口通讯程序(查询方式) 文章目录 STM32的USART串口通讯程序(查询方式) 一.USART介绍 1.异步通信: 2.同步通信: 二.CubeMX创建项目 1.点击ACCE ...
- 在 stm32CubeMX下生成程序完成流水灯以及完成STM32的USART串口通讯程序实现STM32系统给上位机(win10)连续发送“hello windows”
目录 一.STM32CubeMX简介及安装 二.利用STM32CubeMX生成代码 1.创建项目 2.配置芯片 3.导出项目 三.Keil中补充代码完善功能 四.在Keil中观察实验波形 五.US ...
- 嵌入式学习笔记——STM32的USART通信概述
文章目录 前言 常用通信协议分类及其特征介绍 通信协议 通信协议分类 1.同步异步通信 2.全双工/半双工/单工 3.现场总线/板级总线 4. 串行/并行通信 5. 有线通信.无线通信 STM32通信 ...
- STM32的USART中RTS、CTS的作用和意义
USART中RX和TX这两个引脚的功能,这两个引脚是USART串行通信最常见和必不可少的两个引脚.但我们在手册中会发现关于USART的其他引脚:USART_CK.USART_RTS.USART_CTS ...
- STM32系列 USART中断接收 注意事项 (USART_IT_ORE)
ZHL学习笔记 STM32系列USART中断接受注意事项 之 USART_IT_ORE USART_IT_ORE含义:接收溢出,尚未处理上一拍就迎来了下一拍数据: USART_IT_ORE使能:该中断 ...
- 了解串口协议,及完成STM32的USART串口通讯程序,并用keil观察波形
文章目录 前言 一.串口协议 1.RS-232 2.485标准 二.RS-232.485和TTL电平 1.RS-232电平 2.485 3.TTL电平 4.区别 三.USB/TTL转232 1.CH3 ...
- 清泉HAL库开发STM32之USART
文章目录 前言 一.USART硬件特征 1.物理层 2.协议层 二.STM32 的 USART 简介 USART 和UART 三.编程实战 串口阻塞式发数据 串口非阻塞式发数据 实践现象 总结 前言 ...
最新文章
- 顶级程序员的10条最佳实践
- python资源管理错误漏洞_国家信息安全漏洞库
- linux下利用valgrind工具进行内存泄露检测和性能分析
- 页面滚动效果库,有点儿皮!
- linux git 显示 分支,Linux 终端显示 Git 当前所在分支
- 出差一个多星期,买了个肥皂,把衬衫全部洗了一遍
- 元素可视区client系列(附实例)
- 软件工程需求分析方法
- c语言自学教程——博文总结
- c语言指针 汇编间接寻址,C语言指针和汇编语言间接寻址的关省略探讨从存储空间图的视角加以分析.pdf...
- 2012科技业大公司与大事件:苹果不再创新垄断(转)(二)
- 创建一个字体wx.Font
- 用vlookup在excel表格里查找数据
- 练习:数字时钟(Python 自定义类)
- 仿射密码 python实现
- Omni协议PHP开发包
- FFmpeg音频播放器(8)-创建FFmpeg播放器
- 【思维导图】人像摄影如何使用光线?十个小技巧
- python opencv关闭摄像头自动白平衡(white balance)
- 将excel数据导入到SQL server数据库,SQL server引入导入excel报表,如何解决“未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序”问题
热门文章
- 慧智微电子冲刺科创板:年亏3亿 大基金与红杉是股东
- html实现自动清理js、css文件的缓存
- React报错之React hook ‘useState‘ cannot be called in a class component
- JavaScript设计模式系统讲解与应用-笔记
- 微信小程序之map地图
- 计算机书在书架A上的英语,书架用英语怎么说
- VSCODE codeforces 插件
- PHP最新恶搞好友之伪视频通话模板源码
- 蓝桥杯第九届省赛B组c/c++
- Mysql 备份工具XtraBackup增量备份