⑴ 單片機怎麼用定時器替代延時函數
1、首先分析您的程序,
void
delay()
{
int
i;
if(1
==
tf0)//if(tf0==1),查詢定時器溢出標志位
{
tf0=0;
i=10000;//定時溢出時給i賦值1000
th0=0xdc;tl0=0x00;
i--;//i=999,如果還沒有減到0時定時器又溢出,則i永遠不會減到0!!!!所以您的這段程序不應該行不通!!
}
while(1)
{
if(i==0)
break
;
}
}
2、建議做法
(1)定義一個全局變數用於作定時計數如unsigned
char
n;
(2)定時器採用以某一時間基準(10ms)中斷方式,每中斷一次中斷處理程序里n++;
(3)在延時函數中對n進行操作,如延時1s即1000ms則:
void
delay_1s()
{
while(n<100);//如果n<100,即還沒有到1s就等待
n=0;如果1s時間到則清零n,退出子程序
}
當然這樣定時精度可能需要調整,但思路可以試試。
⑵ 單片機程序什麼作用啊 尤其是X++作用 定時器中斷作用是什麼呢
x應該是一個全局變數,每次中斷函數都會將x加1,程序的其餘函數會掃描x的值來做出相應的動作,
interrupt 1 是計時器中斷洞局,這里應該是用一個全局變數計時,main函數或者其他中斷函數檢查x的數值做到定時的響應,如閃燈或者屏幕刷新又或者PWM輸出 ,
定時器中斷的作用是在CPU運行期間 ,定時器在不幹擾CPU正常運行的情況下不停地將自身寄存器(從你的函數初始化看是TH0和TL0並起來的一個16位值)減一,當寄存器值為0時候發起中斷(從1減去1開始到寄存器值為0之間發起的),這樣可以做到CPU不用一直等待一個時間的到來而空轉,或者運行一個程序的過程中計算運行的時間並定時插入一個額外的工作,
C51的計時器有4個工作模式(對於At89S51或者STC89C52及以上型號來說)不同的模式有不同的功能,這個網路文庫能看到的,另外TMOD寄存器和其他寄存器還設定了計時器是外部的跳帶臘變信號或者單片機內部時鍾來引起計時器的一次減1動作(計時動作)。
另外計時器可以設置為外部輸入模式,這樣就能作為計數器,比如說一個外接的按鍵,按10次後才觸發中斷,如果用外中斷處理蠢顫滑,那麼整個主函數會被中斷九次做無效中斷才能等到第十次按鍵執行需要的中斷處理動作。
這一點在操作系統中也用到了,比如我們的PC的多任務操作系統,就是用時鍾中斷來把一個程序中斷執行另一個程序(比如操作系統和應用程序間)實現了時間片輪轉,不過PC的操作系統把所有的中斷處理函數都包含進去了,所以我們基本不用去管硬體中斷就能編程。 反觀單片機,因為資源有限,想要做到多任務(主函數與各個中斷函數及其子函數)必須用定時器(也可以通過外部信號做計數器)以及外中斷作為契機來切換多個任務。
如果需要解答整個中斷函數的功能,最好把全部的程序都帖出來,因為x這個全局變數的作用沒有在中斷函數中體現
有問題可以繼續跟我交流,我現在是大學本科生,學過C51單片機,正在學STM32
⑶ 用C語言給單片機編程時,主函數中的變數為什麼都得定義成全局變數
變數是定義成全局變數還是局部變數得看變數的在程序中所起的作用,比如如下程序:
#include <REGX52.h>
unsigned int int_count=0;
unsigned char count=0;
unsigned char second=0;
unsigned char seg[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x40};
unsigned char seg1[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
Delay_1s() //500m秒延時子程序
{unsigned char l,i,n;
for(l=50;l>0;l--)
for(i=20;i>0;i--)
for(n=248;n>0;n--);
}
void t0(void) interrupt 1 using 0
{int_count++;
if(int_count==4000)
{ int_count=0;
second=1;
}
}
void main (void)
{TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(second)
{
second=0;
P0=seg1[count];
count++;
if(count>=10)
count=0;
}
}
}
定時器輸出0到9,每一秒變化一次,其中int_count、second是全局變數這是因為,int_count是中斷次數統計,他需要在完成一次次的中斷以雹鋒後數值保持不變,如果定義成局部變數,沒發生一次中斷,它加一,中斷結束又變成0了,所以定義成全局變數,這樣他的數值會根據中斷發生的次數不斷增加。而second則因為是數碼管顯示的數組鎮舉的下標,如果定義成局部變數那麼每次函數調用結束,內存釋放變數值也就沒有了,這樣就達不到每秒輸出不同數字的要求。、
總的來講呢,如果變數的值在函數調用結束以後還會被其他的函數,活著表達式使用,源旅晌才定義成全局變數。
⑷ 51單片機定時器定時 2秒燈亮 3秒燈滅,如此循環
如果想實現無限循環那就採用死循環方式,可以無限的循環如while(1){};然後設定定時器定時時間為1s(此值需要根據單片機確定是否可以設定這么大),其次,設定一個變數對時間進行計數,根據計數情況做出相應的改變,程序可以這樣設定:
unsigned
char
gucledstatus
=
0x00;
//全局變數,表示燈當前的狀態
0為滅,1為亮
volatile
unsigned
int
gustimecnt;
//全局變數對時間計數
int
main()
{
//增加定時器初始化並開放中斷
while(1)
{
if(gucledstatus
==
0x01)
//當前為亮狀態
{
if(gustimecnt
>=
7200)
//兩個小時時間到
{
gustimecnt
=
0x00;
//清零
gucledstatus
=
0x00;
//燈為滅狀態
//此處加程序代碼,控制燈為滅的狀態
}
else
{
//此處加程序代碼,控制燈為亮的狀態,此處會重復執行,可以進行控制
}
}
else
if(gucledstatus
==
0x00)
//燈為滅的狀態
{
if(gustimecnt
>=
3600)
//1個小時
{
gustimecnt
=
0x00;
gucledstatus
=
0x01;
//亮狀態
//增加程序代碼,控制燈亮
}
else
{
//增加程序代碼,控制燈滅,此處會重復執行,可以進行控制
}
}
}
return
0;
}
在中斷函數中,對gustimecnt進行遞增即可!
⑸ c8051單片機定時器中斷求助
那為什麼要 每隔 5ms 判斷一次呢?直伏槐接在主函數判斷不行嗎?
void main()
{
while(Flag)
{
//……繼續的內容
}
while(1);//這缺羨友就是不繼派嫌續的結果,死在這里,不執行任何東西。當然,定時器還是會工作。
}
這還涉及到另一個問題,如果 這個 變數,一會 0,一會 1,一會又 0,一會 又 1,你想咋整啊?
⑹ 單片機兩分鍾定時器,從2:00:00~0:00:00
通過這個函埋瞎數可以定時A*time ms
定時器精確定時Ams的程序
uchar T0RH,T0RL; //全局變數
uint time;
void configtime(uchar ms)
{
unsigned long tmp;
tmp=11059200/12;//晶振除12,就是機器周期每秒的次數
tmp=(tmp*ms)/1000;//除以1000,就是每毫秒的次塌液散數,乘ms,即每ms毫秒的次數
tmp=65536-tmp; //轉換為計數初值;
tmp=tmp+18; //補償中斷響應延團氏時造成的誤差
T0RH=(uchar)(tmp>>8);
T0RL=(uchar)tmp;
TMOD=0x01;
TH0=T0RH;
TL0=T0RL;
ET0=1;
TR0=1;
}
void Timer0() interrupt 1
{
TH0=T0RH;
TL0=T0RL;
time++;
}
⑺ 單片機定時器中斷改變全局變數
int h1,m1,s1; //時分秒全局變數
int tt; //定時器0進入中斷的次數
void main()
{
init(); //初始化
while(1)
{
display(h1,m1,s1);
}
}
void dingshi0() interrupt 1 //定時器0中斷
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==20)
{
tt=0;
s1++; //秒數+1
if(s1==60){ s1=0; m1++;}//計滿60秒分位進1,秒位清0
if(m1==60){ m1=0; h1++; }//計滿60分時位進1
if(h1==24){ h1=0; }//計滿24小時時位清0
}
}
在中斷內,你可以直接寫成這樣
只用全局變數更方便
再有,你苦惱的問題是因為函數每次調用的時候
都是以0為數據傳遞的,錯誤在串口初始化部分以及你調用函數的時候
你的變數S,沒有全局變數聲明,切也沒有局部變數聲明
所以每次調用函數的時候,S都是以0開始,最多加到1,之後又從0開始遞增
⑻ 單片機中什麼叫做全局變數,請幫忙謝謝
單改培片機中全局變數就是在所有子程序中都通用的變數,一般在主程序的前面部位聲明,當然也可以在其他侍殲斗位置聲明,只要老磨在子程序外部就可以。
⑼ 51單片機50ms定時
12MHz 的晶振,那麼一個周穗磨期就是 1 us,所以需要計數 50ms / 1us = 50000,可以選唯圓擇定時器工作方式 1。
由上述計算:
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
方式一,所以:
TMOD = 0x10;
運行 TR1 = 1,所以:
TCON = 0x40;
允許中斷 ET1 = 1,EA = 1,所以:
IE = 0x88;
綜合可以編寫如下程序(匯編我不會指族塌,不知道你要的是匯編還是C):
#include <reg52.h>
void timer1_int() interrupt 3
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
}
void timer1_init()
{
TH1 = (65536 - 50000) / 256;
TL1 = (65536 - 50000) % 256;
TMOD = 0x10;
IE = 0x88;
TCON = 0x40;
}
void main()
{
timer1_init();
while(1);
}
⑽ 請教如何用51單片機的一個定時器計算三路開關量輸入的頻率
方案1:51的定時器定時時間不長,為了解決這一問題,可以設置一全局變數(假設你用c編程序)作計數器,等到定時中斷發生時中斷函數給這一全局變數加一,在主程序中判斷這一變數的大小,從而推算出定時時間。譬如說,定時器設置成0.5秒中斷一次,中斷時給變數t加一,那麼當t等於16時,就是8秒了。這種方案的缺點是必須在中斷函數中加入給變數加一的額外語句,使得定時出現誤差,但是也能通過減少定時器的定時時間來補償,不過計算較麻煩,而且不便於精確定時。
方案2:使用低頻的晶振或低頻外部震盪。有些型號的單片機支持0至12mhz的震盪頻率,只要頻率足夠低絕對能夠在定時器最大定時時間內產生出想要的脈沖。這種方案是以犧牲單片機的運行速度為前提的,不過要是做一些簡單控制的話,倒是一種不錯的選擇。