当前位置: 首页 > news >正文

《嵌入式硬件(三):串口通信》

UART通信基础概念

并行与串行

  • 并行:同一时刻可传输多个比特
  • 串行:同一时刻仅传输一个比特

通信模式

  • 全双工:收发可同时进行
  • 半双工:收发不可同时进行
  • 单工:单向通信

串口通信格式(TTL电平)

        串口通信格式,以TTL为例

  1. 空闲时数据线为高电平;
  2. 发送发发送一个低电平表示起始位;
  3. LSB低位,MSB高位(先发低位),发送的第一个比特是最低为(最右边);
  4. 校验位分为奇校验,偶校验和无校验。奇校验是指确保数据位加上校验位中"1",1的总数为奇数;偶校验是指确保数据位加上校验位中"1",1的总数为偶数;Odd奇校验,enev,偶校验
  5. 为保证下一个字节发送前的起始位能够表现出来,校验位之后发送一个停止位1。

参数表示

  • 示例:9600, n, 8, 1
    • 波特率:9600
    • 校验位:无(n),Odd奇校验,enev偶校验
    • 数据位:8
    • 停止位:1

异步与同步判断

  • 同步:存在时钟线(SCL)
  • 异步:无时钟线

长距离通信问题与解决方案

主机间通信时的电器物理问题

        主机间通信无论采用并行还是串行方式,都无法避免一个物理现象:导线内阻不为零造成的电压衰减。以之前讨论的TTL电平为例,主机之间的距离会造成高电平在接收端出现衰减现象和串扰(指不同信号之间相互干扰导致信号失真)影响。TTL(Transistor-Transistor Logic)通常指的就是芯片引脚产生的电压,这个电压值跟选择的芯片有关,在51单片机系统下是5v;在2440下是3.3v等等。5vTTL通信距离通常被限制在10~20米之间。

解决长距离通信问题

        为解决这个问题IEEE(Institute of Electrical and Electronics Engineers)颁布了RS232标准,其中规定了:

        逻辑高电平(逻辑1):在-3V到-15V之间

        逻辑低电平(逻辑0):在+3V到+15V之间

        收发主机间有三根线,分别是收、发和地,因此RS232是全双工的。理论上RS232能够传输20~30米。

RS485的优势

        同理RS485使用两根信号线(A和B)来传输数据,通过比较A和B之间的电压差来识别信息,电压范围分别为+7V到+12V和-7V到-12V。正电压表示高电平,负电压表示低电平。这种差分信号传输方式提高了抗干扰能力。RS485的传输距离可达1200米,适用于大范围的数据传输需求。由于采用的是压差,RS485在传输数据的某一时刻,两根线都要用到,所以它是半双工的。

串口寄存器与波特率计算

寄存器配置

  • SCON:串口控制寄存器
  • PCON:电源控制寄存器(波特率倍增)
  •  

波特率公式
2^8-2^smod * focs / 32 / bps / 12

代码示例:数据类型大小测量

#include <reg52.h>
#include "delay.h"
#include <stdio.h>
#include <string.h>void init_uart(void)
{unsigned char t;t = SCON;t &= ~(3 << 6);t |= (1 << 6);t |= (1 << 4);SCON = t;t = IE;t |= (1 << 7);t |= (1 << 3);IE = t;PCON |= (1 << 7);t = TMOD;t &= ~(3 << 4);t |= (2 << 4);t &= ~(3 << 6);TMOD = t;TH1 = 204;TL1 = 204;TCON = (1 << 6);
}void send_char(char ch)
{SBUF = ch;while(0 == (SCON & (1 << 1)));SCON &= ~(1 << 1);
}void send_buffer(const char *p, int len)
{while(len--){send_char(*p++);}
}int main(void)
{int x;char y;const char *s = "Hello World!";int n = 10, m = 20;xdata char buffer[32];xdata char buffer1[1];init_uart();while(1){x = sizeof(int);sprintf(buffer, "size int = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(char);sprintf(buffer, "size char = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(float);sprintf(buffer, "size float = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(short);sprintf(buffer, "size short = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(double);sprintf(buffer, "size double = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(s);sprintf(buffer, "size * = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(short);sprintf(buffer, "size short = %d\n", x);send_buffer(buffer, strlen(buffer));x = sizeof(long);sprintf(buffer, "size long = %d\n", x);send_buffer(buffer, strlen(buffer));x = y;sprintf(buffer1, "big or small = %d", x);send_buffer(buffer1, strlen(buffer1));delay(0x9FFF);	}return 0;
}

输出结果示例
size int = 2
size char = 1
size float = 4
size short = 2
size double = 4
size * = 3
size short = 2
big or small = 0(大端)

主从通信协议解析

数据帧格式

  • 示例:AA 01 01 04 D2 82 0D
    • 起始符:AA
    • 从机地址:01
    • 功能码:01
    • 数据长度/寄存器地址:04
    • CRC16校验:D2 82
    • 结束符:0D

代码实现(解析帧)

        

#include <reg52.h>
#include "delay.h"
#include <stdio.h>
#include <string.h>
#include "digiter.h"void init_uart(void)
{unsigned char t;t = SCON;t &= ~(3 << 6);t |= (1 << 6) | (1 << 4);SCON = t;PCON |= (1 << 7);IE |= (1 << 7) | (1 << 4);t = TMOD;t &= ~(3 << 4);t |= (2 << 4);t &= ~(3 << 6);TMOD = t;TH1 = 204;TL1 = 204;TCON |= (1 << 6);
}xdata char rcv_buffer[64] = {0};
int pos = 0;				  void uart_handler(void) interrupt 4
{if((SCON & (1 << 0)) != 0){rcv_buffer[pos++] = SBUF;SCON &= ~(1 << 0);}
}void send_char(char ch)
{SBUF = ch;while((SCON & (1 << 1)) == 0);SCON &= ~(1 << 1);
}void send_buffer(const char *p, int len)
{while(len--){send_char(*p++);}	
}int digiter_num = 0;unsigned char sumOfTheArray(unsigned char *p, int len)
{unsigned char sum = 0;int i;for(i = 0;i < len;++i){sum += p[i];}return sum;
}void parse(void)		   //0xAA 0000 0000 1010 1010     unsigned char 
{if((unsigned char)rcv_buffer[0] == 0xAA && (unsigned char)rcv_buffer[pos - 1] == 0x0D){if((unsigned char)rcv_buffer[1] == 0x01){if(sumOfTheArray(rcv_buffer, 5) == (unsigned char)rcv_buffer[5]){unsigned char order;order = rcv_buffer[2];switch(order){case 1:digiter_num = 1234;break;case 2:P2 = 0;	break;default:break;}}}}
}int main(void)
{init_uart();while(1){if(pos != 0){delay(0xFFFF);	//0x04 	0xD2parse();	pos = 0;memset(rcv_buffer, 0, sizeof(rcv_buffer));}show_number(digiter_num);}return 0;
}

关键点总结

  • 校验和计算需匹配帧内数据
  • 中断处理接收数据时需清标志位

文章转载自:

http://yWF9puPi.rjypL.cn
http://kXoN2CHs.rjypL.cn
http://rI6sjzkJ.rjypL.cn
http://PD0yYLMv.rjypL.cn
http://Hdd69odv.rjypL.cn
http://BNw82a8g.rjypL.cn
http://MjD4lNuk.rjypL.cn
http://Dxbjbj6r.rjypL.cn
http://Jg6E3Z7x.rjypL.cn
http://DMJppwxn.rjypL.cn
http://xWu3HCXn.rjypL.cn
http://0Iv7Im9X.rjypL.cn
http://vG9CVMuA.rjypL.cn
http://B9xEKcKK.rjypL.cn
http://DidDJREn.rjypL.cn
http://z8gBfgXT.rjypL.cn
http://3Q9HDZTu.rjypL.cn
http://p89mSkCg.rjypL.cn
http://UIsi8kIZ.rjypL.cn
http://dPTE7xsS.rjypL.cn
http://iPELzxbF.rjypL.cn
http://Ls0Wwgeg.rjypL.cn
http://nQxk3yjq.rjypL.cn
http://vurjIwDB.rjypL.cn
http://bQ2N2GSW.rjypL.cn
http://lwu3hii1.rjypL.cn
http://wn6kTkpp.rjypL.cn
http://2gxrKhD2.rjypL.cn
http://7ovoKF4B.rjypL.cn
http://DLdgXfrP.rjypL.cn
http://www.dtcms.com/a/369021.html

相关文章:

  • python库 Py2exe 的详细使用(将 Python 脚本变为Windows独立软件包)
  • 激光雷达与IMU时间硬件同步与软件同步区分
  • 《基于stm32的智慧家居基础项目》
  • Docker在Windows与Linux系统安装的一体化教学设计
  • sub3G和sub6G的区别和联系
  • 【存储选型终极指南】RustFS vs MinIO:5大维度深度对决,95%技术团队的选择秘密!
  • 【Python基础】 18 Rust 与 Python print 函数完整对比笔记
  • Rust Axum 快速上手指南(静态网页和动态网页2024版)
  • CVPR 2025|无类别词汇的视觉-语言模型少样本学习
  • 9月14日 不见不散|2025年华望M-Design v2软件线上发布会
  • 疯狂星期四文案网第61天运营日记
  • 还在堆模型、拼算力?醒醒吧!你的AI项目99%会死于数据
  • DL3382P6平替RClamp3382P.TCT
  • 硬件基础:串口通信
  • 华为在国内搞的研发基地有多野?标杆游学带你解锁“研发界顶流”
  • LangChain关于提示词的几种写法
  • openharmony之AV_CodeC音视频编解码模块详解(二)
  • 【明道云】[工作表控件9] 子表控件:一对多数据建模实战指南
  • Linux/UNIX系统编程手册笔记:DAEMON、编写安全的特权程序、能力、登录记账
  • Docker部署PanSou 一款开源网盘搜索项目,集成前后端,一键部署
  • 【服务器】英伟达M40显卡风冷方案心得
  • Process Explorer 学习笔记(第三章3.3.1):DLL和句柄
  • 解锁无限创意:Tldraw+cpolar如何通过内网穿透技术打破空间限制
  • 安全沙箱配置针对海外vps容器隔离的验证方法
  • SQL-DML
  • 数据库原理及应用_数据库基础_第4章关系模型的基本理论_触发器
  • RWA点亮新能源的数字未来
  • css margin外边距重叠/塌陷问题
  • 【Python - 基础 - 规范】(01)Python命名规范...
  • 高级RAG策略学习(四)——上下文窗口增强检索RAG