1.基本概念

(1)串行通信,并行通信

通信方式数据传输方式所需数据线数量传输速度传输距离抗干扰能力硬件成本常见接口/应用
串行通信数据一位一位 (bit) 依次传输少(通常 1 根数据线 + 控制线)相对较低(单次仅 1 bit),但可通过高速协议弥补长距离可靠(可达数米到数十公里)高(线少、同步机制强)成本低(布线简单)UART、SPI、I²C、USB、CAN、RS232、RS485
并行通信多个位(一般 8 位或 16 位)同时在多条线上并行传输多(一般 8/16/32 根数据线 + 控制线)高(一次传多个 bit)短距离(通常在 PCB 内或板间连接)差(易受时序偏差和干扰影响)成本高(线多、排布复杂)内存总线、CPU 与外设总线、老式打印机并口 (LPT)

(2)单工,半双工,全双工通信

通信方式传输方向是否可同时双向带宽利用率常见接口/标准典型应用场景举例
单工 (Simplex)只能单向传输低(仅一方使用通道)无特殊接口要求信息广播、数据采集收音机、电视广播、键盘输入
半双工 (Half Duplex)可双向传输,但同一时刻只能一个方向中等(通道可切换方向,但有等待时间)RS485、对讲机协议节点较多但不要求实时双向通信的总线系统对讲机、RS485 总线、旧式无线电台
全双工 (Full Duplex)可双向传输是(同时收发)高(收发通道同时利用)RS232、UART、TCP/IP、光纤通信实时交互、数据吞吐要求高电话、以太网、UART 串口通信

(3)什么是串口通信

串口通信:指通过串行接口(如 UART)逐位传输数据的通信方式。

(4)串口通信的通信时序

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

(5)串口通信的速率(波特率)

  • 决定因素

    • 串口的时钟频率(晶振 + 分频器)。

    • 通信双方必须设置为相同的波特率。

  • 常见波特率
    9600、19200、38400、57600、115200、230400 bps 等。

(6)同步通信、异步通信

  • 同步通信:通信双方共享同一个时钟信号,数据和时钟同步进行(如 SPI、I²C)。

  • 异步通信:没有公共时钟,用起始位/停止位来实现同步(如 UART)。

  • 串口通信(UART):属于 异步通信

(7)TTL,RS232,RS485

标准电平范围逻辑定义通信方式传输距离特点/应用场景
TTL0V(低) ~ 5V/3.3V(高)高电平=1,低电平=0单端< 1m芯片之间短距离通信,常见于 MCU、模块接口(如 STM32、Arduino 的 UART)
RS232-3V ~ -15V 表示逻辑 1;+3V ~ +15V 表示逻辑 0(与 TTL 相反)反逻辑点对点≤ 15m早期电脑串口、调制解调器,抗干扰比 TTL 强
RS485差分信号:A、B 两根线电压差A-B > +200mV = 1;A-B < -200mV = 0半双工或全双工(多点总线)≤ 1200m抗干扰强,支持多机通信,常用于工业现场总线、485 转换器

2.代码

(1)初始化

void init_uart(void)
{
	unsigned char t;
	t = SCON;
	t &= ~(3 << 6);
	t |= (1 << 6) | (1 << 4);
	SCON = t;

	PCON |= (1 << 7);
	TCON |= (1 << 6);

	t = TMOD;
	t &= ~(0xFFFF);
	t |= (1 << 5);
	t |= (1 << 0);
	TMOD = t;
	TH1 = 204;
	TL1 = 204;
	TH0 = a >> 8;
	TL0 = a;

	IE |= (1 << 4) | (1 << 7) | (1 << 1);
	 
}

(2)发送函数

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++);
	}
}

(3)串口中断服务函数

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);
	}
}

8051 的存储空间分为几类:

  1. DATA:内部 RAM 的低 128 字节(0x00 ~ 0x7F),可直接寻址。

  2. IDATA:内部 RAM 的全部 256 字节(0x00 ~ 0xFF),间接寻址。

  3. XDATA:外部 RAM(0x0000 ~ 0xFFFF,最大 64KB),通过 MOVX 指令访问。

  4. CODE:程序存储器(ROM/Flash),存放程序和常量。

(4)检验大小端存储函数

void check_mcu_endianness(void)
{
    int n = 0x1234;
    unsigned char *s = (unsigned char *)&n;
    int i;
    for (i = 0; i < sizeof(n); ++i)
    {
        sprintf(buffer, "%X", s[i]);  
        send_buffer(buffer, strlen(buffer));
        send_char(' ');                 
    }
    send_char('\n');
}

(5)检测51单片机中数据类型所占用的字节

int n;
n = sizeof(int);
sprintf(buffer, "int size = %d", n);
send_buffer(buffer, strlen(buffer));

(6)通信协议解析函数

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 timer0_handler(void)  interrupt 1
{  
	P2 ^= (1 << 1);
	TH0 = a >> 8;
	TL0 = a;
}

int *p;
int n = 0;

void parse(void)
{
	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])
			{
				if((unsigned char)rcv_buffer[2] == 0x01)
				{					
					p = (int *)&rcv_buffer[3];
					n = *p;
					TCON &= ~(1 << 4);
				}
				else if((unsigned char)rcv_buffer[2] == 0x02)
				{
					p = (int *)&rcv_buffer[3];
					n = *p;
					
					if(200 == n)
					{
						a = HZ200;
						TCON |= (1 << 4);	
					}
					else if(400 == n)
					{
						a = HZ400;
						TCON |= (1 << 4);
					}
				}
			}
		}
	}	
}


int main(void)
{
	init_uart();
	while(1)
	{
		 if(pos != 0)
		 {
			delay(0xFFFF);
			parse();
			pos = 0;
			memset(rcv_buffer, 0, sizeof(rcv_buffer));
		 }
		 show_number(n);
	}
}

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