一、 使用晶體頻率為22.1184MHz的AT89C52單片機(jī),串行口應(yīng)用工作方式1,以9600bps的波特率向外發(fā)送數(shù)據(jù),數(shù)據(jù)為十個數(shù)字‘0’到‘9’,循環(huán)不斷地發(fā)送。
解:數(shù)字字符為增量進(jìn)二進(jìn)制碼,‘0’對應(yīng)0x30,‘1’= ‘0’+ 1 = 0x31,從‘0’到‘9’對應(yīng)編碼為0x30到0x39,記憶二進(jìn)制編碼較難,實際編程中用單引號括起對應(yīng)字符表示引用該字符的二進(jìn)制編碼值,如‘?’表示引用?號的編碼值。
在用11.0592MHz晶體時,9600bps的初始化分頻初值為-6,現(xiàn)晶頻加倍,如果其它條件不變,只有分頻初始加倍為-12,才能得到9600bps;如果想得到2400bps(速率降4倍),分頻初始自然加大4倍,即為-48。根據(jù)題意編得如下程序:
#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’;
}
}
}
二、 在上題的基礎(chǔ)上,改為2400bps,循環(huán)發(fā)送小寫字母‘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’;
}
}
}
上述改變值時,也可以再設(shè)一變量表示當(dāng)前的大小寫狀態(tài),比如寫成如下方式:
++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兩臺單片機(jī),晶體頻率分別為13MHz和14MHz,在容易編程的條件下,以最快的速度進(jìn)行雙工串行通信,A給B循環(huán)發(fā)送大寫字母從‘A’到‘Z’,B給A循環(huán)發(fā)送小寫字母從‘a’到‘z’,雙方都用中斷方式進(jìn)行收發(fā)。
解:由于晶體頻率不同,又不成2倍關(guān)系,所以只有通信方式1和方式3,由于方式3的幀比方式1多一位,顯然方式3的有效數(shù)據(jù)(9/11)比方式1(8/10)高,但要用方式3的第9位TB8來發(fā)送數(shù)據(jù),編程難度較大,這里方式1較容易編程。
在計算最高速率時,由于單方程,雙未知數(shù),又不知道波特率為多少,所以要綜合各方面的條件,估算出A和B的分頻常數(shù),分別為-13和-14時,速率不但相同,且為最大值。如下給出A機(jī)的程序:
#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任一位變?yōu)?都中斷
{
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’;
}