嵌入式第四十六天(51单片机(通信))
一.串行通信与并行通信
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;
}