最近做的一个项目里需要用到两个串口来完成通信,但是熟悉的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;
}
最近一直在做单片机,不经常上网,大家原谅啊。~~