前言
该笔记记录了4月11日上午在粤嵌兴趣课中学习的内容。本次兴趣课我的设备环境如下:
硬件方面
单片机:C51
CPU:AT89C52
软件方面
IDE:Keil uVision4
烧写软件:stc-isp-15xx-v6.85H.exe
驱动:ch341ser
(适用于win10操作系统)
实验部分
1、C51单片机实现蜂鸣器实验
2、实现运行流水灯的同时可通过独立按键改变蜂鸣器状态
附:一个更好的实验2的代码(链接)
课堂笔记部分
1、轮询
2、中断
3、C51单片机的中断源以及中断的使用
正文
实验部分
1、C51单片机实现蜂鸣器实验
大家经过计算机或者电子的学生实验室,可能会经常听到一些刺耳的声响,这一般是实验室里的同学做单片机实验时弄响了单片机上的蜂鸣器。
打开C51单片机引脚图,找到蜂鸣器以及蜂鸣器对应的引脚
如图,蜂鸣器引脚(FM)与CPU上的P07号引脚相连接,同时也可看出输入0时蜂鸣器才会运行发声,因此可按照点亮LED的方法编写程序
#include<reg52.h>
#include<intrins.h>
#define bara unsigned int
sfr p1= 0x90;
sbit bee = P0^7;
int main()
{
while(1)
{
bee = 0;
}
}
之后再烧写到单片机上。
编写程序时引脚设置错误:这么小声(没声音)还想当蜂鸣器!?设置正确:你吼辣么大声干什么啦!!
2、实现运行流水灯的同时可通过独立按键改变蜂鸣器状态
这可能是开课以来我遇到的最难的实验,一个上午几乎都耗在了这个实验上。但是我完成了这个实验,才感觉自己入了C51单片机的门 (很有可能在不久后还会入一次C51的门) (一种知识的入门可以有无数次)
设置需要用到的引脚()
根据上节课的知识点,要想让流水灯运行的同时,还能实现按键改变蜂鸣器状态,需要:在检测到按键按下时,让单片机短暂的暂停流水灯,将蜂鸣器状态改变后再继续运行流水灯。暂停流水灯的时间必须要足够短,以至于无法察觉。
中断:你直接点我名算了
很明显需要设定一个中断,使按键电平变化的时候改变蜂鸣器的电平,因此该中断是外部中断。
先设置中断操作函数:
void int0()interrupt 2//外部中断,且要生成高电平
{ //高电平的原因:LED遇到高电平停止工作
sleep(1000); //先延时,和按键控制一样,需要一定时间进行判断
if(bee==1) {//若蜂鸣器为高电平,则改为低电平
bee=0;
}
else{bee=1;}//若蜂鸣器为低电平,则改为高电平
}
然后在主函数中将IE寄存器(控制外部中断)初始化,并设置为下沿方式触发
EA = 1;
EX1 = 1;
IT1 = 1;//下沿触发
bee = 1;
完整代码如下:
#include<reg52.h>
#include<intrins.h>
#define bara unsigned int
sfr p1= 0x90;
sbit key = P3^7;
sbit led1 = p1^0;
sbit led2 = p1^1;
sbit led3 = p1^2;
sbit led4 = p1^3;
sbit led5 = p1^4;
sbit led6 = p1^5;
sbit led7 = p1^6;
sbit led8 = p1^7;
sbit bee = P0^7;
void sleep(bara n)
{
bara i;
for(i=0;i<n;i++){
}
}
void light_water()
{
led1=0;
sleep(5000);
led1=1;
led2=0;
sleep(5000);
led2=1;
led3=0;
sleep(5000);
led3=1;
led4=0;
sleep(5000);
led4=1;
led5=0;
sleep(5000);
led5=1;
led6=0;
sleep(5000);
led6=1;
led7=0;
sleep(5000);
led7=1;
led8=0;
sleep(5000);
led8=1;
led7=0;
sleep(5000);
led7=1;
led6=0;
sleep(5000);
led6=1;
led5=0;
sleep(5000);
led5=1;
led4=0;
sleep(5000);
led4=1;
led3=0;
sleep(5000);
led3=1;
led2=0;
sleep(5000);
led2=1;
led1=0;
sleep(5000);
led1=1;
}
void int1() interrupt 2
{
sleep(1000);
if(bee==1) {
bee=0;
}
else{bee=1;}
}
int main()
{
EA = 1;
EX1 = 1;
IT1 = 1;//下沿触发
bee = 1;
while(1)
{
light_water();//流水灯
}
return 0;
}
将程序烧写到单片机上,按下电源键,流水灯开始运行;当按下key1时即可触发中断,让程序暂时放下流水灯,将蜂鸣器的电平置反后继续运行流水灯,由于中断使劲啊极短,因此看起来流水灯并无停顿
我这个代码看起来比较玄学。。。整篇代码没提到过独立按键的变量,却能用独立按键引发中断。。。
因为是模仿他,所以我们博客的标题特别雷同
课程笔记部分
在我的上一篇博客中,我记录了关于对中断的大致定义以及中断编号、中断优先级的认识,本次课程连接上次。
1、中断的使能开关
中断的使能开关位于IE寄存器处,其各引脚以及功能如下表所示
被定义的变量名 | 对应引脚 | 功能介绍 |
---|---|---|
(sbit)EA | IE^7 | 中断总开关 |
(sbit)ET2 | IE^5 | |
(sbit)ES | IE^4 | 串口中断开关 |
(sbit)ET1 | IE^3 | 定时器中断开关(1) |
(sbit)EX1 | IE^2 | 外部中断开关(1) |
(sbit)ET0 | IE^1 | 定时器中断开关(0) |
(sbit)EX0 | IE^0 | 外部中断开关(0) |
2、外部中断的触发方式以及配置代码
外部中断有两种触发方式:低电平触发
与下降沿触发
。
两种触发方式区别:
一、触发条件不同
1、低电平触发
:外部中断低电平触发是检测到引脚为低电平就触发,从而进入中断函数中处理这个中断。
2、下降沿触发
:下降沿触发是检测到信号有下降沿时的开关动作就触发,从而进入中断函数中处理这个中断。
二、触发次数不同
1、低电平触发
:外部中断低电平触发只要引脚为低电平时间内中断一直有效,那么就会一直进入中断,直到电平变化为高电平。
2、下降沿触发
:下降沿触发中断只会触发一次,只有在下次电平发生变化时才会重新触发中断。
在程序运行时对ITx(x=1或0)变量赋值,可以控制外部中断的触发方式:若为0则是低电平触发,为1则是下降沿触发;
x的取值表示第几号IE寄存器,因为IE寄存器有0号和1号两个,每次程序运行时只能调用其中一个,因此要注意。
常见的设置IE寄存器函数编写如下:
void config()
{
IT1 = 0;//1号IE寄存器设置为低电平触发
EA = 1;//打开中断总开关
EX1 = 1;//打开外部中断1开关
}