代码如下:
#include “reg51.h”
/*
将P1.0虚拟成串口发送脚TX
以9600bit/s的比特率向外发送数据
因为波特率是 9600bit/s
所以me发送一位的时间是 t=1000000us/9600=104us
*/
sbit TX=P3^1; //P1^0 output TTL signal, need to transferred to rs232 signal, can be connected to P3^1
#define u16 unsigned int //宏定义
#define u8 unsigned char
u8 sbuf;
bit ti=0;
void delay(u16 x)
{
while(x--);
}
void Timer0_Init()
{
TMOD |= 0x01;
TH0=65440/256;
TH0=65440%256;
TR0=0;
}
void Isr_Init()
{
EA=1;
ET0=1;
}
void Send_Byte(u8 dat)
{
sbuf=dat;//通过引入全局变量sbuf,可以保存形参dat
TX=0; //A 起始位
TR0=1;
while(ti==0); //等待发送完成
ti=0; //清除发送完成标志
}
void TF0_isr() interrupt 1 //每104us进入一次中断
{
static u8 i; //记录进入中断的次数
TH0=65440/256;
TL0=65440%256;
i++;
if(i》=1 && i《=8)
{
if((sbuf&(1《《(i-1)))==0) // (sbuf&(1《《(i-1)))表示取出i-1位
{
TX=0;
}
else
{
TX=1;
}
}
if(i==9) //停止位
{
TX=1;
}
if(i==10)
{
TR0=0;
i=0;
ti=1; //发送完成
}
}
void main()
{
TX=1; //使TX处于空闲状态
Timer0_Init();
Isr_Init();
while(1)
{
Send_Byte(65); //0x41
delay(60000);
}
} 实验引入了定时器0来控制发送线上的各个位的保持时间。首先main函数进入,TX置1则使发送线处于空闲,这时候发送方和接受方都处于空闲。接下来初始化定时器0,TR0置0表示还不要启动定时器0。接着中断系统初始化,此时中断系统已经开启。进入while循环,先进Send_Byte()函数,将65传给形参dat,dat再将65赋值给sbuf,到这里准备工作就做好了。接着TX置0,这个是起始位,要保持这个起始位104us。于是就启动定时器TR0置1,计时器开始计数。当第一次溢出的时候,也就是过了104us,进入中断,同时接收方也侦测到了这个突然被拉低的信号,于是迅速启动自己的定时器。进入中断子函数后,先是重装定时器初值,然后i加1,也就是当i=1时,就应该发送数据的最低位了,总共有8位数据,所以使用条件语句if(i》=1 && i《=8)来判断是否发送完数据位。然后再通过if(i==9) 来发送停止位,最后当i=10时,也就是发送完了,这时候要关闭定时器(那么程序也就),同时i置0,ti置1(才能跳出while(ti==0)循环),最后将ti置0,保证下次要发送字节时让程序停留在while(ti==0)。 (责任编辑:admin) |