51单片机模拟串口的三种方法文档格式.docx

上传人:b****2 文档编号:4524609 上传时间:2023-05-03 格式:DOCX 页数:10 大小:18.04KB
下载 相关 举报
51单片机模拟串口的三种方法文档格式.docx_第1页
第1页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第2页
第2页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第3页
第3页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第4页
第4页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第5页
第5页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第6页
第6页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第7页
第7页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第8页
第8页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第9页
第9页 / 共10页
51单片机模拟串口的三种方法文档格式.docx_第10页
第10页 / 共10页
亲,该文档总共10页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

51单片机模拟串口的三种方法文档格式.docx

《51单片机模拟串口的三种方法文档格式.docx》由会员分享,可在线阅读,更多相关《51单片机模拟串口的三种方法文档格式.docx(10页珍藏版)》请在冰点文库上搜索。

51单片机模拟串口的三种方法文档格式.docx

现在就以11.0592M的晶振为例,谈谈三种模拟串口的方法。

方法一:

延时法

通过上述计算大家知道,串口的每位需延时0.104秒,中间可执行96个指令周期。

#define 

uchar 

unsigned 

char

sbit 

P1_0 

0x90;

P1_1 

0x91;

P1_2 

0x92;

RXD 

P1_0

TXD 

P1_1

WRDYN 

44 

//写延时

RDDYN 

43 

//读延时

//往串口写一个字节

void 

WByte(uchar 

input)

{

i=8;

TXD=(bit)0;

//发送启始

Delay2cp(39);

//发送8位数据位

while(i--)

TXD=(bit)(input&

0x01);

//先传低位

Delay2cp(36);

input=input>

>

1;

}

//发送校验位(无)

TXD=(bit)1;

//发送结束

Delay2cp(46);

//从串口读一个字节

RByte(void)

Output=0;

temp=RDDYN;

Delay2cp(RDDYN*1.5);

//此处注意,等过起始位

Output 

=1;

if(RXD) 

|=0x80;

//先收低位

Delay2cp(35);

//(96-26)/2,循环共

占用26个指令周期

while(--temp) 

//在指定的

时间内搜寻结束位。

Delay2cp

(1);

if(RXD)break;

//收到结束位便退出

return 

Output;

//延时程序*

Delay2cp(unsigned 

char 

i)

while(--i);

//刚好两个

指令周期。

此种方法在接收上存在一定的难度,主要是采样定位存在需较准确,另外还必须知道

每条语句的指令周期数。

此法可能模拟若干个串口,实际中采用它的人也很多,但如果你用Keil 

C,本人不建议使用此种方法,上述程序在P89C52、AT89C52、W78E52三种单片机上实验通过。

方法二:

计数法

51的计数器在每指令周期加1,直到溢出,同时硬件置溢出标志位。

这样我们就可以

通过预置初值的方法让机器每96个指令周期产生一次溢出,程序不断的查询溢出标志来决定是否

发送或接收下一位。

//计数器初始化

S2INI(void)

TMOD 

|=0x02;

//计数器0,方式2

TH0=0xA0;

//预值为256-96=140,十六进制A0

TL0=TH0;

TR0=1;

//开始计数

TF0=0;

//发送启始位

WaitTF0();

//发送结束位

TR0=0;

//查询计数器溢出标志位

WaitTF0( 

while(!

TF0);

接收的程序,可以参考下一种方法,不再写出。

这种办法个人感觉不错,接收和发送

都很准确,另外不需要计算每条语句的指令周期数。

方法三:

中断法

中断的方法和计数器的方法差不多,只是当计算器溢出时便产生一次中断,用户可以

在中断程序中置标志,程序不断的查询该标志来决定是否发送或接收下一位,当然程序中需对中

断进行初始化,同时编写中断程序。

本程序使用Timer0中断。

TM0_FLAG 

//设传输标志位

//计数器及中断初始化

//在发送或

接收才开始使用

ET0=1;

//允许定时

器0中断

EA=1;

//中断允许

总开关

//接收一个字符

RByte()

//启动Timer0

//等过起始

//位间延时

TM0_FLAG) 

break;

//停止

Timer0

//中断1处理程序

IntTimer0() 

interrupt 

1

TM0_FLAG=1;

//设置标志位。

//查询传输标志位

TM0_FLAG);

TM0_FLAG=0;

//清标志位

中断法也是我推荐的方法,和计数法大同小异。

发送程序参考计数法,相信是件很容

易的事。

另外还需注明的是本文所说的串口就是通常的三线制异步通信串口(UART),只用RXD、TXD、

GND。

附:

51IO口模拟串口通讯C源程序(定时器计数法)

#include 

BT_SND 

=P1^0;

BT_REC 

=P1^1;

/**********************************************

IO 

口模拟232通讯程序

使用两种方式的C程序 

占用定时器0

**********************************************/

MODE_QUICK

F_TM 

F0

TIMER0_ENABLE 

TIMER0_DISABLE 

ACC0= 

ACC^0;

ACC1= 

ACC^1;

ACC2= 

ACC^2;

ACC3= 

ACC^3;

ACC4= 

ACC^4;

ACC5= 

ACC^5;

ACC6= 

ACC^6;

ACC7= 

ACC^7;

F_TM=1;

//发送一个字符

PSendChar(unsigned 

inch)

#ifdef 

ACC=inch;

F_TM=0;

BT_SND=0;

//start 

bit

TIMER0_ENABLE;

//启动

F_TM);

BT_SND=ACC0;

//先送出低位

BT_SND=ACC1;

BT_SND=ACC2;

BT_SND=ACC3;

BT_SND=ACC4;

BT_SND=ACC5;

BT_SND=ACC6;

BT_SND=ACC7;

BT_SND=1;

TIMER0_DISABLE;

//停止timer

#else

ii;

ii=0;

while(ii<

8)

if(inch&

1)

else

ii++;

inch>

#endif

PGetChar()

//等过起始位

ACC0=BT_REC;

ACC1=BT_REC;

ACC2=BT_REC;

ACC3=BT_REC;

ACC4=BT_REC;

ACC5=BT_REC;

ACC6=BT_REC;

ACC7=BT_REC;

F_TM)

if(BT_REC)

ACC;

rch,ii;

rch=0;

rch>

rch|=0x80;

rch;

//检查是不是有起始位

bit 

StartBitOn()

(BT_REC==0);

main()

gch;

TMOD=0x22;

/*定时器1为工作模式2(8位自动重装),0为模式2(8位

自动重装) 

*/

PCON=00;

//在发送或接收才开始使用

TH0=(256-96);

//9600bps 

就是 

1000000/9600=104.167微秒 

执行的

timer是

// 

104.167*11.0592/12= 

96

PSendChar(0x55);

PSendChar(0xaa);

PSendChar(0x00);

PSendChar(0xff);

while

(1)

if(StartBitOn())

gch=PGetChar();

PSendChar(gch);

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2