历史上的今天
今天是:2025年02月08日(星期六)
2020年02月08日 | 手把手教你单片机串口通信-基础篇
2020-02-08 来源:51hei
通信方式
并行
适合短距离通信,并行通信控制简单、相对传输速度快(8位一起传输)。

串行
只能一位一位的传送。

同步(了解)
建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数倍,同时传送的字符间不留间隙。
发送方对接收方的同步可以通过外同步和自同步
异步(常)
以字符(构成的帧)为单位进行传输。数据位从低到高传送。
格式:

这里的空闲时间是任意的。
串行通信的制式(传输方向)
单工(仅能沿一个方向)

半双工(可进行双向,但需分时)

全双工

串行通信的错误校验
奇偶校验
在发送数据时,数据位尾随的1位为奇偶校验位(1/0)。奇校验时,数据中1的个数与检验位1的个数之和应为奇数;偶校验时,数据中1的个数与校验位1的个数之和应为偶数。接收字符时,对1的个数进行校验,若字符不一致,则说明传输数据过程中出现错误。
代码和校验
发送方将所发数据块求和(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块末尾。接收方接收数据时,同时对数据块(除校验字节外)求和(或各字节异或),将所得的结果与发送方的“校验和”进行比较,一致则无差。
循环冗余校验
通过某种数学预算实现有效信息与校验位之间的循环校验,常用语对磁盘信息的传输、存储区的完整性校验。
串口的基本结构

SBUF:51单片机中的特殊寄存器,串行数据缓冲器(一个接收一个发送),两个其实是共用的一个地址99H,但是两个在物理上面是分开的。
当发送使用时,就采用SBUF=XXX; (XXX为需要传送的数据)
当接收使用时,采用XXX=SBUF;
记得因为是串行的所以传输都是一位一位进行的。
T1溢出率:T1计时器的溢出频率(就是计时器每次低位计满向高位进位时间的倒数)
用处:用于计算波特率(每秒传输二进制代码的位数)
实现单片机与电脑之间的互相传送字符串通信代码:
#include #include #define uc unsigned char #define uint unsigned int uc flag,i,flag_t,s[50]="",j=0,flag_n=0; uc code table[]="I get "; void init() { TMOD=0x20; //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。 TH1=0xfd; //定时器1初值 ,设置波特率为9600 晶振11.0529MHZ? TL1=0xfd; TR1=1; //开启定时器1 SM0=0; SM1=1; //10位异步接收,(8位数据)波特率可变 REN=1; //允许串行口接收位 EA=1; //允许中断(总闸) ES=1; //允许串口中断 } void main() { init(); while(1) { if(flag==1) { if(flag_n!=0) //使第二个及以后I get xx 换行,不与You transfer在一行(单纯为了格式好看) {TI=1; printf("n"); while(!TI); TI=0; } for(i=0;i<6;i++) { SBUF=table[i]; while(!TI); TI=0; } for(i=0;s[i]!='#'&&i<50;i++) { SBUF=s[i]; while(!TI); TI=0; } flag=0; } if(flag_t==1) //发送完毕之后,在电脑端输出。 { TI=1; //printf之前必须将T1置为1才行。 printf ("nYou transfer %s",s); while(!TI); TI=0; flag_t=0; } } } void ser() interrupt 4 { if(RI) //接收数据,手动将RI清0 { RI=0; if(flag==0&&j!=0)//1.循环赋值为'




