watlq2010 发表于 2024-12-29 11:09:41

启动多路定时器死机问题


#include "stc32g.h"   //头文件见下载软件
#include "intrins.h"

typedefunsigned char u8;
typedefunsigned int u16;
typedefunsigned long u32;
#define FOSC      11059200UL
#define BRT         (65536 - FOSC / 19200 / 4)

sfr   AUXR    =   0x8e;
sfr   T2H   =   0xd6;
sfr   T2L   =   0xd7;

sfr   P0M1    =   0x93;
sfr   P0M0    =   0x94;
sfr   P1M1    =   0x91;
sfr   P1M0    =   0x92;
sfr   P2M1    =   0x95;
sfr   P2M0    =   0x96;
sfr   P3M1    =   0xb1;
sfr   P3M0    =   0xb2;
sfr   P4M1    =   0xb3;
sfr   P4M0    =   0xb4;
sfr   P5M1    =   0xc9;
sfr   P5M0    =   0xca;

bit busy;
char wptr;
char rptr;
char buffer;

u32Cout0;
u32Cout1;
void UartIsr() interrupt 4
{
    if (TI)
    {
      TI = 0;
      busy = 0;
    }
    if (RI)
    {
      RI = 0;
      buffer = SBUF;
      wptr &= 0x0f;
    }
}

void UartInit()
{
    SCON = 0x50;
    T2L = 0x70;
    T2H = 0xFF;
    AUXR = 0x15;//15
    wptr = 0x00;
    rptr = 0x00;
    busy = 0;
}

void UartSend(char dat)
{
    while (busy);
    busy = 1;
    SBUF = dat;
}

void Delay1000ms(void)        //@11.0592MHz
{
        unsigned long edata i;

        _nop_();
        _nop_();
        i = 2764798UL;
        while (i) i--;
}

void Timer0_Isr(void) interrupt 1
{
        if(Cout0>0x3E8)
        {
                Cout0=0;
                UartSend(0x02);
        }
        Cout0++;
       
}

void Timer1_Isr(void) interrupt 3
{
        if(Cout1>0x3E8)
        {
                Cout1=0;
                UartSend(0x03);
        }
        Cout1++;
}
void Timer0_Init(void)                //100微秒@11.0592MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xAE;                                //设置定时初始值
        TH0 = 0xFB;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}
void Timer1_Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x40;                        //定时器时钟1T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0xCD;                                //设置定时初始值
        TH1 = 0xD4;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
        ET1 = 1;                                //使能定时器1中断
}
void UartSendStr(char *p)
{
    while (*p)
    {
      UartSend(*p++);
    }
}
void main()
{
          EAXFR = 1; //使能访问XFR,没有冲突不用关闭
    CKCON = 0x00; //设置外部数据总线速度为最快
    WTST = 0x00;//设置程序代码等待参数,
    //赋值为0可将CPU执行程序的速度设置为最快
          Cout0=0;
          Cout1=0;
    P0M0 = 0x00;
    P0M1 = 0x00;
    P1M0 = 0x00;
    P1M1 = 0x00;
    P2M0 = 0x00;
    P2M1 = 0x00;
    P3M0 = 0x00;
    P3M1 = 0x00;
    P4M0 = 0x00;
    P4M1 = 0x00;
    P5M0 = 0x00;
    P5M1 = 0x00;

    UartInit();
    ES = 1;
          
                Timer0_Init();
          Timer1_Init();
       
    EA = 1;
                WDT_CONTR = 0x27; //使能看门狗,溢出时间约为8s
                UartSendStr("Uart Test !\r\n");
    while (1)
    {
                        Delay1000ms();
      UartSend(0x01);
                        WDT_CONTR = 0x34; //清看门狗,否则系统复位
    }
}
,上面代码都是ISP复制过来,运行后每隔5秒触发一次看门狗,请问是哪里问题?

Lkck8210 发表于 2024-12-30 10:00:21

<p>优先度问题</p>
<p>串口1的优先度低于定时器1</p>
<p>但你在定时器1中断内运行UartSend</p>
<p>UartSend内要判断busy标志位</p>
<p>但Busy标志位需要在串口1中断内清零</p>
<p>于是卡死在while(busy);</p>
<p>我不相信以上代码是直接出自ISP</p>
<p>应该是你魔改了吧</p>

lgnstar 发表于 2024-12-31 08:22:44

{:yiwen:}{:yiwen:}

giveyou 发表于 2024-12-31 09:27:46

<p>发送字符串放在主程序里面,定时器里面放个标识。</p>
页: [1]
查看完整版本: 启动多路定时器死机问题