单片机原理及应用 实践部分 主讲人:刘 强 liuliu408@163.com 15928681548 58570305 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强 liuliu408@163.com 15928681548 58570305 1
例1: 键控灯,要求按K1键D1亮变为不亮(或不亮变为亮)。 按键信号加到外部中断0的引脚P3.2上,当S1不按下时,P3.2引脚为高电平,按下则为低电平,在按键的过程中P3.2引脚产生中断请求信号。
例1: 键控灯,要求按K1键D1亮变为不亮(或不亮变为亮)。 #include<STC15.h> void main() { P32=1; //按键对应引脚写“1”初始化! P17=1; //初始熄灭D1 IT0=1; //设定触发方式为:边沿触发 EX0=1; //允许外部中断0 EA=1; //开放总中断 while(1); //等待中断申请 } void INT0_ISR() interrupt 0 P17= ~P17;
void INT0_ISR() interrupt 0 { if(P32==0) //查询按键否? delay(20); //10ms延时去抖动 if(P32==0) //再次查询按键否? P17= ~P17; } while(P32==0); //等待按键释放 #include<stc15.h> void delay(int m) { unsigned int i,j; for (i=0; i<m; i++) for(j=0; j<200;j++) ; } void main() P32=1; //按键对应引脚初始化 P17=1; //初始熄灭D1 IT0=0; //设定触发方式为:低电平触发 EX0=1; //允许外部中断0 EA=1; //开放总中断 while(1); //等待中断申请
#include<STC15.h> void delay(int m) { unsigned int i,j; for (i=0; i<m; i++) for(j=0; j<200;j++) ; } void key_scan() if(P32==0) //查询按键否? delay(20); //10ms延时去抖动 if(P32==0) //再次查询按键否? P17= ~P17; while(P32==0); //等待按键释放 查询方式实现按键---注意对比 void main() { P32=1; //按键对应引脚初始化 P17=1; //初始化D1熄灭 while(1) key_scan(); }
例2:键控流水灯(按下K1左流水,按下K2右流水) 请考虑程序应该如何实现??
P3_2=1; //输入初始化 if (flag==2) break; void main() void left() //向左边移动 { unsigned char i; P1=0XFE; delay(200); for(i=0;i<8;i++) { P1=(P1<<1)|(P1>>(8-i-1)); if (flag==2) break; } void right() //向右边移动 { unsigned char i; P1=0X7F; P1=(P1>>1)|(P1<<(8-i-1)); if (flag==1) break; void main() P32=1; P33=1; //输入初始化 IT0=1; EX0=1; //外部中断0初始化 IT1=1; EX1=1; //外部中断1初始化 EA=1; //总中断使能 while(1) //等待中断发生 if (flag==1) left(); if (flag==2) right(); else P1=0XFF; #include<stc15.h> #define key1 P10 #define key2 P11 unsigned char flag=0; void delay (int m) unsigned int i, j; for (i=0; i<m; i++) for(j=0; j<500; j++) ; void int0_ISR() interrupt 0 if(P32 ==0) delay(20); //延时去抖动 flag=1; while(P32 ==0); void int1_ISR() interrupt 2 if(P33==0) if(P33 ==0) flag=2; while(P33 ==0); void left() //向左边移动 { unsigned char i; P0=0XFE; delay(200); for(i=0;i<8;i++) { P0=(P0<<1)|(P0>>(8-i-1)); } void right() //向右边移动 { unsigned char i; P0=0X7F; P0=(P0>>1)|(P0<<(8-i-1)); void main() P3_2=1; //输入初始化 P3_3=1; while(1) if (flag==1) left(); else if (flag==2) right(); else P0=0XFF; #include<regX51.h> unsigned char flag=0; void delay(int m) unsigned int i,j; for (i=0; i<m; i++) for(j=0; j<500;j++) ; void key_scan () if(P3_2 ==0) delay(20); //延时去抖动 flag=1; while(P3_2 ==0); if(P3_3==0) if(P3_3 ==0) flag=2; while(P3_3 ==0);
C51程序框架(含中断) #include <stc15.h> void INT0_ISR(void) interrupt 0 //外部中断0服务子程序入口 { //根据需要填入程序代码 } void main(void ) ……. // 此处可存放应用系统的初始化代码 while(1) //主程序循环 ; //根据需要填入适当的内容 中断服务与中断返回就是通过执行中断服务程序完成的。中断服务程序从中断入口地址开始执行,到返回指令“RETI”为止。 一般包括四部分内容:保护现场、中断服务、恢复现场、中断返回。 中断请求标志的撤除问题 定时器中断请求的撤除 对于定时/计数器器T0或T1溢出中断, CPU在响应中断后即由硬件自动清除其中断标志位TF0或TF1,无需采取其它措施;定时器T2、T3、T4中断的中断请求标志位被隐藏起来了,对用户是不可见的。当相应的中断服务程序执行后,这些中断请求标志位也会自动被清0; 串行口1中断请求的撤除 CPU在响应中断后,硬件不会自动清除中断请求标志位TI或RI,必须在中断服务程序中,在判别出是TI,还是RI引起的中断后,再用软件将其清除。 外部中断请求的撤除 外部中断0和外部中断1的触发方式可由ITx(x=0,1)设置,但无论ITx(x=0,1)设置为“0”还是为“1”,都属于边沿触发,CPU在响应中断后由硬件自动清除其中断请求标志位IE0或IE1,无需采取其它措施。 外部中断2、外部中断3、外部中断4的中断请求标志虽然是隐含的,但同样属于边沿出发,CPU在响应中断后由硬件自动清除其中断标志位,无需采取其它措施。 电源低电压检测中断 电源低电压检测中断的中断请求标志位,在中断响应后,不会自动清零,需要用软件清除。
中断响应是CPU对中断源中断请求的响应,包括保护断点和将程序转向中断响应后的入口地址(也称中断向量地址)。 中断响应时间问题: 1)CPU正在执行同级或高级优先级的中断。 2)正在执行RETI中断返回指令或访问与中断有关的寄存器的指令,如访问IE和IP的指令。 3)当前指令未执行完。 中断响应过程:中断响应过程包括保护断点和将程序转向中断服务程序的入口地址。CPU响应中断时,将相应的优先级状态触发器置1,然后由硬件自动产生一个长调用指令LCALL,此指令首先把断点地址压入堆栈保护,再将中断服务程序的入口地址送入到程序计数器PC,使程序转向相应的中断服务程序。
Thank You ! Question & Answer 任何建议和疑问,请不要犹豫! liuqiang@stbu.edu.cn 常用码制、 正数表示方法、 正数码制转换、 负数表示方法、 负数补码的计算 定点数表示、 浮点数表示 Question & Answer 任何建议和疑问,请不要犹豫! liuqiang@stbu.edu.cn