目录
一、中断系统
二、外部中断
一)配置外部中断的三个步骤
1)中断允许
(2)中断方式配置
3)中断处理函数
二)实验代码
三、定时器/计数器
一)使用定时器/计数器的三个步骤
1)启动定时/计数器
2)设置工作模式编辑
3)查询定时/计数器是否溢出
二)实验代码
1)定时器
2)计数器
四、定时器/计数器中断
一)执行定时器/计数器中断的四个步骤
1.中断允许
2.启动定时、计数器
3.设置工作模式
4.中断处理函数
二)实验代码
一、中断系统
中断反映计算机处理紧急事件的能力,分为四个步骤:中断请求、中断响应、中断处理、中断返回。
51单片机允许5个中断源:2个外部中断INT0、INT1,3个内部中断:2个定时/计数器中断T0、T1,串口中断TI/RI。
它们的优先级:INT0(H)中断入口:0
T0 1
INT1 2
T1 3
TI/RI (L) 4
二、外部中断
一)配置外部中断的三个步骤
1)中断允许
如果想执行中断,需要将总中断开关闭合,以及各自中断开关闭合 。
可位寻址的意思就是可以直接写EA=1;而不用读二进制。
如果想打开外部中断1
EA=1; EX1=1;
(2)中断方式配置
IE1和IE0是由硬件自动置1置0的,我们不用管。
如果想用下降沿触发外部中断1
IT1=1;
3)中断处理函数
void int1() interrupt 2{
}
二)实验代码
将P3^2与P3^7用杜邦线相连,按一次独立按键S2,先给P3^7一个高电平,再给一个低电平,实现下降沿触发,用P1的翻转体现中断执行。
#include <reg52.h>
sbit key=P3^0;
sbit flag=P3^7;
#define uint unsigned int
void delay(uint z){
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void int0init(){
EA=1;
EX0=1;
IT0=1;
}
void int0() interrupt 0{
P1=~P1;
}
void main(){
int0init();
while(1){
if(key==0){
delay(20);
if(key==0){
flag=1;
flag=0;
while(!key);
}
}
}
}
三、定时器/计数器
一)使用定时器/计数器的三个步骤
1)启动定时/计数器
想让定时器T0运行
TR0=1;
TF0是判断是否溢出,if(TF0==1) 完成从初值加到65536的过程。
软件查询方法 可以直接TF0=0;
2)设置工作模式
不可位寻址,就是不可以直接写GATE=1;而要读二进制
如果要执行16位计数器1
1)GATE位置0; 如果置1还需要INT1为高电平才能执行
2)C/T位置1;
3)工作模式1
TMOD=01010000=0x50;
TL0和TH0怎么计算
如果是定时器50ms
单片机工作频率11.0592MHz,时钟周期1/11.0592/1000000*1000000=0.0904us
机器周期0.0904*12=1.085us
50ms=50000us
50000/1.085=46082
65535-46082=19453
TH0=0XFD;
TL0=0X4B;
如果是计数器
TH0=0;
TL0=0;
3)查询定时/计数器是否溢出
if(TF1==1){
TF1=0;
}
二)实验代码
1)定时器
T0做定时器,数码管显示从0-10,间隔时间1s。
#include <reg52.h>
sbit DU=P2^6;
sbit WE=P2^7;
#define uchar unsigned char
#define uint unsigned int
uchar board[]={0x3f,/*00111111*/0x06,/*00000110*/0x5b,/*01011011*/
0x4f,/*01001111*/0x66,/*01100110*/0x6d,/*01101101*/0x7d,/*01111101*/0x07,/*00000111*/
0x7f,0x6f/*01101111*/};
void delay(uint z){
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void display(uchar z){
uchar bai=z/100;
uchar shi=z%100/10;
uchar ge=z%10;
P0=0xff;
WE=1;
P0=0xfe;
WE=0;
DU=1;
P0=board[bai];
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0xfd;
WE=0;
DU=1;
P0=board[shi];
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0xfb;
WE=0;
DU=1;
P0=board[ge];
DU=0;
delay(5);
}
void timer0Init(){
TR0=1;
TMOD=0x01;
TH0=(65535-46082)/256;
TL0=(65535-46082)%256;
}
void main(){
uchar msec=0,sec=0;
timer0Init();
while(1){
if(TF0==1){
TF0=0;
TH0=(65535-46082)/256;
TL0=(65535-46082)%256;
msec++;
if(msec==20){
msec=0;
sec++;
if(sec>10)
sec=0;
}}
display(sec);}}
2)计数器
T0做定时器,T1做计数器,1sLED1翻转一次,数码管显示LED1翻转次数。
#include <reg52.h>
sbit DU=P2^6;
sbit WE=P2^7;
sbit LED1=P1^0;
#define uchar unsigned char
#define uint unsigned int
uchar board[]={0x3f,/*00111111*/0x06,/*00000110*/0x5b,/*01011011*/
0x4f,/*01001111*/0x66,/*01100110*/0x6d,/*01101101*/0x7d,/*01111101*/0x07,/*00000111*/
0x7f,0x6f/*01101111*/};
void delay(uint z){
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void display(uchar z){
uchar bai=z/100;
uchar shi=z%100/10;
uchar ge=z%10;
P0=0xff;
WE=1;
P0=0xfe;
WE=0;
DU=1;
P0=board[bai];
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0xfd;
WE=0;
DU=1;
P0=board[shi];
DU=0;
delay(5);
P0=0xff;
WE=1;
P0=0xfb;
WE=0;
DU=1;
P0=board[ge];
DU=0;
delay(5);
}
void timer0Init(){
TR0=1;
TMOD=0x51;
TH0=(65535-46082)/256;
TL0=(65535-46082)%256;
}
void timer1Init(){
TR1=1;
TMOD=0x51;
TH1=0;
TL1=0;
}
void main(){
uchar msec=0;
timer0Init();
timer1Init();
while(1){
if(TF0==1){
TF0=0;
TH0=(65535-46082)/256;
TL0=(65535-46082)%256;
msec++;
if(msec==20){
msec=0;
LED1=~LED1;
}}
display(TL1);}}
四、定时器/计数器中断
一)执行定时器/计数器中断的四个步骤
1.中断允许
2.启动定时、计数器
TF0、TF1软件查询时软件清零,中断时硬件清零。
3.设置工作模式
4.中断处理函数
void timer0() interrupt 1{
}
void timer1() interrupt 3{
}
二)实验代码
功能: 数码管动态扫描在独立按键不松手时不能及时扫描,我们可以利用中断解决这一问题。
用定时器中断代替延时函数调用,S2一直加到100,S3一直减到0文章来源:https://www.toymoban.com/news/detail-473215.html
#include<reg52.h>
sbit WE=P2^7;
sbit DU=P2^6;
sbit S2=P3^0;
sbit S3=P3^1;
#define uchar unsigned char
#define uint unsigned int
uchar SMGduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar SMGwei[]={0xfe,0xfd,0xfb};
uchar num;
void delay(uint z){
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
void timer0Init(){
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0Xed;
TL0=0Xff;
}
void display(uchar z){
static uchar wei;
P0=0xff;
WE=1;
P0=SMGwei[wei];
WE=0;
switch(wei){
case 0:DU=1;P0=SMGduan[z/100];DU=0;break;
case 1:DU=1;P0=SMGduan[z%100/10];DU=0;break;
case 2:DU=1;P0=SMGduan[z%10];DU=0;break;
}
wei++;
if(wei==3)
wei=0;
}
void main(){
timer0Init();
while(1){
if(S2==0){
delay(20);
if(S2==0){
if(num<100)num++;
while(!S2);
}
}
if(S3==0){
delay(20);
if(S3==0){if(num>0)num--;
while(!S3);
}
}
}}
void timer0() interrupt 1{
TH0=0Xed;
TL0=0Xff;
display(num);}
以上就是我今天的分享,希望对你有所帮助!!!如果觉得这篇文章还不错的话,可以点个赞再走哟~文章来源地址https://www.toymoban.com/news/detail-473215.html
到了这里,关于【STC89C52】外部中断与定时/计数器中断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!