做外汇最好的财经网站,晋江模板建站,网络建设网站有关知识,php做电商网站一、标准串口#xff08;UART#xff09;介绍
1、通信协议相关概念
1.1同步通信和异步通信
(1)同步通信#xff1a;两个器件之间共用一个时钟线#xff0c;要发送的数据在时钟的作用下一位一位发送出去。 #xff08;2#xff09;异步通信#xff1a;指两个器件之间没…一、标准串口UART介绍
1、通信协议相关概念
1.1同步通信和异步通信
(1)同步通信两个器件之间共用一个时钟线要发送的数据在时钟的作用下一位一位发送出去。 2异步通信指两个器件之间没有时钟线连接器件接受/发送数据时使用各自的时钟以不同的时钟频率进行通信。 1.2串行与并行通信
1串行通信只有一根数据线各个数据位通过数据线按照顺序一位一位的传输。
优点:稳定性高、简单、成本低
缺点速度慢
2并行通信有多根数据线各个数据位同时传输。
优点速度快。
缺点稳定性不高、设计复杂、成本高。占用引脚资源多
1.3单工、半双工、全双工通信
(1)单工数据只能由设备A到设备B不能从设备B到设备A任何时候只能是一个方向如遥控器。 (2)半双工设备A发送数据给设备B或者设备B发送数据给设备A。数据可以在两个方向上传输。同一时刻数据只能在一个方向传输传输方向可切换的单工通信接收端和发送端可以使用一个端口扩展。如对讲机。 3全双工设备A发送数据给设备B的同时设备B也可以发送数据给设备A。允许数据同时在两个方向上传输发送接收互补影响所以需要独立的接收端和发送端。 2、标准串口UART概念及其作用
2.1概念串口也称串行通信接口是一种MCU与其他器件通信的通信协议。
2.2作用主要用于芯片与芯片之间、模块与芯片之间、模块与模块之间按照这种通信协议进行数据交换。如STM32F4XX 和 GSM ,WIFE.北斗.语音5G模块等。
2.2.1标准UART的协议类型及拓扑接口接口标准
底层接口规范
标准UART的协议类型异步串行全双工。没有时钟线一条发送数据线一条接收数据线
RXD数据接收管脚R receive接受
TXD数据发送管脚T transmit发送
注意地线在硬件上一定要接否则数据不正常。
2.2.2标准UART的数据帧格式
数据帧格式将要发送的真正的信息和其它通信必须的信号封装成一包数据这一包数据包含以下几个内容。 标准UART中一帧数据1位起始位5~8数据位1位校验位0.5~2位停止位。
空闲电平数据线不传输数据时的状态该状态为高电平。
起始位该状态为低电平占用一个bit代表通信开始。 数据位真正传输的数据占用5~8bit。 校验位为了检测数据传输的正确与否。占用1bit。
一般不用奇偶校验位奇校验1000 1100 0 偶校验1110 0000 1 停止位该状态为高电平占用0.5~2bit代表通信结束。
2.2.3标准串口速率控制 什么是波特率波特率的作用是什么? (1)波特率的作用和概念: 当接收和发送器件的时钟频率不一致时为了让数据可以正确的收发所以双方要规定好一个合适的频率进行通信规定的这个频率称之为波特率,波特率又叫比特率。 (2)波特率单位时间内传输的二进制代码的有效位数其常用单位为每秒比特数bit/s(bps bit per second)。 (3)常用的波特率115200、38400、9600,每秒能传输多少位数据。 总结标准UART的四要素波特率通讯速率数据位长度校验位停止位长度。
二、串口的概述
串口是模块是芯片内部的一个片内外设。 STM32F407单片机内部共有6个串口
1.USART介绍
名词解析USART Universal Synchronous/Asynchronous ReceiverTransmitters
U:通用的 S:同步 A:异步 R:接受 T:发送 通用同步异步收发器 (USART) 能够灵活地与外部设备进行全双工数据交换满足外部设备对工业标准 NRZ 异步串行数据格式的要求。 2.UART框图分析 2.1管脚部分
TX发送数据管脚
RX接收数据管脚
2.2数据发送/接收部分 CPU定义一个8位或者9位的数据并写入到数据寄存器DR 1发送数据’A’ USART-DR ’A’;
(cpu)读取接收数据寄存器(DR)里的值。(人为) 2接受数据int a USART-DR;
串口通讯流程 2.3波特率设置
USART 通过小数波特率发生器提供了多种波特率。 2.4控制部分及寄存器分析 三、UART相关寄存器介绍
状态寄存器 (USART_SR) 位 7 TXE发送数据寄存器为空 (Transmit data register empty) 当 TDR 寄存器的内容已传输到移位寄存器时该位由硬件置 1。 如果 USART_CR1 寄存器 中 TXEIE 位 1则会生成中断。通过对 USART_DR 寄存器执行写入操作将该位清零。 0数据未传输到移位寄存器 1数据传输到移位寄存器 位 6 TC发送完成 (Transmission complete) 如果已完成对包含数据的帧的发送并且 TXE 置 1则该位由硬件置 1。如果 USART_CR1 寄存器中 TCIE 1则会生成中断。该位由软件序列清零读取 USART_SR 寄存器然后写入 USART_DR 寄存器。TC 位也可以通过向该位写入‘0’来清零。建议仅在多缓冲区通信时使用此清零序列。 0传送未完成 1传送已完成 位 5 RXNE读取数据寄存器不为空 (Read data register not empty) 当 RDR 移位寄存器的内容已传输到 USART_DR 寄存器时该位由硬件置 1。如果 USART_CR1 寄存器中 RXNEIE 1则会生成中断。通过对 USART_DR 寄存器执行读入操作将该位清零。RXNE 标志也可以通过向该位写入零来清零。建议仅在多缓冲区通信时使用此清零序列。 0未接收到数据 1已准备好读取接收到的数据 位 4 IDLE检测到空闲线路 (IDLE line detected) 检测到空闲线路时该位由硬件置 1。如果 USART_CR1 寄存器中 IDLEIE 1则会生成中 断。该位由软件序列清零读入 USART_SR 寄存器然后读入 USART_DR 寄存器。 0未检测到空闲线路 1检测到空闲线路 注意直到 RXNE 位本身已置 1 时即当出现新的空闲线路时IDLE 位才会被再次置 1。
2.数据寄存器 (USART_DR) 位 8:0 DR[8:0]数据值 包含接收到数据字符或已发送的数据字符具体取决于所执行的操作是“读取”操作还是“写入”操作。 因为数据寄存器包含两个寄存器一个用于发送 (TDR)一个用于接收 (RDR)因此它具有双重功能读和写。 3.波特率寄存器 (USART_BRR)
位 31:16 保留必须保持复位值 位 15:4 DIV_Mantissa[11:0]USARTDIV 的尾数 这 12 个位用于定义 USART 除数 (USARTDIV) 的尾数 位 3:0 DIV_Fraction[3:0]USARTDIV 的小数 这 4 个位用于定义 USART 除数 (USARTDIV) 的小数。当 OVER8 1 时不考虑 DIV_Fraction3 位且必须将该位保持清零。 注意 如果 TE 或 RE 位分别被禁止则波特计数器会停止计数。 4.控制寄存器 1 (USART_CR1)
位 15 OVER8过采样模式 (Oversampling mode) 016 倍过采样 18 倍过采样 //过采样就是为得到一个信号真实情况需要用一个比这个信号频率高的采样信号去检测也就是将串口接收的速度提高了16倍就是采样速度提高16倍即会采样更多 的点来确定数据的正确性但为了得到越高频率采样信号越也困难运算和功耗等等也会增加所以一般选择合适就好。 位 13 UEUSART 使能 (USART enable) 该位清零后USART 预分频器和输出将停止并会结束当前字节传输以降低功耗。此位由软件置 1 和清零。 0禁止 USART 预分频器和输出 1使能 USART 注意串口全部配置好最后打开此位 位 12 M字长 (Word length) 该位决定了字长。该位由软件置 1 或清零。 01 起始位8 数据位n 停止位 11 起始位9 数据位n 停止位 位 3 TE发送器使能 (Transmitter enable) 该位使能发送器。该位由软件置 1 和清零。 0禁止发送器 1使能发送器 位 2 RE接收器使能 (Receiver enable) 该位使能接收器。该位由软件置 1 和清零。 0禁止接收器 1使能接收器并开始搜索起始位 5.控制寄存器 2 (USART_CR2)
位 13:12 STOP停止位 (STOP bit) 这些位用于编程停止位。 001 个停止位 010.5 个停止位 102 个停止位 111.5 个停止位
6.外设时钟使能寄存器 USART是学习STM32F407ZGT6的第一个外设这个外设如果要正常工作需要开启相应的时钟打开开关。USART外设接在哪条总线上。《STM32F407ZGT6数据手册》第二章节芯片框架中有。开启RCC相关寄存器配置。 (1).RCC APB1 外设时钟使能寄存器 (RCC_APB1ENR)
位 20 UART5ENUART5 时钟使能 (UART5 clock enable) 由软件置 1 和清零。 0禁止 UART5 时钟 1使能 UART5 时钟 位 19 UART4ENUART4 时钟使能 (UART4 clock enable) 由软件置 1 和清零。 0禁止 UART4 时钟 1使能 UART4 时钟 位 18 USART3ENUSART3 时钟使能 (USART3 clock enable) 由软件置 1 和清零。 0禁止 USART3 时钟 1使能 USART3 时钟 位 17 USART2ENUSART2 时钟使能 (USART2 clock enable) 由软件置 1 和清零。 0禁止 USART2 时钟 1使能 USART2 时钟 2RCC APB2 外设时钟使能寄存器 (RCC_APB2ENR) 位 5 USART6ENUSART6 时钟使能 (USART6 clock enable) 由软件置 1 和清零。 0禁止 USART6 时钟 1使能 USART6 时钟位 4 USART1ENUSART1 时钟使能 (USART1 clock enable) 由软件置 1 和清零。 0禁止 USART1 时钟 1使能 USART1 时钟 四、硬件分析 五、软件分析 配置GPIO口 1. 打开GPIOA的时钟 2. 配置PA9和PA10为复用模式 3. 推挽类型 4. 不需要上下拉 5. 速度2M 6. 复用到哪里 配置USART 1. 打开USART1外设时钟 2. 配置CR1寄存器16倍过采样8位字长接收器和发送器使能无奇偶校验 3. 配置停止位CR2 4. 配置波特率BRR 5. 使能USART1 6. 发送数据出去DR
#include usart1.h/************************************
函数功能USART1初始化
函数形参u32 baud -- 波特率
函数返回值void
函数说明PA9 -- 复用到USART1_TXPA10 -- 复用到USART1_RX
作者
日期
************************************/
void Usart1_Init(u32 baud)
{float USARTDIV 0;u16 DIV_Man 0;u16 DIV_Fra 0;// 一.配置GPIO口//1.打开GPIOA的时钟RCC-AHB1ENR | 0X1 0;//2.配置PA9和PA10为复用模式GPIOA-MODER ~(0XF 9 *2);GPIOA-MODER | 0XA 9*2;//3.复用到哪里往复用高位寄存器的9号和10号管脚写7GPIOA-AFR[1] ~(0XFF 4);GPIOA-AFR[1] | (0X77 4);// 二.配置USART//1.打开USART1外设时钟RCC-APB2ENR | 0X1 4;//2.配置CR1寄存器USART1-CR1 0;/*16倍过采样1 起始位 8 数据位 n 停止位无奇偶校验*/USART1-CR1 | 0X3 2;//接收器和发送器都使能了//3.配置1个停止位CR2USART1-CR2 ~(0X3 12);//4.配置波特率BRRUSARTDIV FPCLK / baud / 16;DIV_Man USARTDIV;DIV_Fra (USARTDIV - DIV_Man) *16;USART1-BRR DIV_Man 4 | DIV_Fra;//5.使能USART1USART1-CR1 | 0X1 13;}/************************************
函数功能使用USART发送字符串
函数形参u8 *str
函数返回值void
函数说明可以通过USART1的DR寄存器发送数据到电脑上
作者
日期
************************************/
void Send_String(u8 *str)
{while(*str ! 0){if(USART1-SR (0X1 7)){USART1-DR *str;str;//只有成功发出去才进行偏移}}
}RECEVICE rec_str {0};
/************************************
函数功能接受一个字符串
函数形参void
函数返回值void
函数说明要有一个接收电脑传过来数据的数组当前数组的长度有一个接收完成的标志位利用一个特定的字符来判断什么时候接受完数据
作者
日期
************************************/
void Receive_String(void)
{if(USART1-SR (0X1 5))//判断什么时候接受到数据{if(USART1-DR ! \n){rec_str.rec_buff[rec_str.len] USART1-DR;}else{rec_str.rec_buff[rec_str.len] USART1-DR;rec_str.rec_buff[rec_str.len] \0;rec_str.len 0;//让下一次存储的字符串又从0号元素下标开始rec_str.flag 1;//接收完成标志位可以让别人知道接收完整个字符串} }
}//printf支持
#pragma import(__use_no_semihosting_swi) //取消半主机状态struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;int fputc(int ch, FILE *f) {while((USART1-SR (0X017))0);USART1-DRch;return (ch);
}
int ferror(FILE *f) {/* Your implementation of ferror */return EOF;
}void _ttywrch(int ch) {while((USART1-SR (0X017))0);USART1-DRch;
}void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}#ifndef __USART_H_
#define __USART_H_#include stm32f4xx.h
#include io_bit.h
#include stdio.h#define FPCLK 84000000
#define BUFFSIZE 256typedef struct{u8 rec_buff[BUFFSIZE];//定义一个接收数据的数组u8 len; //当前接收到的数据的长度u8 flag;//表示当前接收到的数据已经是一个字符串的形式了
}RECEVICE;
extern RECEVICE rec_str;void Usart1_Init(u32 baud);
void Send_String(u8 *str);
void Receive_String(void);
#endifint main(void)
{Usart1_Init(9600);printf(111);while(1){Receive_String();//不断的接收数据if(rec_str.flag 1){rec_str.flag 0;//首先把标志位清零printf(接收到的字符串%s\r\n,rec_str.rec_buff);memset(rec_str.rec_buff,0,sizeof(rec_str.rec_buff));}}
}