今天收到同学们的支持和鼓励,大Z在此谢谢大家了。做这个帖子的初衷,就是为了给各位努力的同学们提供一个交流问题,分享问题,解决问题的平台。希望或多或少能够对大家有所帮助。曾子曰:大家好,才是真的好嘛!
今天的题目,主要是练习如何操作单片机的外部中断。曾子又曰:学单片机不学中断的话,就跟不会单片机没什么两样。
可见中断在单片机学习体系中的地位有多么的重要。每年从蓝桥杯的竞赛题目来看,如果不会用中断,那么你基本上是没法完整的实现题目当中所要求的各项内容的。因此呢~中断也是必考点,当然也是必须要进行练习的要点之一。
那么如何使用中断解题,如何形成使用中断的编程思维,就显得尤为重要。下面咱们就来先针对练习题,把相关代码发给大家,请大家自行查看哈。本节的练习题要求如下。
题1、在数码管上显示字符8,按下外部按键中断0(S5)则8左移动,按下外部按键中断1(S4)则8右移动
题2、数码管初始显示0,按下外部按键中断0(S5),数值加1,按下外部按键中断1(S4),数值减1
下面仍照惯例给出两个题目的代码,并在文末给出所有代码压缩包的下载链接,想要源代码怎么操作,曾子曰:你懂的~
学习中如有任何问题,请大家在下方回帖告知~回帖有好礼,不要白不要呀~哈哈~~
-----------------------蓝桥板代码---------------------
蓝桥板题1代码:
/******************************************************************************************
1、在数码管上显示字符8,按下外部按键中断0(S5)则8右移动,按下外部按键中断1(S4)则8左移动
******************************************************************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code smgwei[]={0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80,0X01};
uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0XFF};
uchar s4,s5;
void init();//蓝桥杯板初始化程序
void keyScan();//键盘扫描
void int0Init();//外部中断0与1的初始化函数
void delayms(uint z);//ms级延时函数
/**************************主函数*****************************/
/*void main()
{
uchar i;
int0Init();
init();
while(1)
{
if(s4==1) //左移动
{
uchar i=8;
s4=0;
do
{
P2=0xc0;
P0=smgwei[i]; //位值
P2=0xff;
P0=0x80; //段值8
delayms(500);
}while(i--);
}
else if(s5==1) //右移动
{
s5=0;
for(i=0;i<8;i++)
{
P2=0xc0;
P0=smgwei[i]; //位值
P2=0xff;
P0=0x80; //段值8
delayms(500);
} break;
}
keyScan();
}
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=845;y>0;y--);
}
void init()
{
P2=0xa0;
P0=0x00; //关闭继电器蜂鸣器
P2=0x80;
P0=0xff; //关闭led灯
P2=0xc0;
P0=0xff; //选择所有数码管
P2=0xff;
P0=0xff; //关闭所有数码管
}
void int0Init()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
IT1=1;//设置INT1
EX1=1;//打开INT1的中断允许。
EA=1;//打开总中断
}
void int0()interrupt 0
{
EX0=0;
s5=~s5;
EX0=1;
}
void int1()interrupt 1
{
EX0=0;
s4=~s4;
EX0=1;
}
void keyScan()
{
if(P32==0) //s5
{
delayms(5);
if(P32==0)
{
s5=1; //s5的标志位
}
while(!P32);
}
else if(P33==0) //s4
{
delayms(5);
if(P33==0)
{
s4=1; //s4的标志位
}
while(!P33);
}
}蓝桥板题2代码:
/************************************************************************************
2、数码管初始显示0,按下外部按键中断0(S5),数值加1,按下外部按键中断1(S4),数值减1。
*************************************************************************************/
#include<stc15f2k60s2.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
uchar code smgtab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar tt;
uchar s4,s5,num;
uchar yi,er,san,si,wu,liu,qi,ba;
void init();//蓝桥杯板初始化程序
void keyScan();//键盘扫描
void int0Init();//外部中断0与1的初始化程序
void delayms(uint z);//ms级延时函数
void displayOne(uchar yi,uchar er);//第一 二个数码管显示函数
void displayTwo(uchar san,uchar si);//第三 四个数码管显示函数
void displayThree(uchar wu,uchar liu);//第五 六个数码管显示函数
void displayFour(uchar qi,uchar ba);//第七 八个数码管显示函数
void main()
{
init();
int0Init();
while(1)
{
yi=11;er=11;san=11;si=11;wu=11;liu=num/100;qi=num/10%10;ba=num%10;
if(s5==1) //外部中断加1
{
s5=0;
if(num>=0&&num<255) num=num+1;
else if(num==255){num=255;}
}
else if(s4==1) //外部中断减1
{
s4=0;
if(num>0&&num<=255) num=num-1;
else if(num==0){num=0;}
}
keyScan();
displayOne(yi,er);
displayTwo(san,si);
displayThree(wu,liu);
displayFour(qi,ba);
}
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=845;y>0;y--);
}
void init()
{
P2=0xa0;
P0=0x00; //关闭继电器蜂鸣器
P2=0x80;
P0=0xff; //关闭led灯
P2=0xc0;
P0=0xff; //选择所有数码管
P2=0xff;
P0=0xff; //关闭所有数码管
}
void keyScan()
{
if(P32==0) //s5
{
delayms(5);
if(P32==0)
{
s5=1; //按键s5的标志位
}
while(!P32);
}
else if(P33==0) //s4
{
delayms(5);
if(P33==0)
{
s4=1; //按键s4的标志位
}
while(!P33);
}
}
void int0Init()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
IT1=1;//设置INT1
EX1=1;//打开INT1的中断允许。
EA=1;//打开总中断
}
void int0()interrupt 0
{
EX0=0;
s5=~s5;
EX0=1;
}
void int1()interrupt 1
{
EX0=0;
s4=~s4;
EX0=1;
}
void displayOne(uchar yi,uchar er)
{
P2=0xc0;
P0=0x01; //选通第一个数码管
P2=0xff;
P0=smgtab[yi];//位选
delayms(1);
P2=0xc0;
P0=0x02; //选通第二个数码管
P2=0xff;
P0=smgtab[er];//位选
delayms(1);
}
void displayTwo(uchar san,uchar si)
{
P2=0xc0;
P0=0x04; //选通第三个数码管
P2=0xff;
P0=smgtab[san];//位选
delayms(1);
P2=0xc0;
P0=0x08; //选通第四个数码管
P2=0xff;
P0=smgtab[si];//位选
delayms(1);
}
void displayThree(uchar wu,uchar liu)
{
P2=0xc0;
P0=0x10; //选通第五个数码管
P2=0xff;
P0=smgtab[wu];//位选
delayms(1);
P2=0xc0;
P0=0x20; //选通第六个数码管
P2=0xff;
P0=smgtab[liu];//位选
delayms(1);
}
void displayFour(uchar qi,uchar ba)
{
P2=0xc0;
P0=0x40; //选通第七个数码管
P2=0xff;
P0=smgtab[qi];//位选
delayms(1);
P2=0xc0;
P0=0x80; //选通第八个数码管
P2=0xff;
P0=smgtab[ba];//位选
delayms(1);
}-----------------------小红板代码----------------------
小红板题1代码:
/************************************************************************************
1、在数码管上显示字符8,按下外部按键中断0(S5)则8左移动,按下外部按键中断1(S10)则8右移动
*************************************************************************************/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit s5=P3^0;
sbit s10=P3^1;
sbit P_HC595_SER = P2^7; //pin 14 SER data input
sbit P_HC595_RCLK = P2^5; //pin 12 RCLk store (latch) clock
sbit P_HC595_SRCLK = P2^6; //pin 11 SRCLK Shift data clock
uchar code smgwei[]={0X00,0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
uchar i;
uchar ss5,ss10;
uchar yi,er,san,si,wu,liu,qi,ba;
void keyscan();//键盘扫描
void smg_Init();//数码管初始化
void int0Init();//外部中断0与1初始化
void delayms(uint z);//ms级延时函数
void Send_595(unsigned char dat);
/****************主函数***********************/
/*void main()
{
smg_Init();
int0Init();
while(1)
{
if(ss5==1)
{
ss5=0;
for(i=8;i>0;i--) //左移
{
Send_595(smgwei[i]); //位选
Send_595(0x7f); // 段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1000);
}break;
}
else if(ss10==1)
{
ss10=0;
for(i=0;i<8;i++) //右移
{
Send_595(smgwei[i]);
Send_595(0x7f);
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1000);
}break;
}
keyscan();
}
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(s5==0) //s5
{
delayms(5);
if(s5==0)
{
ss5=1; //s5的标志位
}
while(!s5);
}
else if(s10==0) //s10
{
delayms(5);
if(s10==0)
{
ss10=1; //s10的标志位
}
while(!s10);
}
}
void smg_Init()
{
Send_595(0x00); //同时选择8个数码管
Send_595(0x00); //让8个数码管同时显示消隐字符
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void int0Init()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
IT1=1;//设置INT1
EX1=1;//打开INT1的中断允许。
EA=1;//打开总中断
}
void int0()interrupt 0
{
EX0=0;
ss5=~ss5;
EX0=1;
}
void int1()interrupt 1
{
EX0=0;
ss10=~ss10;
EX0=1;
}
void Send_595(unsigned char dat) //发送一个字节
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x80) //判断dat的最高位是否为1
P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1
else
P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0
P_HC595_SRCLK = 0;
P_HC595_SRCLK = 1;
P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
dat = dat << 1; //将dat左移一位,取次高位
}
}小红板题2代码:
/*************************************************************************************
2、数码管初始显示0,按下外部按键中断0(S5),数值加1,按下外部按键中断1(S4),数值减1。
**************************************************************************************/
#include"reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit P_HC595_SER = P2^7; //pin 14 SER data input
sbit P_HC595_RCLK = P2^5; //pin 12 RCLk store (latch) clock
sbit P_HC595_SRCLK = P2^6; //pin 11 SRCLK Shift data clock
sbit s5=P3^0;
sbit s10=P3^1;
sbit s15=P3^2;
sbit s20=P3^3;
uchar code smgtab[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X40,0X00};
uchar ss5,ss10,num;
uchar yi,er,san,si,wu,liu,qi,ba;
void keyscan();
void smg_Init();//数码管初始化函数
void int0Init();//外部中断0与1的初始化函数
void delayms(uint z);//ms级延时函数
void Send_595(unsigned char dat);
void displayOne(uchar yi,uchar er);//第一 二个数码管显示函数
void displayTwo(uchar san,uchar si);//第三 四个数码管显示函数
void displayThree(uchar wu,uchar liu);//第五 六个数码管显示函数
void displayFour(uchar qi,uchar ba);//第七 八个数码管显示函数
/**********************主函数*****************************/
void main()
{
smg_Init();
int0Init();
while(1)
{
yi=11;er=11;san=11;si=11;wu=11;liu=num/100;qi=num/10%10;ba=num%10;
if(ss5==1) //外部中断加1
{
ss5=0;
if(num>=0&&num<255) num=num+1;
else if(num==255){num=255;}
}
else if(ss10==1) //外部中断减1
{
ss10=0;
if(num>0&&num<=255) num=num-1;
else if(num==0){num=0;}
}
keyscan();
displayOne(yi,er);
displayTwo(san,si);
displayThree(wu,liu);
displayFour(qi,ba);
}
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void keyscan()
{
if(s5==0) //s5
{
delayms(5);
if(s5==0)
{
ss5=1; //按键s5的标志位
}
while(!s5);
}
else if(s10==0) //s10
{
delayms(5);
if(s10==0)
{
ss10=1; //按键s10的标志位
}
while(!s10);
}
}
void int0Init()
{
//设置INT0
IT0=1;//跳变沿出发方式(下降沿)
EX0=1;//打开INT0的中断允许。
IT1=1;//设置INT1
EX1=1;//打开INT1的中断允许。
EA=1;//打开总中断
}
void int0()interrupt 0
{
EX0=0;
ss5=~ss5;
EX0=1;
}
void int1()interrupt 1
{
EX0=0;
ss10=~ss10;
EX0=1;
}
void smg_Init()
{
Send_595(0x00); //同时选择8个数码管
Send_595(0x00); //让8个数码管同时显示消隐字符
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
}
void Send_595(unsigned char dat) //发送一个字节
{
unsigned char i;
for(i=0; i<8; i++)
{
if(dat & 0x80) //判断dat的最高位是否为1
P_HC595_SER = 1; //最高位如果为1,则令P2.7 = 1
else
P_HC595_SER = 0; //最高位如果为0,则令P2.7 = 0
P_HC595_SRCLK = 0;
P_HC595_SRCLK = 1;
P_HC595_SRCLK = 0; //使用P2.6制造一个上升沿将这一位数据送到74HC595的QA输出端
dat = dat << 1; //将dat左移一位,取次高位
}
}
void displayOne(uchar yi,uchar er)
{
Send_595(0xfe); //选通第一个数码管
Send_595(smgtab[yi]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xfd); //选通第二个数码管
Send_595(smgtab[er]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayTwo(uchar san,uchar si)
{
Send_595(0xfb); //选通第三个数码管
Send_595(smgtab[san]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xf7); //选通第四个数码管
Send_595(smgtab[si]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayThree(uchar wu,uchar liu)
{
Send_595(0xef); //选通第五个数码管
Send_595(smgtab[wu]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0xdf); //选通第六个数码管
Send_595(smgtab[liu]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}
void displayFour(uchar qi,uchar ba)
{
Send_595(0xbf); //选通第七个数码管
Send_595(smgtab[qi]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
Send_595(0x7f); //选通第八个数码管
Send_595(smgtab[ba]);//段选
P_HC595_RCLK = 0;
P_HC595_RCLK = 1; //使用P2.5制造一个上升沿将这两个字节数据同时送给数码管,完成段选和位选
delayms(1);
}----------------所有代码打包下载链接------------------
大家可以继续提前接着往下进行 07. 单片机定时计数器的使用 的题目练习~如对代码有任何问题,请粗暴的指出来告诉我哦~
曾子最后曰:忍不住想夸大家一句,同学们奋斗的样子真美丽~
真是让老师辛苦了。)
我要赚赏金
