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