上一个贴子介绍了中断,下面是我利用定时器中断和外部中断写的程序,看到现象我更好的理解了中断的概念
#include<stc12c5a60s2.h>
sbit ADDR0 = P2^0;
sbit ADDR1 = P2^1;
sbit ADDR2 = P2^2;
sbit ENLED = P1^1;
unsigned char code LedChar[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
}; //共阳极数码管显示字符转换表
unsigned char LedBuff[6] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
}; //数码管显示缓冲区,初值 0xFF 确保启动时都不亮
unsigned char i = 0; //动态扫描的索引
unsigned int cnt = 0; //记录 T0 中断次数
unsigned char flag1s = 0; //1 秒定时标志
unsigned int c = 0; //定义循环变量 i,用于软件延时
unsigned char cnt1 = 0; //定义计数变量 cnt1,用于移位控制
void main()
{
unsigned long sec = 0; //记录经过的秒数
EA = 1; //使能总中断,启动。
ENLED = 0; //74CH245数码管导通
TMOD = 0x01; //设置 T0 为模式 1
TH0 = 0xC1; //为 T0 赋初值 0xC100(32mHZ,条件下12倍的标准单片机)
TL0 = 0x00; //
ET0 = 1; //使能 T0 中断 ,打开定时器中断0
TR0 = 1; //启动 T0,启动定时器0
EX0 = 1; //打开外部中断,为电平触发方式
IT0 = 0; //声明外部中断源 p3.2引脚需要低电平
while (1)
{
if (flag1s == 1) //判断 1 秒定时标志
{
flag1s = 0; //1 秒定时标志清零
sec++; //计数值自加 1
//以下代码将 sec 按十进制位从低到高依次提取并转为数码管显示字符
LedBuff[0] = LedChar[sec%10];
LedBuff[1] = LedChar[sec/10%10];
LedBuff[2] = LedChar[sec/100%10];
LedBuff[3] = LedChar[sec/1000%10];
LedBuff[4] = LedChar[sec/10000%10];
LedBuff[5] = LedChar[sec/100000%10];
}
}
}
void InterruptTimer0() interrupt 1
{
TH0 = 0xC1; //重新加载初值
TL0 = 0x00;
cnt++; //中断次数计数值加 1
if (cnt >= 200) //中断 200 次即 1 秒
{
cnt = 0; //清零计数值以重新开始下 1 秒计时
flag1s = 1; //设置 1 秒定时标志为 1
}
//以下代码完成数码管动态扫描刷新
switch(i)
{
case 0:ADDR0 =1; ADDR1 =0;ADDR2 =1;i++; P0=LedBuff[0];break;
case 1:ADDR0 =0; ADDR1 =0;ADDR2 =1;i++; P0=LedBuff[1];break;
case 2:ADDR0 =1; ADDR1 =1;ADDR2 =0;i++; P0=LedBuff[2];break;
case 3:ADDR0 =0; ADDR1 =1;ADDR2 =0;i++0=LedBuff[3];break;
case 4:ADDR0 =1; ADDR1 =0;ADDR2 =0;i++; P0=LedBuff[4];break;
case 5:ADDR0 =0; ADDR1 =0;ADDR2 =0;i=0; P0=LedBuff[5];break;
default:break;
}
}
void Interruptled() interrupt 0
{
ADDR0 =0;
ADDR1 =1;
ADDR2 =1;
P0 = ~(0x01 << cnt1); //P0 等于 1 左移 cnt1 位,控制 8 个 LED
for (c=0; c<50000; c++); //软件延时
cnt1++; //移位计数变量自加 1
if (cnt1 >= 8) //移位计数超过 7 后,再重新从 0 开始
{
cnt1 = 0;
}
手机像素太低
}
|