找回密码
 立即注册
查看: 43|回复: 4

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

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:577
  • 最近打卡:2025-12-16 06:51:05

47

主题

238

回帖

957

积分

高级会员

积分
957
发表于 昨天 13:46 | 显示全部楼层 |阅读模式
在单片机上电以后,需要一段时间的延时,等待系统稳定,以前是一段“程序循环等待”的延时,发现不是很准,想用定时器做,于是写下了一下的程序,符合预期:


#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函数中就不行了。
IMG_20251216_132820.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:577
  • 最近打卡:2025-12-16 06:51:05

47

主题

238

回帖

957

积分

高级会员

积分
957
发表于 昨天 13:59 | 显示全部楼层
这是修改后的程序, 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);
}

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:389
  • 最近打卡:2025-12-16 08:53:16
已绑定手机

97

主题

3864

回帖

8332

积分

荣誉版主

无情的代码机器

积分
8332
发表于 昨天 14:11 | 显示全部楼层

这种写法被优化为了死循环:
优化级别7:
截图202512161408174750.jpg

调整编译优化级别或声明易变类型:
易变volatile:
截图202512161410569626.jpg
优化级别0:
截图202512161409031687.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:577
  • 最近打卡:2025-12-16 06:51:05

47

主题

238

回帖

957

积分

高级会员

积分
957
发表于 昨天 14:36 | 显示全部楼层
erci*** 发表于 2025-12-16 14:11
这种写法被优化为了死循环:
优化级别7:

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

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:646
  • 最近打卡:2025-12-17 07:25:27
已绑定手机

93

主题

6933

回帖

1万

积分

超级版主

积分
13010
发表于 昨天 17:12 | 显示全部楼层
相当于while(500);死循环
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-12-17 07:44 , Processed in 0.120208 second(s), 65 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表