赞助论坛
  • 4900阅读
  • 0回复

51单片机C语言编程基础及实例之九[串行口应用] [复制链接]

楼层直达
rkvclu  
发帖
17
精华
0
金币
65
威望
3
贡献
0
好评
0
注册
2008-06-14
楼主    rkvclu 发表于: 2008-06-16 15:23:54 
串行口应用
一、 使用晶体频率为22.1184MHz的AT89C52单片机,串行口应用工作方式1,以9600bps的波特率向外发送数据,数据为十个数字‘0’到‘9’,循环不断地发送。

解:数字字符为增量进二进制码,‘0’对应0x30,‘1’= ‘0’+ 1 = 0x31,从‘0’到‘9’对应编码为0x30到0x39,记忆二进制编码较难,实际编程中用单引号括起对应字符表示引用该字符的二进制编码值,如‘?’表示引用?号的编码值。
在用11.0592MHz晶体时,9600bps的初始化分频初值为-6,现晶频加倍,如果其它条件不变,只有分频初始加倍为-12,才能得到9600bps;如果想得到2400bps(速率降4倍),分频初始自然加大4倍,即为-48。根据题意编得如下程序:


代码
#include <at89x52.h>  
void main( void )  
{  
TMOD = (TMOD & 0x0F) | 0x20;  
TH1 = -12;  
PCON |= 0x80; //SMOD = 1  
TR1 = 1;  
SCON = 0x42;  
while( 1 )  
{  
if( TI==1 )  
{  
  static unsigned char Dat=‘0’;  
  SBUF = Dat;  
  TI = 0;  
  If( ++Dat > ‘9’) Dat=‘0’;  
}  
}  
}  

二、 在上题的基础上,改为2400bps,循环发送小写字母‘a’到‘z’,然后是大写字母‘A’到‘Z’。


代码
#include <at89x52.h>  
void main( void )  
{  
TMOD = (TMOD & 0x0F) | 0x20;  
TH1 = -96; //注意不用倍频方式  
PCON &= 0x7F; //SMOD = 0  
TR1 = 1;  
SCON = 0x42;  
while( 1 )  
{  
if( TI==1 )  
{  
  static unsigned char Dat=‘a’;  
  SBUF = Dat;  
  TI = 0;  
  //If( ++Dat > ‘9’) Dat=‘0’;  
  ++Dat;  
  if( Dat == (‘z’+1) ) Dat=‘A’;  
  if( Dat == (‘Z’+1) ) Dat=‘a’;  
}  
}  
}  


上述改变值时,也可以再设一变量表示当前的大小写状态,比如写成如下方式:


代码
++Dat;  
{  
static unsigned char Caps=1;  
if( Caps != 0 )  
if( Dat>‘Z’){ Dat=‘a’; Caps=0; }  
else  
if( Dat>‘z’){ Dat=‘A’; Caps=1; }  
}  


如下写法有错误:因为小b比大Z的编码值大,所以Dat总是‘a’


代码
++Dat;  
if( Dat>‘Z’){ Dat=‘a’}  
else if( Dat>‘z’){ Dat=‘A’}  


三、 有A和B两台单片机,晶体频率分别为13MHz和14MHz,在容易编程的条件下,以最快的速度进行双工串行通信,A给B循环发送大写字母从‘A’到‘Z’,B给A循环发送小写字母从‘a’到‘z’,双方都用中断方式进行收发。
解:由于晶体频率不同,又不成2倍关系,所以只有通信方式1和方式3,由于方式3的帧比方式1多一位,显然方式3的有效数据(9/11)比方式1(8/10)高,但要用方式3的第9位TB8来发送数据,编程难度较大,这里方式1较容易编程。
在计算最高速率时,由于单方程,双未知数,又不知道波特率为多少,所以要综合各方面的条件,估算出A和B的分频常数,分别为-13和-14时,速率不但相同,且为最大值。如下给出A机的程序:


代码
#include <at89x52.h>  
void main( void )  
{  
TMOD = (TMOD & 0x0F) | 0x20;  
TH1 = -13; //注意用倍频方式  
PCON |= 0x80; //SMOD = 1  
TR1 = 1;  
SCON = 0x52; //REN = 1  
ES = 1;  
EA = 1;  
while( 1 );  
}  
void RS232_intr( void ) interrupt 4 //注意RI和TI任一位变为1都中断  
{  
unsigned char rDat;  
if( RI == 1 ){ RI=0; rDat=SBUF; }  
if( TI==1 )  
{  
static unsigned char tDat=‘a’;  
SBUF = tDat;  
TI = 0;  
If( ++Dat > ‘z’) Dat=‘a’;  
}  
}  

四、 多机通位
 在方式2和方式3,SM2只对接收有影响,当SM2=1时,只接收第9位等于1的帧(伪地址帧),而SM2=0时,第9位不影响接收。
 多机通信中,地址的确认与本机程序有关,所以可以实现点对点、点对组、以及通播方式的通信。
 如果收发共用一总线,任何时刻只有一个发送源能占用总线发送数据,否则发生冲突。由此可构造无竞争的令牌网;或者多主竞争总线网。