Ⅰ 單片機定時/應用問題請教下
開始5個代表什麼意思 ORG 0000H LJMP MAIN 是不是在0000H單元 跳轉到主程序 ORG 000BH?
-------開始 寫ORG 000H, LJMP MAIN , 就是說LJMP MAIN 放在單片機的000H 位置,一般單片RESET 後開始運行的地址就是0000H, 這句話的作用是單片上電後或RESET後就跳到MAIN:這個地方,不是跳到ORG 000BH 這個地方,而是ORG 0100H這個地方,也就是MAIN的地方,ORG 的作用就是設定ORG 後面的程序從這個地方開始放。
LJMP DVTO 這兩個又是什麼意思 有什麼聯系 最後的ORG 0100H 代表什麼?
------ ORG 000BH 這個地方是單片機的中斷點,就是有中斷,單片就會到這里,這里的程序LJMP DVTO就是跳到中斷服務程序的了!ORG 0100H 代表MAIN:MOV TMOD,#01H, 開始從地址0100H 放!
中斷程序中 CPL P1.0取反的作用 以及為什麼又要在中斷程序中重新設定計數初值 MOV TH0 #0D8H MOV TL0,#0F0H 不是最後的中斷返回RETI 返回主程序 將中斷響應時保存的斷點從棧頂彈回送PC CPU從原來中斷的地方執行程序 那麼中斷程序中設定計數初值的作用是什麼?
-------CPL P1.0 的作用就是產生方波,高,低,變化。 中斷返回的地方是這里SJMP $
,所以你也知道中斷的程序里為什麼會設定計數初值的了!
Ⅱ 介紹計數器 /定時器 程序 的編寫步驟 (C語言的)
注意:
多數C語言編譯器不支持多線程,而且ANSI C也沒有線程庫,因此C語言無法實現實際意義上的定時器(即包含觸發機制的定時器)。
回到本問題:
1 計數器:
簡單的int變數(一般為全局或相對全局)就可以實現。
2 計時器:
包含time.h,使用clock相關函數,通過運行時間差來實現計時功能。示例:
/*@*/ clock_t startstart = clock();
……
/*@*/ clock_t endend = clock();
float start2end = (float)(endend-startstart)/CLOCKS_PER_SEC;
// 這里的start2end就是時間差
3 定時器
使用系統API,比如Windows下的Sleep()函數(注意,是大寫),原型如下:
VOID Sleep(
DWORD dwMilliseconds // sleep time in milliseconds
);
Ⅲ 單片機定時器計數器如何使用
使用12MHz晶振,其機器周期為1us
欲產生5000us周期方波,只需在p1.0以2500us時間交替輸出高低電平
1.T0為方式0,則M1M0=00H。使用定時功能,C/T=0,GATE=0。T1不用,其有關位設為0。因此,TMOD=00H
2.方式0為13長度計數(TL0高3位不使用),設計數初值為X,則(8192-X)*1us=2500us,得X=5692D。X=1011000111100B。因為TL0高3位不用,所以10110001-00011100B得TH0=B1H,TL0=1CH
3.由控制寄存器TCON的TR0位來控制定時的啟動和停止,TR0=1啟動,TR0=0停止
C語言程序如下(編譯器Keil C)
#include<REG51.H>
sbit FB=p1^0;
void initial(void)
{
TMOD=0x00;
TH0=0xb1;
TL0=0x1c;
IE=0x00;
TR0=1;
}
void main(void)
{
initial();
for(;;)
{
while(!TF0);
TF0=0;
FB=!FB;
}
}
匯編程序如下
ORG 0000H
AJMP START
ORG 30H
START: MOV P1.0,#0FFH
MOV TMOD,#00H
MOV TH0,#0B1H
MOV TL0,#1CH
SETB TR0
LOOP: JBC TF0,NEXT
LJMP LOOP
NEXT: CPL P1.0
MOV TH0,#0B1H
MOV TL0,#1CH
LJMP LOOP
END
Ⅳ 單片機高手給點撥下,定時器這個不太理解,定時器初始化有幾種方法啊比如說定時1毫秒
51 單片機中定時器,是個 16 位的加法計數器。
其內容是 0000H ~ FFFFH,即:0 ~ 65535。
每隔一個機器周期,加一次一。加到 65536,就會溢出,產生中斷。
在外部振盪器頻率 = 11.0592 MHz 時,機器周期=1085.06944...us。
要想定時 1000us,這就有點困難了。
在外部振盪器頻率 = 12 MHz 時,機器周期=1us。
要想定時 1000us,就可以設初始值為:65536 - 1000 = 64536。
分成高、低八位後,寫入 THx、TLx,即可。
求出:初始值、分成高低八位,可以人工計算,那麼,程序就是:
TH1 = 0XFC;
TL0 = 0X67;
也可以由編譯軟體來算,程序中,寫出公式,這就是:
TH0 = (65535 - 1000)/256;
TL0 = (65535 - 1000)%256;
-------
又因為,中斷響應,是不會及時發生的,通常,都會遲到 3 ~ 8 個機器周期。
用 C 語言編程,會耽誤更多吧。
所以,定時時間,應該縮短一些,定時才准確。
因此,才有+ 28 的演算法。
加上這個數之後,初始值,就大了一些,更接近 65536,定時時間,就短了。
這是個經驗數據。
Ⅳ linux下的幾種時鍾和定時器機制
1. RTC(Real Time Clock)
所有PC都有RTC. 它和CPU和其他晶元獨立。它在電腦關機之後還可以正常運行。RTC可以在IRQ8上產生周期性中斷. 頻率在2Hz--8192HZ.
Linux只是把RTC用來獲取時間和日期. 當然它允許進程通過對/dev/rtc設備來對它進行編程。Kernel通過0x70和0x71 I/O埠來訪問RTC。
2. TSC(Time Stamp Counter)
80x86上的微處理器都有CLK輸入針腳. 從奔騰系列開始. 微處理器支持一個計數器. 每當一個時鍾信號來的時候. 計數器加1. 可以通過匯編指令rdtsc來得到計數器的值。通過calibrate_tsc可以獲得CPU的頻率. 它是通過計算大約5毫秒里tsc寄存器裡面的增加值來確認的。或者可以通過cat /proc/cpuinfo來獲取cpu頻率。tsc可以提供比PIT更精確的時間度量。
3. PIT(Programmable internval timer)
除了RTC和TSC. IBM兼容機提供了PIT。PIT類似微波爐的鬧鍾機制. 當時間到的時候. 提供鈴聲. PIT不是產生鈴聲. 而是產生一種特殊中斷. 叫定時器中斷或者時鍾中斷。它用來告訴內核一個間隔過去了。這個時間間隔也叫做一個滴答數。可以通過編譯內核是選擇內核頻率來確定。如內核頻率設為1000HZ,則時間間隔或滴答為1/1000=1微秒。滴答月短. 定時精度更高. 但是用戶模式的時間更短. 也就是說用戶模式下程序執行會越慢。滴答的長度以納秒形式存在tick_nsec變數裡面。PIT通過8254的0x40--0x43埠來訪問。它產生中斷號為IRQ 0.
下面是關於pIT裡面的一些宏定義:
HZ:每秒中斷數。
CLOCK_TICK_RATE:值是1,193,182. 它是8254晶元內部振盪器頻率。
LATCH:代表CLOCK_TICK_RATE和HZ的比率. 被用來編程PIT。
setup_pit_timer()如下:
spin_lock_irqsave(&i8253_lock, flags);
outb_p(0x34,0x43);
udelay(10);
outb_p(LATCH & 0xff, 0x40);
udelay(10);
outb (LATCH >> 8, 0x40);
spin_unlock_irqrestore(&i8253_lock, flags);
4. CPU Local Timer
最近的80x86架構的微處理器上的local apic提供了cpu local timer.他和pit區別在於它提供了one-shot和periodic中斷。它可以使中斷發送到特定cpu。one-shot中斷常用在實時系統裡面。
Ⅵ 單片機實驗「定時/計數器及中斷」的一些問題
1.1)主程序各行作用如下:
第一行:設置定時器模式
第二行:設置定時器高位寄存器初值
第三行:設置定時器低位寄存器初值
第四行:T0定時器中斷使能
第五行:總中斷使能
第六行:打開T0定時器
第七行:死循環(主程序停留在此行)
主程序整體實現的功能:初始化定時器T0
1.2)void Timer0_Int(void)是定時器0中斷函數,每行作用如下:
第一行:重新設定定時器高位寄存器初值
第二行:重新設置定時器低位寄存器初值
第三行:如果P1_0 IO口是高電平則改為低電平,如是低電平改為高電平
整體實現的功能:P1_0 IO口高低電平1秒切換一次
媽呀,這么多問題,網上找找,應該有的
Ⅶ (微機原理)用8086,8253,8251,8255,8259和8237其中的幾種設計一個簡單的實驗,請給點思路
可編程定時/計數器8253實驗
一、實驗要求
利用8086外接8253可編程定時/計數器,可以實現方波的產生。
二、實驗目的
1、學習8086與8253的連接方法。
2、學習8253的控制方法。
3、掌握8253定時器/計數器的工作方式和編程原理
三、實驗說明
8253晶元介紹
8253是一種可編程定時/計數器,有三個十六位計數器,其計數頻率范圍為0-2MHz,用+5V單電源供電。
8253的功能用途:
⑴延時中斷;⑵可編程頻率發生器;⑶事件計數器;⑷二進制倍頻器⑸實時時鍾;⑹數字單穩⑺復雜的電機控制器。
8253的六種工作方式:
⑴方式0:計數結束中斷;⑵方式l:可編程頻率發生;⑶方式2:頻率發生器;⑷方式3:方波頻率發生器;⑸方式4:軟體觸發的選通信號;⑹方式5:硬體觸發的選通信號。
四、實驗步驟
1、Proteus模擬
a.在Proteus中打開設計文檔「8253_STM.DSN」;
b.建立實驗程序並編譯,模擬;
c.如不能正常工作,打開調試窗口進行調試。
參考程序:
CODE SEGMENT
ASSUMECS:CODE
START:
JMPTCONT
TCONTROEQU0A06H
TCON0EQU0A00H
TCON1EQU0A02H
TCON2 EQU0A04H
TCONT:
MOVDX,TCONTRO
MOVAL,16H;計數器0,只寫計算值低8位,方式3,二進制計數
OUTDX,AL
MOVDX,TCON0
MOVAX,20 ;時鍾為1MHZ,計數時間=1us*20=20us,輸出頻率50KHZOUTDX,AL
JMP$
CODEENDS
ENDSTART
五、實驗電路及連線
1、Proteus實驗電路
Ⅷ 關於51單片機定時/計數器裝入初值的問題
這個有什麼看不懂得呢 第一種 是吧十進制化成十六機制的方法 第二種呢 就是單純的十進制
這樣跟你說吧 因為th0隻有一個位元組 那就只能放下8位2進制 於是第一種表示就是把一個大於一個位元組小於兩個位元組的數據轉化成兩個位元組高八位和第八位的分離形式
第二種就簡單了 0x9c就是65536-100的十六進製表示啊
那高八位就是前兩個十六進制數ff就裝到th0中 低八位就是後兩個十六進制數9c 裝到th1中唄3
這有啥看不懂的啊
這個真的基礎到不行了 沒法再解釋啊
至於轉化嗎
你去找c語言教程 16進制與十進制的轉化 再好好學學
這個是絕對的基礎啊
Ⅸ 單片機定時器與計數器的區別
在51單片機的學習過程中,我們經常會發現中斷、計數器/定時器、串口是學習單片機的難點,兩者的區別是什麼呢?下面就跟著我一起來看看吧。
單片機計數器與定時器的區別
計數器和定時器的本質是相同的,他們都是對單片機中產生的脈沖進行計數,只不過計數器是單片機外部觸發的脈沖,定時器是單片機內部在晶振的觸發下產生的脈沖。當他們的脈沖間隔相同的時候,計數器和定時器就是一個概念。
在定時器和計數器中都有一個溢出的概念,那什麼是溢出了。呵呵,我們可以從一個生活小常識得到答案,當一個碗放在水龍頭下接水的時候,過了一會兒,碗的水滿了,就發生溢出。同樣的道理,假設水龍頭的水是一滴滴的往碗里滴,那麼總有一滴水是導致碗中的水溢出的。在碗中溢出的水就浪費了,但是在單片機的定時計數器中溢出將導致一次中斷,至於什麼是中斷我們下次再講,這里只是初步的提下概念,中斷就是能夠打斷系統正常運行,而去運行中斷服務程序的過程,當服務程序運行完以後又自動回到被打斷的地方繼續運行。
在定時器計數器中,我們有個概念叫容量,就是最大計數量。方式0是2的13次方,方式1是2的13次方,方式2是2的8次方,方式3是2的8次方。把水滴比喻成脈沖,那麼導致碗中水溢出的最後一滴水的就是定時計數器的溢出的最後一個脈沖。
在各種單片機書本中,在介紹定時計數器時都講到一個計數初值,那什麼是計數初值呢?在這里我們還是假設水滴碗。假設第一百滴水能夠使碗中的水溢出,我們就知道這個碗的容量是100。問題1,我如何才能使碗接到10滴水就溢出呢?呵呵,我可以想像,如果拿一個空碗去接水,那麼還是得要100滴水才能溢出,但是如果我們拿一個已經裝有水的碗拿去接,那就不用100滴了。到此我們可以算出,要使10滴水讓碗中的水溢出,那麼碗中就先要裝90滴水。
在定時計數器中,這90滴水就是我們所謂的初始值。問題2,在一個車間我們如何利用單片機對100件產品進行計件,並進行自動包裝呢?
我們可以利用計數器計數100,在中斷中執行一個自動包裝的動作就可以了。
在這里計數初值有3個,假設有方式0:計數初值=8912(2的13次方)—100=8812。方式1:計數初值=65536(2的16次方)—100=65436。方式0:計數初值=256(2的8次方)—100=156。
根據所得的初始值,再將其轉換為16進制或者2進制,就可以進行計數或者定時了。當然要讓程序完全的運行起來還需要相應的寄存器進行設置。這些可以從各種單片機教程中找到。
單片機中定時器與計數器的區別
定時器實際上也是計數器,只是計數的是固定周期的脈沖
定時/計數器很容易理解的啊
定時器實際上也是工作在計數方式下,只是計數的是固定周期的脈沖,由於脈沖周期固定,由計數值可以計算時間,有定時功能
定時和計數只是觸發來源不同(時鍾信號和外部脈沖)其他方面是一樣的。
單片機里的寄存器可以看成一個個電子開關,用來切換不同的功能、信號。
51里通過TMOD里的T/C 位切換計數信號的來源
當T/C工作在定時器時,對振盪源12分頻的脈沖計數,即每個機器周期計數值加1,計數頻率為1/12fosc,當晶振頻率6MHZ時,計數頻率為500KHz,每2us計數值加1;晶振12MHZ就是每1us加1 了。
當T/C工作在計數器是,計數脈沖來自外部脈沖輸入管腳T0(P3.4)或T1(P3.5),當T0或T1腳上負跳變時計數值加1 ,識別管腳負跳變需要2個機器周期,即24個振盪周期。所以T0或T1腳輸入的可計數的外部脈沖的最高頻率為1/24fosc,當晶振12MHZ時,最高計數頻率為500KHz,高於此頻率將計數出錯。
至於賦初值就是杯子原理了,由於51隻能加計數,且只能在杯子剛剛滿的那一刻發出中斷,觸發中斷程序,所以我們就往杯子里先放好一定的豆子,再來相應數量的豆子就滿了,然後中斷程序就自動工作了。
注意:
定時和計數只是觸發來源不同(時鍾信號和外部脈沖)其他方面是一樣的。
假設我們要定時一定時間(100個機器周期),我們就置初值為(溢出值-100)就行了,假設我們要計件100個,實際上也是置初值為(溢出值-100),然後將輸入脈沖設為外部輸入就可以了
所以說:定時和計數只是觸發來源不同(時鍾信號和外部脈沖)其他方面是一樣的。
在中斷里置初值是為下一個循環作準備,沒什麼好說的,看需要定了。
由於定時計數器的值也可以隨時讀出來,所以我們也可以從0開始計數,從而計算一段時間或一定脈沖的數量哦,這是照樣可以打開中斷,中斷時就說明已經又計數了(定時器溢出值)個脈沖哦,在中斷里進行溢出處理,就可以計算出遠遠大於(定時器溢出值)的數字了
此時也要注意一點:51讀數時除了T/C2的捕捉功能,直接讀TH和TL可是不斷變化的哦,具體的還是看書。當你理解了定時計數器後,我們甚至還可以將計數值置為(溢出值-1),從而實現自動單步(定時模式)或作為外部中斷(計數模式)用哦,仔細想想吧,呵呵;-)
至於中斷中的需要保護現場的原因,是為了防止不小心修改了別的程序的參數,從而影響別的程序的運行,所以要且只要保護中斷程序自己動過的數據,將動過的那些存儲器在退出中斷時恢復到進入時的狀態,就不會影響被中斷的程序了。
匯編需要自己保存現場,反正程序就是自己編的嘛,一切盡在掌握中;
C的話編譯器會自動進行覆蓋分析,自動保存需要保存的變數,一般應用時盡可放心,當然,如果你很了解編譯器做了什麼,也可以嵌入匯編天馬行空自由發揮啊,但新手可不建議這樣哦,還是交給編譯器吧。
其實這些可以說都是基礎知識啊,如果不明白肯定是你的書看的不夠仔細哦.
猜你喜歡
1. 單片機的硬體結構是什麼
2. 10秒定時器電路設計
3. 單片機技術論文
4. 單片機的發聲原理
5. 單片機開題報告範文
6. 電子實習報告單片機
7. 單片機實訓報告範文3篇
Ⅹ 89c51單片機定時計數器的工作原理
單片機C51計數器要求:編寫一個計數器程序,將T0作為計數器來使用,對外部信號計數,將所計數字顯示在數碼管上。 該部分的硬體電路如圖所示,U1的P0口和P2口的部份引腳構成了6位LED數碼管驅動電路,數碼管採用共陽型,使用PNP型三極體作為片選端的驅動,所有三極體的發射極連在一起,接到正電源端,它們的基極則分別連到P2.0…P2.5,當P2.0…P2.5中某引腳輸是低電平時,三極體導通,給相應的數碼管供電,該位數碼管點亮哪些筆段,則取決於筆段引腳是高或低電平。圖中看出,所有6位數碼管的筆段連在一起,通過限流電阻後接到P0口,因此,哪些筆段亮就取決於P0口的8根線的狀態。 編寫程序時,首先根據硬體連線寫出LED數碼管的字形碼、位驅動碼,然後編寫程序如下: #include "reg51.h"#define uchar unsigned char#define uint unsigned int uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};//位驅動碼uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};//字形碼uchar DispBuf[6]; //顯示緩沖區 void Timer1() interrupt 3{ uchar tmp;uchar Count; //計數器,顯示程序通過它得知現正顯示哪個數碼管TH1=(65536-3000)/256;TL1=(65536-3000)%256; //重置初值tmp=BitTab[Count]; //取位值P2=P2|0xfc; //P2與11111100B相或P2=P2&tmp; //P2與取出的位值相與tmp=DispBuf[Count];//取出待顯示的數 tmp=DispTab[tmp]; //取字形碼P0=tmp;Count++;if(Count==6)Count=0; }void main(){ uint tmp;P1=0xff;P0=0xff;TMOD=0x15; //定時器0工作於計數方式1,定時器1工作於定時方式1TH1=(65536-3000)/256;TL1=(65536-3000)%256; //定時時間為3000個周期TR0=1; //計數器0開始運行TR1=1;EA=1;ET1=1;for(;;){ tmp=TL0|(TH0<<8);//取T0中的數值DispBuf[5]=tmp%10;tmp/=10;DispBuf[4]=tmp%10; tmp/=10;DispBuf[3]=tmp%10;tmp/=10;DispBuf[2]=tmp%10;DispBuf[1]=tmp/10;DispBuf[0]=0;}} 這個程序中用到了一個新的知識點,即數組,首先作一個介紹。 數組是C51的一種構造數據類型,數組必須由具有相同數據類型的元素構成,這些數據的類型就是數組的基本類型,如:數組中的所有元素都是整型,則該數組稱為整型數組,如所有元素都是字元型,則該數組稱為字元型數組。 數組必須要先定義,後使用,這里僅介紹一維數組的定義,其方式為: 類型說明符數組名[整型表達式] 定義好數組後,可以通過:數組名[整型表達式]來使用數組元素。 在定義數組時,可以對數組進行初始化,即給其賦予初值,這可用以下的一些方法實現: 1.在定義數組時對數組的全部元素賦予初值:例:int a[5]={1,2,3,4,5}; 2.只對數組的部分元素初始化;例:int a[5]={1,2}; 上面定義的a數組共有5個元素,但只對前兩個賦初值,因此a[0]和a[1]的值是1、2,而後面3個元素的值全是0。 3.在定義數組時對數組元素的全部元素不賦初值,則數組元素值均被初始化為0 4.可以在定義時不指明數組元素的個數,而根據賦值部分由編譯器自動確定例:uchar BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};則相當於定義了一個BitTab[6]這樣一個數組。 5.可以為數組指定存儲空間,這個例子中,未指定空間時,將數組定義在內部RAM中,可以用code關鍵字將數組元素定義在ROM空間中。uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB}; 用這兩種定義分別編譯,可以看出使用了code關鍵字後系統佔用的RAM數減少了,這種方式用於編程中不需要改變內容的場合,如顯示數碼管的字形碼等是很合適的。 6.C語言並不對越界使用數組進行檢測,例如上例中數組的長度是6,其元素應該是從BitTab[0]~BitTab[5],但是如果你在程序中寫上BitTab[6],編譯器並不會認為這有語法錯誤,也不會給出警告(其他語言如BASCI等則有嚴格的規定,這種情況將視為語法錯誤),因此,編程者必須自己小心確認這是否是你需要的結果。 程序分析:程序中將定時器T1用作數碼管顯示,通過interrupt 3關鍵字定義函數Timer1()為定時器1中斷服務程序,在這個中斷服務程序中,使用 TH1=(65536-3000)/256;TL1=(65536-3000)%256; 來重置定時器初值,這其中3000即為定時周期,這樣的寫法可以直觀地看到定時周期數,是常用的一種寫法。其餘程序段分別完成取位碼以選擇數碼管、從顯示緩沖區獲得待顯示數值、根據該數值取段碼以點亮相應筆段等任務。其中使用了一個計數器,該計數器的值從0~5對應第1到第6位的數碼管。 主程序的第一部分是做一些初始化的操作,設置定時器工作模式、開啟定時器T1、開啟計數器T0、開啟T1中斷及總中斷,隨後進入主循環,主循環首先用unsigned int型變數tmp取出T0中的數值,這里使用了「tmp=TL0|(TH0<<8);」這樣的形式,這相當於tmp=TH0*256+TL0,但比之於後一種形式,該方式可以得到更高的效,其後就是將tmp值不斷地除10取整,這樣將int型數據的各位分離並送入相應的顯示緩沖區