通讯方式
并行
适合短距离通讯,并行通讯控制简单、相对传输速度快(8位一块儿传输)。数组

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

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

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

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

全双工

串行通讯的错误校验
奇偶校验
在发送数据时,数据位尾随的1位为奇偶校验位(1/0)。奇校验时,数据中1的个数与检验位1的个数之和应为奇数;偶校验时,数据中1的个数与校验位1的个数之和应为偶数。接收字符时,对1的个数进行校验,若字符不一致,则说明传输数据过程当中出现错误。code
代码和校验
发送方将所发数据块求和(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块末尾。接收方接收数据时,同时对数据块(除校验字节外)求和(或各字节异或),将所得的结果与发送方的“校验和”进行比较,一致则无差。blog
循环冗余校验
经过某种数学预算实现有效信息与校验位之间的循环校验,经常使用语对磁盘信息的传输、存储区的完整性校验。字符串
串口的基本结构
SBUF:51单片机中的特殊寄存器,串行数据缓冲器(一个接收一个发送),两个实际上是共用的一个地址99H,可是两个在物理上面是分开的。
当发送使用时,就采用SBUF=XXX; (XXX为须要传送的数据)
当接收使用时,采用XXX=SBUF;
记得由于是串行的因此传输都是一位一位进行的。
T1溢出率:T1计时器的溢出频率(就是计时器每次低位计满向高位进位时间的倒数)
用处:用于计算波特率(每秒传输二进制代码的位数)
实现单片机与电脑之间的互相传送字符串通讯
工具:STC-ISP
代码:
- #include <reg52.h>
- #include <stdio.h> //printf头文件
- #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.循环赋值为'\0'(字符串结尾标志符),j=0,为了第二次传递字符串是又是从头输出
- { //2.flag为0和j不为0时,保证是第二次及之后,传输字符串(控制输出格式)
- flag_n++;
- for(j=0;s[j]!='#'&&j<50;j++)
- s[j]='\0';
- j=0;
- }
- s[j]=SBUF;
- flag=1;
- if(s[j]=='#'||j==49) //以'#'做为传送字符串的结尾符,我定义的字符数组最长为50因此49也应该结束。
- flag_t=1;
- else
- j++;
- }
-
- if(TI) //发送数据
- {
- }
- }
运行截图:
代码解读:基本上就是几个模块:计时器、中断以及串口通讯
中断
寄存器介绍
IE(interrupt enable):(可位寻址)设定各个中断源的打开和关闭

IP(interrupt prior)中断优先级寄存器:(可位寻址)用来设定各个中断源属于两级中断中的哪一级
中断源:
中断响应条件:
1.中断源有中断请求
2.此中断源的中断容许位为1
3.CPU开中断(EA=1)
代码书写:
1.先开总中断EA
void 函数名() interrupt 中断号(上面图示的序号)
//中断函数返回值必定是void
//函数名随便写
//中断号用来判断是哪一个中断源
计时器
寄存器介绍
TCON 支持位寻址 :控制寄存器,控制T一、T0的启动和中止及设置溢出标志

TMOD,不支持位寻址:定时/计数器的工做方式寄存器,肯定工做方式和功能
计时器代码书写步骤:
1.EA=1;
2.ETX=1; //开启计时器X中断
3.配置工做方式 TMOD=0x..; //根据本身需求按照上表来配
3.配置计时器初值
//THX=(65535-N)/256;
//TLX=(65535-N)%256;
//N由你要计时的时长决定。计时器计一个数花费一个时钟周期来计算。
4.TRX=1; //开启计时器X
串口通讯
寄存器介绍
PCON电源管理寄存器 :(不可位寻址)
用来管理单片机的电源部分,包括上电复位检测、掉电模式
、空闲模式等


SCON:(可位寻址)用以设定串行口的工做方式、接收/发送控制以及设置状态标志
波特率计算
SMOD就是PCON中的第一位,默认为0
fosc为晶振频率,因此本身设定不一样波特率时,也要考虑晶振不一样的问题。
代码书写
1.上面都书写完毕以后
2.还须要ES=1
3.传输数据时,SBUF=XX
接收数据时,XX=SBUF
4.中断函数书写
必定要将RI清0,可是TI的清0在主函数中进行
//由于TI在中断中进行,(1)没有if(TI)的判断,那么就会和RI的处理混淆(2)若是有TI判断
//那么有可能永远进行不了传输数据,由于最开始TI是为0的,没法进入TI条件,就无传
//输数据(SBUF=XX)。并且在传输数据的时候会又一次进入中断,就是还没处理中
//断就又进入了另一个中断,致使通讯出现异常。
相信有了这些模块的讲解以后加上代码的注释应该都懂了~
若是有任何问题和不懂的均可以提出~