51单片机模拟串口发送与接收

其他代码 blackfeather

 

最近做的一个项目里需要用到两个串口来完成通信,但是熟悉的51只有一个串口,后来问老师给我的回答竟然是用两个单片机。。。

无语了,于是想尝试使用普通I/O端口模拟串口来通信(微机原理不能白学呀),于是百度了一些资料,有了以下代码。

此代码不是我写的,但是感觉这个代码比较适合新手,有很高的参考价值并且可以直接编译,使用的是传说中的中断法。各位使用的时候注意修改晶振。

 

打包下载: 单片机模拟串口发送与接收代码

 

代码如下:

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define  crystalloid 22.1184   //晶振
#define TIMER0_ENABLE TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0; 
sfr WDT_CONTR=0xe1;
sbit RT=P3^7;
sbit BT_SND =P3^3;   //模拟串口发送口
sbit BT_REC =P3^2;   //模拟串口接收口
bit F_TM;
idata float tt;
bit tempbit,In_usart1,In_usart2;
unsigned char i;
unsigned char tempchar;
void delay(uint z);
/*******************模拟串口接收************************/
unsigned char Pgetchar(void)  
{
unsigned char rch,ii;
 TIMER0_ENABLE; // 启动T0定时器
 EX0 = 0;   //禁止外部中断
 F_TM=0;
 ii=0;
 rch=0;
 while(!F_TM); //等过起始位  T1中断F_TM置1
 F_TM = 0;
 while(ii<8)
   {
     rch>>=1;
  if(BT_REC)
      {
   rch|=0x80;
      }
     ii++;
     F_TM=0;
     while(!F_TM);
  F_TM = 0;
   }
 F_TM=0;
 while(!F_TM) 
   {
    if(BT_REC)
     {
       break;
     }

   }
 BT_REC = 1;
   F_TM = 0;
  IE0 = 0;   //外部中断0请求源,IE=1中断,软件清零
   EX0 = 1; //允许外部中断
 TIMER0_DISABLE; //停止timer
 return rch;
}
/********************模拟串口发送******************************/
void Psendchar(unsigned char inch)

  uchar ii;
  ii=0;
  F_TM=0;
  BT_SND=0; //start bit
  TIMER0_ENABLE; //启动
  while(!F_TM);
  F_TM = 0;
  TIMER0_ENABLE; //启动

  while(ii<8)
  {
      if(inch&1)
       {
         BT_SND=1;
       }
      else
       {
         BT_SND=0;
        }
       F_TM=0;
      while(!F_TM);
   F_TM = 0;
      TIMER0_ENABLE; //启动
      ii++;
      inch>>=1;
   }
  BT_SND=1;
  F_TM=0;
  while(!F_TM);
  F_TM = 0;
 
  TIMER0_DISABLE; //停止timer
}


/*****************串口波特率设置********************************/
void set_uart_bps(unsigned char uartID,unsigned int bps)

   unsigned char ch;
   tt=1000000/bps*crystalloid/12;
   ch=(unsigned char)tt;
  if(uartID==0)
   {  
    TH1=256-ch;  
    TL1=TH1;
 }
   if(uartID==1)  
   {
    TH0=256-ch;
    TL0=TH0;
 }
}
/*********************初始化*****************************/
void init_uart()
{                                                      
   SCON = 0x50;     
   TMOD = 0x22;    
     
   TH1 = 0xD0;    
   TL1 = 0xD0;

   ET0=1;
   EA=1;
   ES =1;
   TR1 = 1;    //启动定时器 
   IT0=1;
   
                           
}
/*********************1ms的延时******************************/


 void delay(unsigned int sn)   
{
  unsigned char dd;
  while(sn-->0)
     {
  for(dd=0;dd<125;dd++)                  
       {;}
  
  }
}
/****************设置中断优先级********************************/

void ininterruptmade(void)
{
TCON = 0x01;
EX0 = 1;
PT0 = 1;
PX0 = 0;
}

 


/**************************************************************/
main()
{
  init_uart();
  set_uart_bps(1,9600);
  ininterruptmade();
  delay(2000);
 
  In_usart2 = 0;
 
  while(1)
  {
  
   if(In_usart2 == 1)
      {
  Psendchar(tempchar);
  In_usart2=0;
    
  
   
  }
  
  }
 
}

/******************T0中断*********************************/
void IntTimer0() interrupt 1 using 1
{
F_TM=1;

}
/******************外部0中断**********************************/
void Int0() interrupt  0
{
TF0 = 0;

tempchar=Pgetchar();
In_usart2 = 1;

}

 

最近一直在做单片机,不经常上网,大家原谅啊。~~

 

 

评论列表:

发表评论: