普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
源码
stdint.h见【51单片机快速入门指南】1:基础知识和工程创建
中断知识见【51单片机快速入门指南】3:中断系统
将外部中断0和外部中断1均配置为下降沿触发,但外部中断1的优先级最高,外部中断0的优先级最低。
EXTI.c
#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "EXTI.h"
//定义LED管脚
sbit D1 = P2^0;
sbit D2 = P2^1;
//定义独立按键控制脚
sbit K3 = P3^2;
sbit K4 = P3^3;
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}
//P3.2
void EXTI0_Callback() interrupt 0 //外部中断0中断函数
{
Delay20ms();
if(K3 == 0)
{
D1 = !D1;
while(K3 == 0);
}
}
//P3.3
void EXTI1_Callback() interrupt 2 //外部中断1中断函数
{
Delay20ms();
if(K4 == 0)
{
D2 = !D2;
while(K4 == 0);
}
}
#if USE_EXTI2_EXTI3
//P4.3
void EXTI2_Callback() interrupt 6 //外部中断2中断函数
{
}
//P4.2
void EXTI3_Callback() interrupt 7 //外部中断3中断函数
{
}
#endif
#if EXTI_USE_STC
sfr IPH = 0xb7;
#endif
void EXTI0_Init(uint8_t EXTI_Type, uint8_t Priority)
{
#if EXTI_USE_STC
IPH &= ~1;
IPH |= (2 & Priority) >> 1;
#endif
PX0 = (1 & Priority); //设置中断优先级
IT0 = EXTI_Type; //触发方式
EX0 = 1; //打开INT0的中断允许
EA = 1; //打开总中断
}
void EXTI0_Switch(uint8_t Status)
{
EX0 = Status;
}
void EXTI1_Init(uint8_t EXTI_Type, uint8_t Priority)
{
#if EXTI_USE_STC
IPH &= ~4;
IPH |= (2 & Priority) << 1;
#endif
PX1 = (1 & Priority); //设置中断优先级
IT1 = EXTI_Type; //触发方式
EX1 = 1; //打开INT1的中断允许
EA = 1; //打开总中断
}
void EXTI1_Switch(uint8_t Status)
{
EX1 = Status;
}
#if USE_EXTI2_EXTI3
sfr XICON = 0xc0;
sbit PX2 = XICON^3;
sbit EX2 = XICON^2;
sbit IE2 = XICON^1;
sbit IT2 = XICON^0;
sbit PX3 = XICON^7;
sbit EX3 = XICON^6;
sbit IE3 = XICON^5;
sbit IT3 = XICON^4;
void EXTI2_Init(uint8_t EXTI_Type, uint8_t Priority)
{
#if EXTI_USE_STC
IPH &= ~0x40;
IPH |= (2 & Priority) << 5;
#endif
PX2 = (1 & Priority); //设置中断优先级
IT2 = EXTI_Type; //触发方式
EX2 = 1; //打开INT1的中断允许
EA = 1; //打开总中断
}
void EXTI2_Switch(uint8_t Status)
{
EX2 = Status;
}
void EXTI3_Init(uint8_t EXTI_Type, uint8_t Priority)
{
#if EXTI_USE_STC
IPH &= ~0x80;
IPH |= (2 & Priority) << 6;
#endif
PX3 = (1 & Priority); //设置中断优先级
IT3 = EXTI_Type; //触发方式
EX3 = 1; //打开INT1的中断允许
EA = 1; //打开总中断
}
void EXTI3_Switch(uint8_t Status)
{
EX3 = Status;
}
#endif
EXTI.h
#ifndef EXTI_H_
#define EXTI_H_
#include "stdint.h"
//使用外部中断2(P4.3)和外部中断3(P4.2) 貌似只有LQFP44封装的芯片才有,普通的DIP40芯片没有
#define USE_EXTI2_EXTI3 1
//使用STC单片机的4级优先级
#define EXTI_USE_STC 1
#define EXTI_LOW_LEVEL 0
#define EXTI_FALLING 1
#if EXTI_USE_STC
//STC单片机的4级优先级
#define STC_EXTI_Priority_Lowest 0
#define STC_EXTI_Priority_Lower 1
#define STC_EXTI_Priority_Higher 2
#define STC_EXTI_Priority_Highest 3
#endif
//传统51单片机的2级优先级
#define EXTI_Priority_Low 0
#define EXTI_Priority_High 1
void EXTI0_Init(uint8_t EXTI_Type, uint8_t Priority);
void EXTI0_Switch(uint8_t Status);
void EXTI1_Init(uint8_t EXTI_Type, uint8_t Priority);
void EXTI1_Switch(uint8_t Status);
#if USE_EXTI2_EXTI3
void EXTI2_Init(uint8_t EXTI_Type, uint8_t Priority);
void EXTI2_Switch(uint8_t Status);
void EXTI3_Init(uint8_t EXTI_Type, uint8_t Priority);
void EXTI3_Switch(uint8_t Status);
#endif
#endif
main.c
#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "EXTI.h"
void main(void)
{
EXTI0_Init(EXTI_FALLING, STC_EXTI_Priority_Lowest);
EXTI1_Init(EXTI_FALLING, STC_EXTI_Priority_Highest);
while(1)
{
}
}
实验现象
按下K3,D0翻转;按下K4,D1翻转。
当按住K3时(处理外部中断0时),仍可响应外部中断1;
当按住K4时(处理外部中断1时),不能响应外部中断0。