单片机定时器实验两位倒计时秒表_51单片机基础与应用8天速成(三)
在講授中斷這一概念時,人們總是喜歡舉洗衣服燒水的例子:
話說,一天“你”獨自在家,為了泡腳給自己燒上了一壺水,然后想著明天沒有衣服穿了,就去陽臺洗起了衣服。過了十幾分鐘,“你”在陽臺洗著衣服,突然聽到了廚房燒水壺沸騰的鳴叫,所以,“你”放下洗了一半的衣服,去關閉了煤氣灶,接著又返回陽臺繼續洗衣服。在這個小故事中,如果我們把燒水和洗衣服分別看作兩個進程,那么顯然,燒水壺沸鳴對應的是中斷請求,洗衣服則是正常運行的主進程,高優先級進程通過向CPU提交中斷請求的方式,暫時中斷主進程轉而運行其他進程,利用有限的CPU資源,盡可能的做到了對效率和實時性的兼顧。
在第一天的教程中曾經提到過,我們會用三天的時間分別學習外部中斷、定時器/計數器中斷以及串口中斷,占據全部八天課程的三分之一還多,單單從課程安排上,大家就可以體會到中斷在單片機學習中的重要地位。
中斷的優先級
當有多個中斷同時被提交,那么CPU該選擇響應哪個中斷呢?這要從中斷源的類型來分
單片機的中斷源分為三類:
外部中斷
定時器/計數器中斷
串口中斷
但單片機最基本的中斷源卻有5個:
外部中斷0
定時器/計數器中斷0
外部中斷1
定時器/計時器中斷1
串口中斷
(排列即為他們的優先級)
豐富的中斷源可以大大提高單片機的便捷性,有些較新的單片機已經擁有了8個中斷源,但本教程中只講單片機必備的5個中斷源的使用.
在洗衣燒水的小故事中,我們已經意識到了優先級這一概念的存在,高優先級的中斷將被優先執行,且可以打斷低優先級的中斷,反之則不能。5個中斷源的優先級(或查詢次序)已經被指定,在軟件編程中又有著相對應的中斷號(0-4),軟件編程里的中斷號與中斷優先級匹配正確,程序才能正常進入中斷(程序中會再次講解)。
特殊功能寄存器
前面也曾講過,對單片機的編程,基本可以說是對單片機內部寄存器的操作,五種中斷所涉及到的特殊寄存器以及各個位的功能講解如下:
IE寄存器(中斷允許控制寄存器)
IE:EAXXESET1EX1ET0EX0
其中,EA為總中斷允許位,ES為串口中斷允許位。
ET1、ET0分別是定時器/計數器1與定時、計數器0中斷允許位。
EX1、EX0為外部中斷1與外部中斷0中斷允許位。
可以看到,IE寄存器可以控制所有中斷的開關,而且支持位尋址。
TCON寄存器(定時器/計數器控制寄存器)TCON:TF1TR1TF0TR0IE1IT1IE0IT0
其中,TF1、TF0分別為定時器T1/T0溢出標志位,當定時器溢出時狀態改變,無需手動設置。
TR1/TR0分別為定時器1/定時器0中斷允許位
IE1/IE0分別為外部中斷請求標志位,IT1/IT0分別設置兩個外部中斷源的觸發方式(0上升沿觸發,1下降沿觸發)。
TCON寄存器支持位尋址。
TMOD寄存器(定時器/計數器模式控制寄存器)
TMOD:GATEC/TM1M0GATEC/TM1M0
其中,GATE為門控制位,當此位為1時,外部中斷被觸發與定時器中斷允許位同時為1,才會開啟定時器/計數器。
兩個C/T位,分別是定時器/計數器1模式選擇位,0為定時器模式,1為計數器模式。
M1M0,設置定時器/計數器1/0工作方式,00為13位定時/計數器模式,01為16位定時器/計數器模式,10為8位定時/計數器自重裝模式(就是自動歸零),11則是指將T0分為兩個8位定時/計數器,T1停止計數。
要注意的是,TMOD不支持位尋址,只能對整體賦值
T0寄存器組:TH0TL0
T1寄存器組:TH1TL1
以上兩種寄存器分別是定時/計數器的計數初值設定,TH是高八位,TL指低八位,這兩者共同控制定時器/計數器溢出的時間(在定時/計數器中斷一節會詳細講解)
從上面的總體介紹中,我們單獨提取外部中斷需要設置的寄存器:IE寄存器中的EA、EX,TCON中的IT1、IT0,同時需要接線P3^2、P3^3外部中斷引腳
接下來,我們將會在上次流水燈的項目基礎上,使用外部中斷的方式讓按鈕控制流水燈的切換
原理圖
本項目新增Button元件(按鈕),原理圖如下:
說明:
emm,沒什么特別好說的,看圖連接就行了,注意整潔美觀。
keli中的代碼
#include
#include
sbit k0 = P3^2;
sbit k1 = P3^3;
sbit LED = P2^0;
void IntInit()
{
EA = 1;//打開總中斷
IT0 = 1;//設置觸發方式為下降沿
EX0 = 1;
IT1 = 1;
EX1 = 1;
P0 = 0x01;
k0 = k1 = 1;
}
void main()
{
IntInit();
while(1);
}
void Int0() interrupt 0
{
if(k0 == 0)
{
P0=P0>>1;
}
if(P0==0x00)
{
P0 = 0x80;
}
}
void Int1() interrupt 2
{
LED = 0;
if(k1 == 0)
{
P0=P0<<1;
}
if(P0==0x00)
{
P0 = 0x01;
}
}
說明
說明:
1.頭文件中包含了很多匯編會用的操作,比如這個項目中使用的左移右移運算,可以大大簡化代碼
2.IntInit()函數主要用來初始化外部中斷,其中語句的順序可以調換,可以依照自己的習慣或者記憶方式,自行設計安排。
3.void Int0() interrupt 0 、void Int1() interrupt 2分別對應外部中斷0與外部中斷1,interrupt之后跟的數字就是我們之前說的優先級標號,格式不能錯,編號一定一一對應,名字各自隨便修改(依照C語言命名規范),函數里面的內容就是中斷后執行的程序。
實驗現象
分別按下兩個按鈕,可以觀察到LED燈向左/右接力閃爍,證明實驗成功。
另外:
剩下兩天基礎課程的學習難度將會提升,定時器/計數器中斷以及串口中斷的學習,將要比今天的課程難度提升不少
不過,穩扎穩打,多做實驗,你會發現也沒有什么大不了。加油!
總結
以上是生活随笔為你收集整理的单片机定时器实验两位倒计时秒表_51单片机基础与应用8天速成(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python怎么画图片 wafer ma
- 下一篇: JAVA入门级教学之(方法重写/方法重载