串行通信 发送标志位TI误用导致死循环

若用 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;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值