问下大神定时器T0中断导致串口通信无法正常进行的问题。

这是我的代码,将之烧入51单片机时,串口通信本来是让led显示,但是可能由于红外遥控的中断函数干扰了串口通信,导致红外遥控工作正常,串口通信无法进行,led无法显示。

#include
#include
#include"lcd.h"
#include"temp.h"
#define uint unsigned int
#define uchar unsigned char

sbit moto=P1^0;

uchar CNCHAR[6] = "摄氏度";
void LcdDisplay(int);
void UsartConfiguration();

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

  • 函数名 : main
  • 函数功能 : 主函数
  • 输入 : 无
  • 输出 : 无 *******************************************************************************/ void UsartConfiguration()

{

SCON=0X50;          //设置为工作方式1
TMOD=0X20;          //设置计数器工作方式2
PCON=0X80;          //波特率加倍
TH1=0XF3;               //计数器初始值设置,注意波特率是4800的
TL1=0XF3;

//ES=1; //打开接收中断
//EA=1; //打开总中断
TR1=1;
//打开计数器
}

uchar time0;
bit IRok;//33数据位处理完成标志位
bit handle_ok;
uchar IRcode[4];//4个字节
uchar IRdata[33];//33位数据
void InitUART() //定时器初始化
{
TMOD=0x02;//定时器重装初值
TH0=0;
TL0=0;
EA=1;
EX0=1;
TCON=0X01;

    ET0=1;
    TR0=1;//启动定时器

}

void t0() interrupt 1
{
time0++;//一次中断为277.76us

}
void int0() interrupt 0
{

static uchar i;
static bit flag;
if(flag)
{
ES=0;
if((time032))
i=0;

            IRdata[i]=time0;
            time0=0;
            i++;

    if(i==33)
    {
            i=0;
            IRok=1;
    }
    }
    else
    {
            time0=0;
            flag=1;
    }

}

void handle_data()
{
uchar i;//处理四个字节
uchar j;//处理八位
uchar k;//处理三十三个数据
k=1;
for(i=0;i {
for(j=0;j {
if(IRdata[k]>5)
IRcode[i]|=0x80;
k++;
if(j IRcode[i]>>=1;
}
}
handle_ok=1;
}

void work()
{

uchar j;
j=0x01;
switch (IRcode[2])
{
case 0x0c:moto=0;break;//1 数字一按键停止(修改这里更改控制按键)
case 0x18:moto=1;break;//2数字二按键启动
default:break;
}
}
but()
{

while(1)
    {


            if(IRok)
            {
                    handle_data();
                    IRok=0;
            }
            if(handle_ok)//如果处理完成处理遥控器相关程序
            {       
                work();
                handle_ok=0;
            }

    }   

}

void main()
{

    InitUART();
    UsartConfiguration();
    LcdInit();           //初始化LCD1602
    LcdWriteCom(0x88);  //写地址 80表示初始地址
    LcdWriteData('C');



        while(1)

        {
        but(); 
        LcdDisplay(Ds18b20ReadTemp());

 }












}   

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

  • 函数名 : LcdDisplay()
  • 函数功能 : LCD显示读取到的温度
  • 输入 : v
  • 输出 : 无 *******************************************************************************/

void LcdDisplay(int temp) //lcd显示
{

unsigned char i, datas[] = {0, 0, 0, 0, 0}; //定义数组
float tp; 





if(temp< 0)             //当温度值为负数
{
    LcdWriteCom(0x80);      //写地址 80表示初始地址
    SBUF='-';//将接收到的数据放入到发送寄存器
    while(!TI);                  //等待发送数据完成
    TI=0;                        //清除发送完成标志位
    LcdWriteData('-');          //显示负
    //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
    temp=temp-1;
    temp=~temp;
    tp=temp;
    temp=tp*0.0625*100+0.5; 
    //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    //算由?.5,还是在小数点后面。

}
else
{           
    LcdWriteCom(0x80);      //写地址 80表示初始地址
    LcdWriteData('+');      //显示正
    SBUF='+';//将接收到的数据放入到发送寄存器
    while(!TI);                  //等待发送数据完成
    TI=0;                        //清除发送完成标志位
    tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
    //如果温度是正的那么,那么正数的原码就是补码它本身
    temp=tp*0.0625*100+0.5; 
    //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
    //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
    //算加上0.5,还是在小数点后面。
}


if(temp>=2900)   
{
    moto=1;          //开启电机

}

else
{   
moto=0;         //关闭电机

}   

datas[0] = temp / 10000;
datas[1] = temp % 10000 / 1000;
datas[2] = temp % 1000 / 100;
datas[3] = temp % 100 / 10;
datas[4] = temp % 10;

LcdWriteCom(0x82);        //写地址 80表示初始地址
LcdWriteData('0'+datas[0]); //百位 
SBUF = '0'+datas[0];//将接收到的数据放入到发送寄存器
while (!TI)
     ;                   //等待发送数据完成
TI = 0;

LcdWriteCom(0x83);       //写地址 80表示初始地址
LcdWriteData('0'+datas[1]); //十位
SBUF = '0'+datas[1];//将接收到的数据放入到发送寄存器
while (!TI);                     //等待发送数据完成
TI = 0;

LcdWriteCom(0x84);      //写地址 80表示初始地址
LcdWriteData('0'+datas[2]); //个位 
SBUF = '0'+datas[2];//将接收到的数据放入到发送寄存器
while (!TI);                     //等待发送数据完成
TI = 0;

LcdWriteCom(0x85);      //写地址 80表示初始地址
LcdWriteData('.');      //显示 ‘.’
SBUF = '.';//将接收到的数据放入到发送寄存器
while (!TI);                     //等待发送数据完成
TI = 0;

LcdWriteCom(0x86);       //写地址 80表示初始地址
LcdWriteData('0'+datas[3]); //显示小数点  
SBUF = '0'+datas[3];//将接收到的数据放入到发送寄存器
while (!TI);                     //等待发送数据完成
TI = 0;

LcdWriteCom(0x87);       //写地址 80表示初始地址
LcdWriteData('0'+datas[4]); //显示小数点 
SBUF = '0'+datas[4];//将接收到的数据放入到发送寄存器
while (!TI);                     //等待发送数据完成
TI = 0;
for(i=0; i<6; i++)
{
    SBUF = CNCHAR[i];//将接收到的数据放入到发送寄存器
    while (!TI);                     //等待发送数据完成
    TI = 0;
}

}

2个回答

我碰到过一次,也是定时器干扰串口,然后听群里面大佬的把定时器的区间改了下,大概100us一次就可以了,上次1us,没注意时序

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问