找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 469|回复: 11
打印 上一主题 下一主题
收起左侧

中断函数内增加static关键字的问题

[复制链接]
跳转到指定楼层
楼主
ID:705846 发表于 2024-6-23 11:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码要求led间隔0.5秒闪烁,在定时中断函数内的unsigned char i变量是否有必要增加static关键字。原因是什么,谢谢大家。
或者有更优化的代码。

bit flag;
sbit led=P1^2;
void main(){
        while(1){
                   if(flag){led=1;}else{led=0;}
       }
}
void Timer0Init(void)                //5ms@11.0592MHz
{
//定时器代码
}

void Timer0() interrupt 1
{
        unsigned char i;
        i++;
        if(i<100){
                flag=1;
        }else{
                flag=0;
                if(i>200){i=0;}
                }               
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:59202 发表于 2024-6-23 13:21 | 只看该作者
如果你这样写成局部变量就要加上static,因为局部变量退出函数后会被销毁,再次进入函数后会先初始化为零。或者你干脆设置成全局变量
回复

使用道具 举报

板凳
ID:866313 发表于 2024-6-23 13:22 | 只看该作者
在你的代码中,必须使用static关键字来声明局部变量 i 因为局部变量如果没有使用 static 限定,默认就是 auto 类型的,那么每次 5ms 定时时间到,中断服务函数就会被调用一次,每次调用,变量 i 的值又会重新归为垃圾值,主要是需要理解函数调用时会给该函数分配一个栈空间,并不能保证每次分配的都是同一个,所以变量 i 的值在没有使用 static 修饰它的存储类型时就不会按照我们预想的从 i 一直自加到 100

当然,如果不想使用 static 关键字,也可以将记录 T0 中断次数的变量 i 定义成全局变量
回复

使用道具 举报

地板
ID:1080935 发表于 2024-6-23 13:37 | 只看该作者
函数中变量为局部变量,离开该函数后该变量被释放(不保存数据),static 静态变量,离开该函数后数据保存,除了用static,用全局变量也可以,但要注意操作冲突问题,还是静态好些,只在该函数中使用,其他地方用不了。
回复

使用道具 举报

5#
ID:123289 发表于 2024-6-23 13:43 | 只看该作者
中断函数中的i,每次函数执行只将 i+1,下次中断i在上次的基础上再将 i+1。所以要求函数退出时,i 不能改动。函数退出后,其使用的变量(i),不允许改变,你看如何定义它(i)好呢?
回复

使用道具 举报

6#
ID:1109793 发表于 2024-6-23 13:47 | 只看该作者
好像不能每次调用时初始化,因此应该需要STATIC标识吧。否则可能出现无法预料的值。
那个if(falg)行,直接led = flag;可以不。甚至不用flag了,直接在定时器中断里面使用led可以不。
定时器中断里面也不用else吧。改成if(i==100){led=!led;i=0;}是不是也可以。当然static还是要的,或者干脆把i定义成全局吧。
回复

使用道具 举报

7#
ID:705846 发表于 2024-6-23 14:51 来自手机 | 只看该作者
xiaobendan001 发表于 2024-6-23 13:47
好像不能每次调用时初始化,因此应该需要STATIC标识吧。否则可能出现无法预料的值。
那个if(falg)行,直接 ...

谢谢大家回复,解释的很清楚。加static是最佳实践。实际我没有加static,i也不是全局,led灯也会闪烁。这又是什么原因呢。
回复

使用道具 举报

8#
ID:1109793 发表于 2024-6-23 16:51 | 只看该作者
samxon 发表于 2024-6-23 14:51
谢谢大家回复,解释的很清楚。加static是最佳实践。实际我没有加static,i也不是全局,led灯也会闪烁。这 ...

变量比较少,I的地址没有被分配别的变量吧。
回复

使用道具 举报

9#
ID:824490 发表于 2024-6-24 09:15 | 只看该作者
你这个定时器初始化代码呢?没有初始化也能工作,奇了怪了~
回复

使用道具 举报

10#
ID:705846 发表于 2024-6-24 12:25 来自手机 | 只看该作者
xiaobendan001 发表于 2024-6-23 16:51
变量比较少,I的地址没有被分配别的变量吧。

加了static后,确实更健壮些。没有莫名其妙的问题了。
回复

使用道具 举报

11#
ID:517951 发表于 2024-6-30 08:49 | 只看该作者
51单片机定时器的时长可以设置为500ms的, 500ms中断一次就翻转一次LED电压. 就不需要i变量计数了.

中断函数体内代码越少越好, i变量和计数代码完全可以放到main()函数内.
static 修饰变量, 就是函数体执行完毕, i的值依旧保存(i=99),下次函数被调用时就是99+1. 且其他函数是不能改变i的值.
回复

使用道具 举报

12#
ID:1127816 发表于 2024-7-2 00:09 来自手机 | 只看该作者
是否使用 static 关键字取决于你的具体需求和代码设计。如果你需要在中断服务函数之间保持 i 的值,那么使用 static 是合适的。但如果你担心重入性问题或者不希望在函数调用之间保持状态,那么你可能需要考虑其他方法来实现LED的闪烁,例如使用全局变量或者在中断服务之外维护状态。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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