/*此实际旨在同时使用定时器中断和二个外部中断。
实验意图:开机后,五位数码管显示当前八支二极管灯延时切换的数据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;
}
/***************************************/
|