本文是關(guān)于51單片機(jī)中斷系統(tǒng)的擴(kuò)展實驗啥酱。
一粒梦、 擴(kuò)展實驗一:使用外部中斷0控制蜂鳴器存崖,外部中斷1控制直流電機(jī)
外部中斷擴(kuò)展實驗一實現(xiàn)的功能:使用外部中斷0控制蜂鳴器發(fā)聲/不發(fā)聲,外部中斷1控制直流電機(jī)轉(zhuǎn)動/停止济丘。
由蜂鳴器的內(nèi)容可以知道,蜂鳴器分為有源蜂鳴器和無源蜂鳴器洽蛀;蜂鳴器有兩個管腳摹迷,要使蜂鳴器發(fā)聲,需要有電流通過蜂鳴器郊供,即管腳一端接正極峡碉,管腳另一端接負(fù)極。有源蜂鳴器只需給一定的電壓即可發(fā)聲驮审,無源蜂鳴器需要一定頻率的脈沖才可發(fā)聲鲫寄。這里設(shè)計了兩種蜂鳴器吉执,都由外部中斷0控制。
直流電機(jī)的驅(qū)動方式與蜂鳴器類似地来。
proteus中硬件設(shè)計如下戳玫,為顯示蜂鳴器的發(fā)聲,這里使用了一個LED顯示發(fā)聲與否未斑。蜂鳴器的一端連接到電源咕宿,另一端經(jīng)過ULN2003芯片連接P1.5口,當(dāng)P1.5=0時蜂鳴器發(fā)聲颂碧;直流電機(jī)的一端連接到電源荠列,另一端經(jīng)過ULN2003連接到P1.0口,當(dāng)P1.0=0時電機(jī)轉(zhuǎn)動载城。為體現(xiàn)中斷肌似,使用獨立按鍵模塊連接到P3.2和P3.3口,當(dāng)按鍵按下诉瓦,蜂鳴器發(fā)聲或電機(jī)轉(zhuǎn)動川队。
軟件設(shè)計如下:
/*
實現(xiàn)功能:外部中斷0控制蜂鳴器發(fā)聲,外部中斷1控制直流電機(jī)轉(zhuǎn)動
- 與外部中斷0和外部中斷1有關(guān)的有兩個寄存器IE和TCON睬澡,
- IE是中斷允許控制寄存器固额,TCON是中斷請求標(biāo)志寄存器。
- IE中包括了
- 總中斷允許位(EA)
- 外部中斷0/1允許位(EX0/EX1)
- 定時器0/1允許位(ET0/ET1)
- 串口中斷允許位(ES);
- TCON中的低四位是外部中斷允許和觸發(fā)方式控制位煞聪,包括了
- IT0/IT1是外部中斷0/1觸發(fā)方式控制位斗躏,0表示低電平觸發(fā),1表示下降沿觸發(fā)昔脯;
- IE0/IE1是外部中斷0/1請求標(biāo)志位
[2023-12-19] zoya
*/
#include "reg52.h"
#include "typedef.h"
#include "Delay.h"
sbit BEEP = P1^5;
sbit MOTOR = P1^0;
sbit CTR_INT0 = P3^2;
sbit CTR_INT1 = P3^3;
/*************************************************************************
* 函數(shù)名: IntInit
* 函數(shù)功能: 外部中斷0/1初始化啄糙,設(shè)置中斷觸發(fā)方式為邊沿觸發(fā)
* 輸入: void
* 輸出: void
**************************************************************************/
void IntInit()
{
// 1. 設(shè)置中斷觸發(fā)方式
IT0=1;
IT1=1;
// 2. 打開外部中斷0/1
EX0=1;
EX1=1;
// 3. 打開總中斷
EA=1;
}
void main()
{
MOTOR=0;
BEEP=0;
IntInit();
while(1);
}
/*************************************************************************
* 函數(shù)名: Int0
* 函數(shù)功能: 外部中斷0中斷服務(wù)函數(shù),
* 控制蜂鳴器發(fā)聲
* 輸入: void
* 輸出: void
**************************************************************************/
void Int0() interrupt 0
{
delayms(10); // 按鍵延時消抖
if(0 == CTR_INT0){
BEEP = ~BEEP;
}
}
/*************************************************************************
* 函數(shù)名: Int1
* 函數(shù)功能: 外部中斷1中斷服務(wù)函數(shù)云稚,
* 控制直流電機(jī)轉(zhuǎn)動
* 輸入: void
* 輸出: void
**************************************************************************/
void Int1() interrupt 2
{
delayms(10); // 按鍵延時消抖
if(0 == CTR_INT1)
{
MOTOR=~MOTOR;
}
}
仿真結(jié)果:
二隧饼、擴(kuò)展實驗二:修改定時器初值,設(shè)定3秒鐘的定時時間讓LED模塊閃爍
如何計算定時器初值静陈?
以使用12MHz的晶振頻率計算燕雁。如果使用的是12MHz晶振,單片機(jī)內(nèi)部的時鐘頻率為12分頻即12/12MHz=1MHz鲸拥;那么對應(yīng)的機(jī)器周期為1/1MHz=1us拐格。即使用12MHz晶振的機(jī)器周期為1us。
如果要定時1ms刑赶,需要計數(shù)1ms/1us=1000個禁荒,定時器使用方式1工作,那么初值為
= 0xFC18角撞。即初值THx=0xfc,TLx=0x18呛伴。
如果要定時1s,可以通過初值設(shè)置定時1ms谒所,當(dāng)定時結(jié)束重新賦初值热康,并設(shè)定一個全局變量累計定時1ms的次數(shù),當(dāng)該全局變量累計1000次時表示定時1s劣领。
如果要設(shè)定3s時間姐军,可以通過初值設(shè)定定時3ms,其它同定時1ms尖淘。定時3ms需要計數(shù)3ms/1us=3000奕锌,定時器使用方式1工作,初值為
= 62536 = 0xF448村生,即初值THx=0xF4,TLx=0x48惊暴。
該實驗在前面使用示例的基礎(chǔ)上更改計數(shù)初值即可實現(xiàn)定時3s實現(xiàn)LED模塊的閃爍。proteus中設(shè)計LED模塊如下趁桃,定時器模塊在單片機(jī)內(nèi)部辽话。
軟件設(shè)計如下:
/*
實現(xiàn)功能:定時器0定時3s實現(xiàn)LED模塊亮滅
- 與定時/計數(shù)器工作有關(guān)的寄存器有IE、TCON卫病、TMOD油啤、THx、TLx
- IE是中斷允許控制寄存器蟀苛,TCON是中斷請求標(biāo)志寄存器益咬,TMOD是定時/計數(shù)器工作方式寄存器
- THx和TLx是計數(shù)初值賦值寄存器。
- IE中包括了
- 總中斷允許位(EA)
- 外部中斷0/1允許位(EX0/EX1)
- 定時器0/1允許位(ET0/ET1)
- 串口中斷允許位(ES);
- TCON中的高四位用于控制定時/計數(shù)器的啟動和中斷申請帜平,包括TR0/1幽告、TF0/1
- TR0/TR1是T0/T1運(yùn)行控制位,TR0=1時開始工作罕模,TR0=0時停止工作评腺,TR1與TR0類似;
- TF0/TF1是T0/T1溢出中斷請求標(biāo)志位淑掌,溢出時由硬件自動置位蒿讥,CPU響應(yīng)中斷后由硬件自動清0
可隨時查詢該位狀態(tài),也可軟件置1或清0.
- TMOD高四位控制T1抛腕,低四位控制T0芋绸,高四位和低四位分別為有GATE、C/T担敌、M1M0
- GATE是門控位摔敛,
- GATE=0表示不受外部中斷信號影響,僅TR0/TR1控制定時/計數(shù)器工作全封,
- GATE=1表示受外部中斷信號影響马昙,即TR0/TR1+INT0控制定時/計數(shù)器工作
- C/T是定時/計數(shù)器模式選擇位桃犬,C/T=0為定時模式,C/T=1為計數(shù)模式行楞;
- M1M0是工作方式設(shè)置位攒暇,有四種方式:00 01 10 11
[2023-12-20] zoya
*/
#include "reg52.h"
#include "typedef.h"
#include "Delay.h"
#define GPIO_LED P2
/*************************************************************************
* 函數(shù)名: Timer0Init
* 函數(shù)功能: 定時器0初始化,工作方式1定時3ms子房,僅TR0啟動或停止計數(shù)
* 輸入: void
* 輸出: void
**************************************************************************/
void Timer0Init()
{
// 1. 設(shè)置工作方式1形用,僅TR0控制
TMOD |= 0x01;
// 2. 設(shè)置定時3ms的初值,0xf448
TH0 = 0xf4;
TL0 = 0x48;
// 3. 打開中斷允許位
EA = 1;
ET0 = 1;
// 4. 置位TR0证杭,開始計數(shù)
TR0 = 1;
}
void main()
{
Timer0Init();
while(1);
}
/*************************************************************************
* 函數(shù)名: Timer0
* 函數(shù)功能: 定時器0中斷服務(wù)函數(shù)田度,定時3s控制LED模塊亮滅
* 輸入: void
* 輸出: void
**************************************************************************/
void Timer0() interrupt 1
{
static u16 i;
// 重新賦初值
TH0 = 0xf4;
TL0 = 0x48;
i++;
if(1000 == i)
{
i=0;
GPIO_LED = ~GPIO_LED;
}
}
仿真結(jié)果:
三、擴(kuò)展實驗三:使用定時器1和數(shù)碼管設(shè)計一個數(shù)字時鐘
定時器的設(shè)置參考擴(kuò)展實驗二解愤。
數(shù)字時鐘采用24小時制镇饺,顯示使用“00-00-00”格式。
這里數(shù)碼管使用一個八位一體的共陰極數(shù)碼管琢歇,使用芯片74HC138控制數(shù)碼管的位選兰怠,使用芯片74HC245控制數(shù)碼管的段選;P0口控制74HC245的輸入李茫,P2.2 ~ P2.4控制74HC138的輸入揭保。proteus設(shè)計如下:
軟件設(shè)計如下:
/*
實現(xiàn)功能:定時器1和數(shù)碼管設(shè)計一個數(shù)字時鐘
- 與定時/計數(shù)器工作有關(guān)的寄存器有IE、TCON魄宏、TMOD秸侣、THx、TLx
- IE是中斷允許控制寄存器宠互,TCON是中斷請求標(biāo)志寄存器味榛,TMOD是定時/計數(shù)器工作方式寄存器
- THx和TLx是計數(shù)初值賦值寄存器。
- IE中包括了
- 總中斷允許位(EA)
- 外部中斷0/1允許位(EX0/EX1)
- 定時器0/1允許位(ET0/ET1)
- 串口中斷允許位(ES);
- TCON中的高四位用于控制定時/計數(shù)器的啟動和中斷申請予跌,包括TR0/1搏色、TF0/1
- TR0/TR1是T0/T1運(yùn)行控制位,TR0=1時開始工作券册,TR0=0時停止工作频轿,TR1與TR0類似;
- TF0/TF1是T0/T1溢出中斷請求標(biāo)志位烁焙,溢出時由硬件自動置位航邢,CPU響應(yīng)中斷后由硬件自動清0
可隨時查詢該位狀態(tài),也可軟件置1或清0.
- TMOD高四位控制T1骄蝇,低四位控制T0膳殷,高四位和低四位分別為有GATE、C/T九火、M1M0
- GATE是門控位赚窃,
- GATE=0表示不受外部中斷信號影響册招,僅TR0/TR1控制定時/計數(shù)器工作,
- GATE=1表示受外部中斷信號影響考榨,即TR0/TR1+INT0控制定時/計數(shù)器工作
- C/T是定時/計數(shù)器模式選擇位跨细,C/T=0為定時模式,C/T=1為計數(shù)模式河质;
- M1M0是工作方式設(shè)置位,有四種方式:00 01 10 11
使用一個八位一體的共陰極數(shù)碼管顯示時間震叙,74HC138芯片控制數(shù)碼管的位選掀鹅,74HC245控制數(shù)碼管的段選。
[2023-12-20] zoya
*/
#include "reg52.h"
#include "typedef.h"
#include "Delay.h"
#define GPIO_DISPLAY P0
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
// 共陰極數(shù)碼管的碼表媒楼,0-9以及:
u8 code smg[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67, 0x40};
static u16 h, m, s;
/*************************************************************************
* 函數(shù)名: Timer0Init
* 函數(shù)功能: 定時器0初始化乐尊,工作方式1定時3ms,僅TR0啟動或停止計數(shù)
* 輸入: void
* 輸出: void
**************************************************************************/
void Timer1Init()
{
// 1. 設(shè)置工作方式1划址,僅TR0控制
TMOD |= 0x10;
// 2. 設(shè)置定時1ms的初值扔嵌,0xFC18
TH1 = 0xFC;
TL1 = 0x18;
// 3. 打開中斷允許位
EA = 1;
ET1 = 1;
// 4. 置位TR1,開始計數(shù)
TR1 = 1;
}
void DigDisplay()
{
LSA=0; LSB=0; LSC=0; GPIO_DISPLAY = smg[h/10];
delayms(1);
LSA=1; LSB=0; LSC=0; GPIO_DISPLAY = smg[h%10];
delayms(1);
LSA=0; LSB=1; LSC=0; GPIO_DISPLAY = smg[10];
delayms(1);
LSA=1; LSB=1; LSC=0; GPIO_DISPLAY = smg[m/10];
delayms(1);
LSA=0; LSB=0; LSC=1; GPIO_DISPLAY = smg[m%10];
delayms(1);
LSA=1; LSB=0; LSC=1; GPIO_DISPLAY = smg[10];
delayms(1);
LSA=0; LSB=1; LSC=1; GPIO_DISPLAY = smg[s/10];
delayms(1);
LSA=1; LSB=1; LSC=1; GPIO_DISPLAY = smg[s%10];
delayms(1);
}
void main()
{
GPIO_DISPLAY = 0x00;
Timer1Init();
while(1)
{
DigDisplay();
}
}
/*************************************************************************
* 函數(shù)名: Timer1
* 函數(shù)功能: 定時器1中斷服務(wù)函數(shù)夺颤,控制數(shù)碼管顯示
* 輸入: void
* 輸出: void
**************************************************************************/
void Timer1() interrupt 3
{
static u16 j;
// 重新賦初值
TH1 = 0xFC;
TL1 = 0x18;
j++;
if(1000 == j)
{
j=0;
s++;
if(60 == s)
{
s=0; m++;
if(60 == m)
{
m=0; h++;
if(24 == h)
{
h=0;
}
}
}
}
}
仿真結(jié)果: