若用 while(TI==0)等待发送完成
当发送完成(TI=1)时,涉及
1)TI=1 跳出循环 while(TI==0) ;
2)TI=1 进入中断
两条指令的执行先后问题
一般认为
TI=1后的瞬间,先进行中断的调用过程,即,将TI清零;
而 while 将永远读不到TI=1,形成死循环
因此,新设置一个标志位 tx_flag,进入中断后置反,保证进入中断后返回while语句时能跳出。
#include <stc12c5a.h>
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned long ulint;
sbit RING =P4^3;
bit tx_flag;
void delay(ulint k);
void Serial_Init ();
void Send_String(uchar *s);
void delay (ulint k)
{
while (k!=0)
{k--;}
}
void Serial_Init()
{
SCON=0x50; //SM0,SM1 = 0 1,REN = 1;
BRT=0xFD; //BRT = FD,bps = 9600 ;
AUXR=0x11; //BRTx12 = 0,12分频;S1BRS = 1, 选定BRT作为波特率发生器;
PCON=0x00; //SMOD = 0 ;
EA=1; // 总中断开启 ;
ES=1; // 串行中断开启 ;
}
void Uart_Is_Send () interrupt 4 using 1
{
if (TI)
{
TI=0;
tx_flag=0;
}
if (RI)
{
RI=0;
}
}
void Send_Char(uchar a)
{
tx_flag=1;
SBUF=a;
while(tx_flag==1);
}
void Send_String(uchar * s)
{
while (*s!='\0')
{
Send_Char(*s);
s++;
}
}
void main (void) {
ulint k=0;
uchar s[40]="Hello World!\n";
P4M1=0x00;
P4M0=0x08;
RING=0;
Serial_Init();
tx_flag=0;
TI=0;
while (1)
{
Send_String(s);
k++;
if(k>0x300)
{
RING=1;
delay(0xffff);
RING=0;
delay(0x1ffff);
k=0;
}
}
}