嵌入式第四十六天(51单片机(通信))

发布于:2025-09-06 ⋅ 阅读:(22) ⋅ 点赞:(0)

一.串行通信与并行通信
1. 
- 串行通信:数据一位一位地依次传输,只需要一条或很少的几条传输线,适合长距离传输,但传输速度相对较慢。例如,计算机的串口(COM口)通信就是串行通信。

2.
- 并行通信:数据的各位同时传输,需要多条传输线(一般为8的倍数,如8位、16位、32位等),传输速度快,但传输线多,成本高,适合短距离高速传输。例如,计算机内部的总线(如PCI总线)、打印机的并行口通信都属于并行通信。

3.

常见传行通信协议

  • UART:异步全双工,使用TX(发送)和RX(接收)两条线,常见于单片机与PC通信。
  • SPI:同步全双工,主从设备通过SCLK(时钟)、MOSI(主发从收)、MISO(主收从发)和SS(片选)交互。
  • I2C:同步半双工,利用SDA(数据线)和SCL(时钟线)支持多设备总线连接。
  • 串行与并行通信的对比

    对比项 串行通信 并行通信
    传输方式 逐位传输 多位同时传输
    线路复杂度 低(线少) 高(线多)
    抗干扰能力 强(适合长距离) 弱(短距离)
    典型协议 UART、SPI、I2C 并行总线(如LPT)

    通过合理选择协议和配置参数(如波特率、数据位),串行通信可灵活适配不同场景需求。

二.单工、半双工、全双工通信
1. 
- 单工通信:数据只能沿一个固定方向传输,发送方只能发送,接收方只能接收。例如,广播电台的广播就是单工通信,电台只能发送信号,收音机只能接收信号。

2.
- 半双工通信:数据可以双向传输,但同一时间只能沿一个方向传输,不能同时双向传输。例如,对讲机通信就是半双工通信,一方说话时,另一方只能听,等一方说完,另一方才能说。

3.
- 全双工通信:数据可以同时双向传输,发送方和接收方可以同时发送和接收数据。例如,电话通信就是全双工通信,双方可以同时说话和听对方说话。


三.串口通信及通信时序

1.
- 串口通信:即串行接口通信,是指采用串行通信方式进行数据传输的通信方式,通过串行端口(如RS - 232、RS - 485等接口)来实现设备间的数据交互。

2.
- 串口通信时序(以异步串口为例):通常包括起始位、数据位、校验位(可选)、停止位。通信开始时,先发送一个起始位(低电平),表示数据传输的开始;接着发送数据位(一般为5 - 8位),数据位是要传输的实际数据;然后可选择发送校验位(用于校验数据传输是否正确);最后发送停止位(高电平,一般为1位、1.5位或2位),表示数据传输的结束。


四. 串口通信速率相关


- 串口通信的速率由波特率决定,波特率是指单位时间内传输的码元个数。


- 常见的波特率有300、600、1200、2400、4800、9600、19200、38400、57600、115200等。


五. 同步通信与异步通信

1.
- 同步通信:发送方和接收方使用同一时钟信号来同步数据的传输,在传输数据时,会先发送同步字符或同步信号,使双方的时钟保持同步,然后再传输数据块。

2.
- 异步通信:发送方和接收方不使用同一时钟信号,而是通过在数据中加入起始位、停止位等方式来实现数据的同步传输,每次传输一个字符(或字节)的数据。
- 串口通信属于异步通信。


六. TTL、RS - 232、RS - 485

1.
- TTL(Transistor - Transistor Logic):是一种晶体管 - 晶体管逻辑电平标准,高电平通常为+5V(或+3.3V等),低电平为0V。主要用于数字电路内部的逻辑电平表示,传输距离较短,一般在几米以内。

2.
- RS - 232:是一种串行通信接口标准,规定了通信的电气特性、机械特性等。采用负逻辑,逻辑“1”为- 3V~- 15V,逻辑“0”为+3V~+15V。适合短距离(约15米以内)的串行通信,在计算机串口通信等领域曾广泛应用。

3.
- RS - 485:也是一种串行通信接口标准,采用差分传输方式(用两根线之间的电压差来表示逻辑电平),抗干扰能力强,传输距离远(可达上千米),并且支持多节点(最多可连接32个或更多节点)通信,常用于工业控制、智能楼宇等需要长距离、多节点通信的场景。

