找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1474|回復: 11
收起左側(cè)

中斷函數(shù)內(nèi)增加static關(guān)鍵字的問題

[復制鏈接]
ID:705846 發(fā)表于 2024-6-23 11:11 | 顯示全部樓層 |閱讀模式
代碼要求led間隔0.5秒閃爍,在定時中斷函數(shù)內(nèi)的unsigned char i變量是否有必要增加static關(guān)鍵字。原因是什么,謝謝大家。
或者有更優(yōu)化的代碼。

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;}
                }               
}


回復

使用道具 舉報

ID:59202 發(fā)表于 2024-6-23 13:21 | 顯示全部樓層
如果你這樣寫成局部變量就要加上static,因為局部變量退出函數(shù)后會被銷毀,再次進入函數(shù)后會先初始化為零;蛘吣愀纱嘣O(shè)置成全局變量
回復

使用道具 舉報

ID:866313 發(fā)表于 2024-6-23 13:22 | 顯示全部樓層
在你的代碼中,必須使用static關(guān)鍵字來聲明局部變量 i 因為局部變量如果沒有使用 static 限定,默認就是 auto 類型的,那么每次 5ms 定時時間到,中斷服務函數(shù)就會被調(diào)用一次,每次調(diào)用,變量 i 的值又會重新歸為垃圾值,主要是需要理解函數(shù)調(diào)用時會給該函數(shù)分配一個棧空間,并不能保證每次分配的都是同一個,所以變量 i 的值在沒有使用 static 修飾它的存儲類型時就不會按照我們預想的從 i 一直自加到 100

當然,如果不想使用 static 關(guān)鍵字,也可以將記錄 T0 中斷次數(shù)的變量 i 定義成全局變量
回復

使用道具 舉報

ID:1080935 發(fā)表于 2024-6-23 13:37 | 顯示全部樓層
函數(shù)中變量為局部變量,離開該函數(shù)后該變量被釋放(不保存數(shù)據(jù)),static 靜態(tài)變量,離開該函數(shù)后數(shù)據(jù)保存,除了用static,用全局變量也可以,但要注意操作沖突問題,還是靜態(tài)好些,只在該函數(shù)中使用,其他地方用不了。
回復

使用道具 舉報

ID:123289 發(fā)表于 2024-6-23 13:43 | 顯示全部樓層
中斷函數(shù)中的i,每次函數(shù)執(zhí)行只將 i+1,下次中斷i在上次的基礎(chǔ)上再將 i+1。所以要求函數(shù)退出時,i 不能改動。函數(shù)退出后,其使用的變量(i),不允許改變,你看如何定義它(i)好呢?
回復

使用道具 舉報

ID:1109793 發(fā)表于 2024-6-23 13:47 | 顯示全部樓層
好像不能每次調(diào)用時初始化,因此應該需要STATIC標識吧。否則可能出現(xiàn)無法預料的值。
那個if(falg)行,直接led = flag;可以不。甚至不用flag了,直接在定時器中斷里面使用led可以不。
定時器中斷里面也不用else吧。改成if(i==100){led=!led;i=0;}是不是也可以。當然static還是要的,或者干脆把i定義成全局吧。
回復

使用道具 舉報

ID:705846 發(fā)表于 2024-6-23 14:51 來自觸屏版 | 顯示全部樓層
xiaobendan001 發(fā)表于 2024-6-23 13:47
好像不能每次調(diào)用時初始化,因此應該需要STATIC標識吧。否則可能出現(xiàn)無法預料的值。
那個if(falg)行,直接 ...

謝謝大家回復,解釋的很清楚。加static是最佳實踐。實際我沒有加static,i也不是全局,led燈也會閃爍。這又是什么原因呢。
回復

使用道具 舉報

ID:1109793 發(fā)表于 2024-6-23 16:51 | 顯示全部樓層
samxon 發(fā)表于 2024-6-23 14:51
謝謝大家回復,解釋的很清楚。加static是最佳實踐。實際我沒有加static,i也不是全局,led燈也會閃爍。這 ...

變量比較少,I的地址沒有被分配別的變量吧。
回復

使用道具 舉報

ID:824490 發(fā)表于 2024-6-24 09:15 | 顯示全部樓層
你這個定時器初始化代碼呢?沒有初始化也能工作,奇了怪了~
回復

使用道具 舉報

ID:705846 發(fā)表于 2024-6-24 12:25 來自觸屏版 | 顯示全部樓層
xiaobendan001 發(fā)表于 2024-6-23 16:51
變量比較少,I的地址沒有被分配別的變量吧。

加了static后,確實更健壯些。沒有莫名其妙的問題了。
回復

使用道具 舉報

ID:517951 發(fā)表于 2024-6-30 08:49 | 顯示全部樓層
51單片機定時器的時長可以設(shè)置為500ms的, 500ms中斷一次就翻轉(zhuǎn)一次LED電壓. 就不需要i變量計數(shù)了.

中斷函數(shù)體內(nèi)代碼越少越好, i變量和計數(shù)代碼完全可以放到main()函數(shù)內(nèi).
static 修飾變量, 就是函數(shù)體執(zhí)行完畢, i的值依舊保存(i=99),下次函數(shù)被調(diào)用時就是99+1. 且其他函數(shù)是不能改變i的值.
回復

使用道具 舉報

ID:1127816 發(fā)表于 2024-7-2 00:09 來自觸屏版 | 顯示全部樓層
是否使用 static 關(guān)鍵字取決于你的具體需求和代碼設(shè)計。如果你需要在中斷服務函數(shù)之間保持 i 的值,那么使用 static 是合適的。但如果你擔心重入性問題或者不希望在函數(shù)調(diào)用之間保持狀態(tài),那么你可能需要考慮其他方法來實現(xiàn)LED的閃爍,例如使用全局變量或者在中斷服務之外維護狀態(tài)。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表