单片机学习

串行通信:将数据字节分为一位一位的形式在一条数据线上逐个传送

串行通信特点:传输线少,长距离传送时成本低,且可以利用电话网等现成设备,但数据的传送控制比并行通信复杂

并行通信:通常是将数据字节的各位用多条数据线同时进行传送

串行工作方式

方式1:是一帧10位的异步串行通信方式,包括1个起始位,8个数据位和一个停止位。

其帧格式为:

 

   (1)数据发送

发送时只要将数据写入SBUF,在串行口由硬件自动加入起始位和停止位,构成一个完整的帧格式。然后在移位脉冲的作用下,由TXD端串行输出。一帧数据发送完毕,将SCON中的TI置1。

(2)数据接收

接收时,在REN=1前提下,当采样到RXD从1向0跳变状态时,就认定为已接收到起始位。随后在移位脉冲的控制下,将串行接收数据移入SBUF中。一帧数据接收完毕,将SCON中的RI置1,表示可以从SBUF取走接收到的一个字符。

串行工作方式2、方式3
        方式2、3是一帧11位的串行通信方式,即1个起始位,8个数据位,1个可编程位TB8/RB8和1个停止位。

        其帧格式为:

起始

 

数据发送和接收:
数据发送和接收与方式1基本相同,区别在于方式2把发送/接收到的第9位内容送入TB8/RB8。

波特率:方式2波特率固定,即fosc/32和fosc/64。  如用公式表示则为:

 波特率=2^SMOD  ╳  fosc/64

通过串口进行实验:


 发送机:

#include<reg51.h>				 
unsigned char code str1[]="15000101";      //设置需要发送的协议代码
unsigned char code str2[]="15000102";
unsigned char code str3[]="15000103";
sbit P1_0=P1^0;                            //给相应端口一个编号
sbit P1_1=P1^1;
sbit P1_2=P1^2;
 
//函数的功能是:向PC端发送一个字节数据
void send(unsigned char dat)
{
	SBUF=dat;
	while(TI==0);
	TI=0;
}
 
 
void delay(unsigned int n)                 //延时函数的设置
{
	unsigned int i,j;
	for(i=0;i<n;i++)
	  for(j=249;j>0;j--)
	  ;
}
 
void main(void)
{
	unsigned int i;
	TMOD=0x20;                //TMOD=0010 0000,设置定时器T1工作于方式二
	SCON=0x60;                //SCON=0100 0000,设置串口的工作方式为方式1
	PCON=0x00;                //PCON=0000 0000,波特率为9600 晶振为11.0592
	TH1=0xfd;                 //设置定时器T1的初值
	TL1=0xfd;                 //定时器T1自动填充的值
	TR1=1;                    //启动定时器T1
	while(1)
	{
	   if(P1_0==0)							   //判断P1_0口的开关状态
	   {
	   		i=0;
			while(str1[i]!='\0')			   //循环发送相应数组中的数据
	   		{
	   			send(str1[i]);
				i++;
				delay(1);
	  		}
			send('\0');                     //最后一位补上\0作为接收机判断结束的标准
			delay(1000);
	   }
	   else if(P1_1==0)						 //判断P1_1口的开关状态
	   {
	   		i=0;
			while(str2[i]!='\0')			 //循环发送相应数组中的数据
	   		{
	   			send(str2[i]);
				i++;
				delay(1);
	  		}
			send('\0');                    //最后一位补上\0作为接收机判断结束的标准
			delay(1000);
	   }
	   else if(P1_2==0)						   //判断P1_2口的开关状态
	   {
	   		i=0;
			while(str3[i]!='\0')			   //循环发送相应数组中的数据
	   		{
	   			send(str3[i]);
				i++;
				delay(1);
	  		}
			send('\0');                        //最后一位补上\0作为接收机判断结束的标准
			delay(1000);
	   }
	}
}

接收机:

#include<reg51.h>
#define uchar unsigned char
uchar temp,flag;
uchar a[10];
uchar count=0;
void main()
{
 	TMOD=0x20;          //定时器T1工作于方式2 
	SCON=0x40;          //SCON=0100 0000B,串口工作方式1
    PCON=0x00;          //PCON=0000 0000B,波特率9600
    TH1=0xfd;           //根据规定给定时器T1赋初值
    TL1=0xfd;           //根据规定给定时器T1赋初值
    TR1=1;              //启动定时器T1   
	REN=1;              //允许接收
	EA=1;               //开起总中断开关
	ES=1;               //需要用到串行口的中断所以ES=1就是把串行口的中断打开了
	while(1)            //进入循环
	{
	 	if(flag==1)     //等待中断的来临,然后flag就会被赋值为1
		{
			if(a[7]==0x31)             //如果发送的数据最后一位为1的话(“15000101”最后一位1            
			P1=0xFE;                   //对应的就是十六进制的0x31)  0xfe对应1111 1110 就第 
                                       //一盏灯亮
			else if(a[7]==0x32)        //以此类推
			P1=0xFD;
			else if(a[7]==0x33)        //以此类推
			P1=0xFC;
			else
			P1=0x00;                   //发送为其他数据时灯全亮
			flag=0;
		}
 
	}
}
 
 
void serial() interrupt 4            //设置中断函数
{
	temp=SBUF;                       //当有中断时把传过来的数据暂存到temp中
	RI=0;                            //把设置中断的标志初始化,等待下一中断
	if(temp==0x00)                   //当到达最后一位
	{
		a[count]=temp; 
		count=0;                     //计数器初始化为下一次中断准备
		flag=1;                      //标志置1进入主函数,进行端口的赋值
	}
	else
	{
	 	a[count]=temp;
		count=count+1;
	}
}

如上代码段为网上教学所提供,有错误请指出

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韬Tao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值