七.简单代码示例(uart)

#include <reg52.h>
#include "delay.h"
#include <string.h>
#include <stdio.h>
#include "digtub.h"

xdata char recv_buffer[64];
int pos = 0;

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 = 208;
	TL1 = 208;
	TCON |= (1 << 6);
}

void send_char(char ch)
{
	//P2 = 0;
	SBUF = ch;
	while((SCON & (1 << 1)) == 0);
	SCON &= ~(1 << 1);
}

void send_buffer(const char *p,int len)
{
	while(len--)
	{
		send_char(*p++);		
	}
}

void uart_recv_hander(void) interrupt 4
{
	if((SCON & (1<<0)) != 0)
	{
		//P2 = SBUF;
		recv_buffer[pos++] = SBUF;
		SCON &= ~(1<<0);
	}
}

int digiter_num = 0;
#define Hz200 63035
#define Hz400 64285
#define Hz800 64910
#define Hz2000 65285
unsigned int n = Hz200;

void init_timer0(void)
{
	TMOD &= ~(3<<2);
	TMOD &= ~(3<<0);
	TMOD |= (1<<0);
	TH0 = n >> 8;
	TL0 = n;
	//TCON |= (1<<4);

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

void timer1_hander(void) interrupt 1
{
	P2 ^= (1<<1);
    TH0 = n >> 8;
	TL0 = n;
}

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)
{
	if((unsigned char)recv_buffer[0] == 0xAA && (unsigned char)recv_buffer[pos - 1] == 0x0D)
	{
		if((unsigned char)recv_buffer[1] == 0x01)
		{
			if(sumOfTheArray(recv_buffer,5) == (unsigned char)recv_buffer[5])
			{
				unsigned char order;
				order = recv_buffer[2];
				switch(order)
				{
					case 0x01:
						P2 = 0;
					break;
					case 0x02:
						digiter_num = (unsigned char)recv_buffer[3];
					break;
					default:
						init_timer0();
						init_key();
						while(1)
						{
							int ret;
							ret = key_pressed();
							if(ret == 0)
							{
								TCON &= ~(1<<4);		
							}
							if(ret == 1)
							{
								n = Hz200;
								TCON |= (1<<4);
							}
							if(ret == 2)
							{
								n = Hz400;
								TCON |= (1<<4);
							}
							if(ret == 3)
							{
								n = Hz800;
							    TCON |= (1<<4);
							}
							if(ret == 4)
							{
								n = Hz2000;
								TCON |= (1<<4);
							}
						}
						break;
				}
			}
		}
	}
}

int main(void)
{
	//xdata char buffer[64];
	//int a,b,c,d,e,f,g;
	//int *p = NULL;

	init_uart();

	/*while(1)
	{
		//send_char('A');
		a = sizeof(int);
		b = sizeof(short);
		c = sizeof(long);
		d = sizeof(float);
		e = sizeof(double);
		f = sizeof(char);
		g = sizeof(p);

		sprintf(buffer,"size1 = %d\n",a);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size2 = %d\n",b);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size3 = %d\n",c);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size4 = %d\n",d);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size5 = %d\n",e);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size6 = %d\n",f);
		send_buffer(buffer,strlen(buffer));

		sprintf(buffer,"size7 = %d\n",g);
		send_buffer(buffer,strlen(buffer));

		delay(0x9FFF);	
	}*/
	/*while(1)
	{
		if(pos != 0)
		{
			delay(0xFFFF);
			if(strcmp(recv_buffer,"Hello") == 0)
			{
				send_buffer("Hi",7);
			}
			else if(strcmp(recv_buffer,"China") ==0)
			{
				send_buffer("NB",2);
			}
			//send_buffer(recv_buffer,pos);
			pos = 0;
			memset(recv_buffer,0,sizeof(recv_buffer));
		}
	} */
	while(1)
	{
		if(pos != 0)
		{
			delay(0xFFFF);
			parse();
			pos = 0;
			memset(recv_buffer,0,sizeof(recv_buffer));
		}
		show_number(digiter_num);
	}

	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到