newlined 发表于 2025-12-16 13:46:45

请教一个Keil C 编程的问题,谢谢。

在单片机上电以后,需要一段时间的延时,等待系统稳定,以前是一段“程序循环等待”的延时,发现不是很准,想用定时器做,于是写下了一下的程序,符合预期:


#include "STC32G.h"
#include "intrins.h"
typedef         unsigned char        u8;
typedef         unsigned int        u16;
typedef         unsigned long        u32;
sbit        Led0=P3^0;
sbit        Led1=P3^1;
u16         i=0;
void Delay500mS(void)
{       
        while(i);
}

void Timer0_Init(void)                //1毫秒@12.000MHz
{
        AUXR |= 0x80;                                                //定时器时钟1T模式
        TMOD &= 0xF0;                                                //设置定时器模式
        TL0 = 0x20;                                                //设置定时初始值
        TH0 = 0xD1;                                                //设置定时初始值
        TF0 = 0;                                                        //清除TF0标志
        TR0 = 1;                                                        //定时器0开始计时
        ET0 = 1;                                                    //开T0中断
}

/********************** Timer0 1ms中断函数 ************************/
void Timer0 (void) interrupt 1
{        if(i!=0)
        {        i--;Led0=~Led0;
        }
}

void        Port_Mode(void)                                                //端口设置
{ P3M0 = 0x00; P3M1 = 0x00;
P3=0x00;                                                        //00000000;
}

void        main(void)
{        WTST         = 0;                                                                //赋值为0可将CPU执行指令的速度设置为最快
        EAXFR = 1;                                                                         //扩展寄存器(XFR)访问使能
        CKCON = 0;                                                                         //提高访问XRAM速度
        Port_Mode();                                                                        //端口设置
        Timer0_Init();                                                                        //1毫秒@12.000MHz
        EA=1;
        i=500;
        Delay500mS();
        Led1=1;
        i=500;
        Delay500mS();
        Led1=0;
        i=500;
        Delay500mS();
        while(1);
}

示波器观察的波形如下:这是符合预期的波形,其中黄色的是Led0的波形,蓝色是Led1的波形。
但是当我把 i=500;这一句拿到 Delay500mS函数中就不行了。

newlined 发表于 2025-12-16 13:59:29

这是修改后的程序, i=500;这一句拿到 Delay500mS函数中:

#include "STC32G.h"
#include "intrins.h"
typedef         unsigned char      u8;
typedef         unsigned int      u16;
typedef         unsigned long      u32;
sbit      Led0=P3^0;
sbit      Led1=P3^1;
u16         i=0;
void Delay500mS(void)
{      i=500;
      while(i);
}

void Timer0_Init(void)                //1毫秒@12.000MHz
{
      AUXR |= 0x80;                                                //定时器时钟1T模式
      TMOD &= 0xF0;                                                //设置定时器模式
      TL0 = 0x20;                                                      //设置定时初始值
      TH0 = 0xD1;                                                      //设置定时初始值
      TF0 = 0;                                                                //清除TF0标志
      TR0 = 1;                                                                //定时器0开始计时
      ET0 = 1;                                                    //开T0中断
}

/********************** Timer0 1ms中断函数 ************************/
void Timer0 (void) interrupt 1
{      
      if(i!=0)
      {      i--;Led0=~Led0;
      }
}

void      Port_Mode(void)                                                      //端口设置
{ P3M0 = 0x00; P3M1 = 0x00;
P3=0x00;                                                                //00000000;
}

void      main(void)
{      WTST         = 0;                                                //赋值为0可将CPU执行指令的速度设置为最快
      EAXFR = 1;                                                         //扩展寄存器(XFR)访问使能
      CKCON = 0;                                                         //提高访问XRAM速度
      Port_Mode();                                                      //端口设置
      Timer0_Init();                                                      //1毫秒@12.000MHz
      EA=1;
      //i=500;
      Delay500mS();
      Led1=1;
      //i=500;
      Delay500mS();
      Led1=0;
      //i=500;
      Delay500mS();
      while(1);
}

这是修改程序后的波形,不符合预期:好像在第二个延时函数中死循环,请教为什么,谢谢。

ercircle 发表于 2025-12-16 14:11:19


这种写法被优化为了死循环:
优化级别7:


调整编译优化级别或声明易变类型:
易变volatile:

优化级别0:

newlined 发表于 2025-12-16 14:36:58

ercircle 发表于 2025-12-16 14:11
这种写法被优化为了死循环:
优化级别7:


老大真是高手,竟然追到汇编,非常感谢,以前没有用到volatile,这次好好揣摩下。

DebugLab 发表于 2025-12-16 17:12:27

相当于while(500);死循环

newlined 发表于 2025-12-17 07:54:11

DebugLab 发表于 2025-12-16 17:12
相当于while(500);死循环

是的,我不知道为什么会优化到这样,又不是a=2;a=b;这样的语句,或者说还有明显更好的程序写法?
页: [1]
查看完整版本: 请教一个Keil C 编程的问题,谢谢。