zoukankan      html  css  js  c++  java
  • 51单片机UART通信与波特率的计算

    UART通信原理

    通讯过程描述

    1. 当没有通信信号时,通信线路保持高电平。
    2. 发送数据之前, 先发送一个0表示起位,表示起始位
    3. 接着发送8位数据位,数据位是先低后高的顺序。
    4. 数据位发送完毕,再发送一个1表示停止位

    通讯数据帧图

    • UART完整串行数据帧:

    UART模块的使用

    51单片机的 UART 串口的结构由串行口控制寄存器 SCON发送电路接收电路三部分构成。

    串口控制寄存器

    • SCON串行控制寄存器的位分配(地址为0x98, 可位寻址)
    7 6 5 4 3 2 1 0
    符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
    复位值 0 0 0 0 0 0 0 0
    符号 描述
    7 SM0 这两位共同决定了串口通信的模式0 ~模式 3 共 4 种模式 。 最常用的就是模式 1 ,也就是 SM0=0 SM1=1 ,其它模式从略。
    6 SM1
    5 SM2 多机通信控制位(极少用),模式 1 直接清零。
    4 REN 使能串行接收。由软件置位使能接收,软件清零则禁止接收。
    3 TB8 模式2 和 3 中要发送的第 9 位数据(很少用)。
    2 RB8 模式2 和 3 中接收到的第 9 位数据(很少用),模式 1 用来接收停止位。
    1 TI 发送中断标志位,当发送电路发送到停止位的中间位置时,TI 由硬件置 1必须通过软件清零。
    0 RI 接收中断标志位,当接收电路接收到停止位的中间位置时,RI 由硬件置 1必须通过软件清零。。
    • 串口模式1: 1 位起始位, 8 位数据位和 1 位停止位。

      • SM0 = 0; SM1 = 1;

    波特率

    波特率的概念

    • 波特率就是发送二进制数据位所用的时间,用baud表示。

    • 发送1位二进制数据的持续时间为1/baud

    波特率计算公式

    • 对于STC89C52单片机来说, 波特率发生器只能由定时器T1/T2产生,不能由T0产生。

    • 使用T1的模式2[自动重装模式], 定时器的重载值计算公式为:

      [TH1 = TL1 = 256 - 晶振值 / 12 / 2 / 16 / 波特率 ]

      • 256 : 定时器模式2(8位)的溢出值
      • 晶振值: 11059200
      • 12 : 一个机器周期(STC89C52中一个时钟周期等于12个时钟周期, 具体看芯片手册)
      • 16: 串口模块将一位信号采集16次,将其中7,8,9次取出来,如果这三次中两次如果是高电平就认为这位数据是1。
      • 波特率: 要设定的波特率
    • 电源管理寄存器PCON, 设置后它可以将波特率提高一倍

      PCON |= 0x80
      
      • 此时波特率公式为:

        [TH1 = TL1 = 256 - 晶振值 / 12 / 16 / 波特率 ]

    • 参考代码

      //  程序名称: uart/main.c
      //  程序简述: uart实例
      //  维护人员: ieeqc
      // 	创建日期:2020/9/13
      //	最后修改时间:2020/9/13
      
      /*
      	功能描述: 单片机usb接上计算机并实现通讯, 将其结果+1发送给计算机
      	
      	实现步骤:
      	- 1. 配置串口为模式1
      	- 2. 配置定时器T1为模式2
      	- 3. 根据波特率计算TH1和TL1的初值, 如果有需要则可以使用PCNF进行波特率加倍
      	- 4. 打开定时器控制寄存器, 让定时器跑起来
      	- 5. 开启UART中断, 1.接收并解析数据, 2.处理数据, 3.发送数据 
      	
      	程序注释:
      	- 波特率计算公式:
      		TH1 = TL1 = 256 - 晶振值 / 机器周期 / 2 / 16 / 波特率
      		- 机器周期: STC89C52RC的机器周期是'晶振/12'
      		- 16: 单片机uart模块会将每一个数据位取16次, 然后判断中间值来确定是'0'还是'1'
      	
      	- 波特率加倍:
      		PCON |= 0x80;那么计算公式为:
      			- TH1 = TL1 = 256 - 晶振值/12/16/波特率
      */
      
      
      #include<reg52.h>
      
      #define Crystal_Frequency 11059200 // 定义当前单片机的晶振频率
      #define BAUDRATE 9600	             // 定义当前单片机UART所采用的波特率
      
      
      void ConfigUART(unsigned int baud); // 串口初始化
      
      void main() {
      	EA = 1; // 打开使能总中断
      	ConfigUART(BAUDRATE);
      	while(1);
      }
      
      
      /* 串口配置函数, baud-通信波特率 */
      void ConfigUART(unsigned int baud) {
      	SCON = 0x50;  // 配置为串口为模式1
      	TMOD &= 0x0F; // 清0 T1的控制位
      	TMOD |= 0x20; // 配置T1为模式2
      	
      	TH1 = 256 - (Crystal_Frequency / 12 / 32) / baud; // 计算T1重载值
      	TL1 = TH1;  // 初值等于重载值
      	ET1 = 0;    // 禁止T1中断
      	ES = 1;     // 使能串口中断
      	TR1 = 1;    // 启动T1
      }
      
      
      /* 串口中断服务函数 */
      void Uart_Interrupt() interrupt 4 {
      	
      	if (RI) {// 接收到字节
      		RI = 0; // 手动清零接收中断标志位
      		SBUF = SBUF + 1; // 接收的数据 +1 后发回,左边是发送 SBUF ,右边是接收 SBUF
      	}
      	
      	if (TI) {// 字节发送完毕
      		TI = 0; // 手动清零 发送中断标志位
      	}
      }
      
  • 相关阅读:
    Android由一个activity 间隔5秒自动跳转到另外一个activity
    ZXing二维码的生成和解析
    JAVA生成条形码
    JAVA生成带Logo的二维码
    JAVA操作MongoDB数据库
    MongoDB数据库的简介及安装
    Redis在windows下的安装使用
    class关键字
    遍历器接口
    Promise对象
  • 原文地址:https://www.cnblogs.com/ieeqc/p/14563762.html
Copyright © 2011-2022 走看看