/*此實際旨在同時使用定時器中斷和二個外部中斷。
實驗意圖:開機后,五位數碼管顯示當前八支二極管燈延時切換的數據100.
外部中斷按鈕可以對延時數據進行加和減,由五位數碼管顯示出來(用六位代替)。
實驗電路:
P0口通過74373接8位共陰LED燈;P2口通過74245接至五位共陰數碼管段顯端;
P1.0-P1.2接至74138地址端; 74138的低五位輸出接五位數碼管的位控端,控制其陽極電源;
中斷口:P3.2和P3.3分別接至一開關(按下時提供下降脈沖),給中斷口下降觸發信號。
結果:實驗結果按照設想的達到目的了,但是是在中斷發生時,數碼管會抖動。估計需要把數碼管數據磅鎖存器才有效果。比如74373IC。
*/
#include<reg52.h> //本程序接8位共陰數碼管在P0口實驗燈閃電路
#include<intrins.h>
sbit A0=P1^0; //138地址端及使能端
sbit A1=P1^1;
sbit A2=P1^2;
sbit EN_138=P1^3;
sbit EN_373=P1^4; //373使能端1腳,為0時使能,為1時輸出高阻
sbit GEN_373=P1^5; //373鎖存端11腳。當其由高轉低時,輸出端鎖存,當其由低為高時,輸出等于輸入
unsigned int jx_hj=500; //延時指針
unsigned int cnt1=0; //定時器計時指針
unsigned char led=0x01; //Led燈的初始數據
static unsigned char led_skip=0; //Led移位指針
unsigned char code Ledchar[]= //用數組來存貯共陽數碼管0-9的真值
{0xC0,0xF9,0xa4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
volatile void delay(unsigned char chj) //100us帶參數的延時函數
{
unsigned char mhj;
for(mhj=1;mhj<chj;mhj++)
{
unsigned char a,b,c;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
}
void main()
{
unsigned char j;
EA=1; //中斷總開關
//設立外部中斷:
EX0=1; //外部中斷INT0使能
IT0=1; //下降沿觸發 IT0=0為低電平觸發
EX1=1; //外部中斷INT1使能
IT1=1; //下降沿觸發 IT1=0為低電平觸發
//設置T0中斷及初值:
TMOD=0x01; //設置T0為模式1
TH0 = 0x0FF;
TL0 = 0x0CE;
ET0=1; //使能T0中斷
TR0=1; //啟動T0
while(1)
{
P0=~(led<<led_skip);
for(j=0;j<5;j++)
{
EN_138=0; //關閉138使能
EN_373=0; //373輸出高阻,起消隱作用
GEN_373=1; //373鎖存數據;
delay(2); //該延時長短帶著消隱的效果,太短,消隱效果不好,太長,數碼管可能會閃爍
switch(j)
{
case 0: A2=0;A1=0;A0=0;P2=Ledchar[jx_hj%10];break;
case 1: A2=0;A1=0;A0=1;P2=Ledchar[jx_hj/10%10];break;
case 2: A2=0;A1=1;A0=0;P2=Ledchar[jx_hj/100%10];break;
case 3: A2=0;A1=1;A0=1;P2=Ledchar[jx_hj/1000%10];break;
case 4: A2=1;A1=0;A0=0;P2=Ledchar[jx_hj/10000%10];break;
default:break;
}
EN_138=1;
}
}
}
void interruptTimer0() interrupt 1 //定時器0中斷服務函數
{
TH0 = 0x0FF;
TL0 = 0x0CE;
cnt1++; //中斷次數計數值加1
if(cnt1>=jx_hj) //中斷100次即0.1S
{
cnt1=0; //清零計數值以重新計時
if(led_skip<7) led_skip++;
else led_skip=0;
}
}
/*INT0中斷函數 */
void counter0(void) interrupt 0
{
EX0=0; //關閉中斷
delay(3);
if(jx_hj<60000) jx_hj+=50; //不曉得什么原因,實際數字總是加2位這個數,即加100.結果證明是中斷開關的總是。
//GEN_373=0; //373鎖存打開,輸出等于輸入,以更新數據;
EX0=1; //兩次打開中斷使能
}
/*INT1中斷函數 */
void counter1(void) interrupt 2
{
EX1=0;
delay(3);
if(jx_hj>100) jx_hj-=50; //同上一樣,總是減100.
//GEN_373=0;
EX1=1;
}
/***************************************/
|