51单片机与PC进行串口通信

昨天搞单片机的串口通信,突然一下就对前面学的中断有了进一步的理解。

单片机的串行口控制寄存器是SCON, 其格式如下:

串行口有4种工作方式,分别为00,01,10,11。 方式0为同步移位寄存器,方式1,2 ,3分别为异步10,11,11位收发方式。一般比较常用的是方式1,即10位异步收发方式。

方式01的10位数据收发具体分析如下:

51单片机与PC进行串口通信_第1张图片要发送的数据SBUF=0X34,根据波形图,10位数据,起始位为1(这里的波形图上未标出),最后一位由波形图知为1,中间的即为8位数据00110100(0x34)。当第8位发送完毕后,单片机会自动发送一位结束标志位,即把TI置1,TI置1表示数据发送完毕,TI不能自动清零,所以每次发送完数据后需要软件清零: 

同上,当单片机需要接受数据的时候,也是执行相同的步步骤。首先接收8位数据,然后把接收标志位RI置1.

串行口的初始化步骤,主要是设定产生波特率的定时器1,串行口控制盒中断控制,步骤如下:51单片机与PC进行串口通信_第2张图片

代码:

//串口初始化程序
	TMOD&=0x0f;
	TMOD|=0x20;
	TH1=0XFD;    //设定波特率为9600
	TL1=0xFD;
	TR1=1;       //启动定时器T1
	SCON=0X50;   //10位数据异步收发,波特率由定时器T1控制,允许串口接收
 	ES=1;        //允许串口中断
    //串口初始化完毕

下面我写了一个串口与PC通信的程序:

#include

unsigned char flag,i;
unsigned int k,j;
unsigned char a[32]={0};

unsigned char code table[6]="I get ";

void init()
{
 TMOD=0x20;         //设定定时器工作方式2
 TH1=0xfd;         //定时器1装入初值
 TL1=0xfd;         //同上
 TR1=1;          //启动T1定时器
 SM0=0;          //设定工作方式1
 SM1=1;          //同上
 REN=1;          //允许串口接收
 EA=1;          //开总中断
 ES=1;          //开串口中断
}
 
void main()
{
 init();
 while(1)
 {
  if(flag==1)
  {
   ES=0;
   for(i=0;i<6;i++)
   {
    SBUF=table[i];
    while(!TI);
    TI=0;
   }
   ES=1;
  for(k=0;k<0xFFFF;k++);
  for(i=0;i<32;i++)
   {  
   SBUF=a[i];           
   while(!TI);
   TI=0;
   }
   flag=0;
  } 
 }  
}
void ser() interrupt 4       //中断程序,接收数据块,标志位置1
{   
	flag=1;
	if(RI==1){
		a[j++]=SBUF;
	    RI=0;    //手动清零  
	}
}

串口通信效果如下:
51单片机与PC进行串口通信_第3张图片

但是我的这个程序有点小问题,我自己想了很多种办法来试着解决,但是都以失败告终。当我输入的数据大于2个字节时,它只能返回前两个字节的数据。如下图:

51单片机与PC进行串口通信_第4张图片

希望有哪位高手能指点我一二。今天就到这儿吧。

你可能感兴趣的:(单片机)