main.c文件
#include "stc8h.h"
#include "intrins.h"
// 定义E1~E8引脚
sbit E1 = P4^5;
sbit E2 = P2^7;
sbit E3 = P2^6;
sbit E4 = P2^5;
sbit E5 = P2^4;
sbit E6 = P0^2;
sbit E7 = P0^1;
sbit E8 = P4^6;
sbit RST_ALL = P0^3;
// 定义MOS_E1~MOS_E8引脚
sbit MOS_E1 = P5^1;
sbit MOS_E2 = P4^4;
sbit MOS_E3 = P2^1;
sbit MOS_E4 = P2^3;
sbit MOS_E5 = P5^2;
sbit MOS_E6 = P0^5;
sbit MOS_E7 = P0^7;
sbit MOS_E8 = P5^5;
// 定义E1~E8复位引脚
sbit RST_E1 = P5^0;
sbit RST_E2 = P4^3;
sbit RST_E3 = P2^0;
sbit RST_E4 = P2^2;
sbit RST_E5 = P0^4;
sbit RST_E6 = P5^3;
sbit RST_E7 = P0^6;
sbit RST_E8 = P5^4;
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
#define Delay1ms 1
// #define Delay10ms 10
#define Delay10ms 20
u8 prev_ch;
// 延时函数
void DelayXms(int T) {
while(T--) {
int i = 2352; //@12.000MHz
while(i--);
}
}
// 初始化所有IO为低电平
void InitIO() {
// E1~E8初始化为输入模式(外部信号输入)
E1 = E2 = E3 = E4 = E5 = E6 = E7 = E8 = 0;
// MOS_E1~MOS_E8初始化为低电平
MOS_E1 = MOS_E2 = MOS_E3 = MOS_E4 = MOS_E5 = MOS_E6 = MOS_E7 = MOS_E8 = 0;
// 复位引脚初始化
RST_E1 = RST_E2 = RST_E3 = RST_E4 = RST_E5 = RST_E6 = RST_E7 = RST_E8 = 0;
}
// 配置端口模式(E1~E8为输入,MOS为推挽输出)
void IOConfigMode() {
// 配置E1~E8、RST_ALL为高阻输入模式(PxM1=1, PxM0=0)
// P4.5(E1)、P4.6(E8) -> 高阻输入
P4M0 = 0x18;
P4M1 = 0x60;
// P2.4(E5)、P2.5(E4)、P2.6(E3)、P2.7(E2) -> 高阻输入
P2M0 = 0x0F;
P2M1 = 0xF0;
// P0.1(E7)、P0.2(E6)、P0.3(RST_ALL) -> 高阻输入
P0M0 = 0xF0;
P0M1 = 0x0E;
// P5.0、P5.1、P5.2、P5.3、P5.4、P5.5 -> 推挽输出
P5M0 = 0x3F;
P5M1 = 0x00;
}
// 配置中断模式(上升沿触发)
void InterruptMode() {
// P0.1(E7)、P0.2(E6)、P0.3(RST_ALL)
P0IM0 = 0x0E; // IM0=1(上升沿触发)
P0IM1 = 0x00; // IM1=0
// P2.4(E5)、P2.5(E4)、P2.6(E3)、P2.7(E2)
P2IM0 = 0xF0; // IM0=1(上升沿触发)
P2IM1 = 0x00; // IM1=0
// P4.5(E1)、P4.6(E8)
P4IM0 = 0x60; // IM0=1(上升沿触发)
P4IM1 = 0x00; // IM1=0
}
// 使能中断
void EnableIoInterrupt() {
// 使能P0.1(E7)、P0.2(E6)、P0.3(RST_ALL)中断
//P0INTE = 0x06;
P0INTE = 0x0E;
// 使能P2.4~P2.7(E2~E5)中断
P2INTE = 0xF0;
// 使能P4.5(E1)、P4.6(E8)中断
P4INTE = 0x60;
}
// 复位所有开关
void ResetAllSwitch() {
RST_E1 = RST_E2 = RST_E3 = RST_E4 = RST_E5 = RST_E6 = RST_E7 = RST_E8 = 1;
DelayXms(Delay10ms);
RST_E1 = RST_E2 = RST_E3 = RST_E4 = RST_E5 = RST_E6 = RST_E7 = RST_E8 = 0;
}
// 复位其他通道的RST引脚(当前通道除外)
void ResetOtherSwitches(u8 channel) {
if(prev_ch != channel) {
// 复位上一个通道
if(prev_ch == 1) RST_E1 = 1;
if(prev_ch == 2) RST_E2 = 1;
if(prev_ch == 3) RST_E3 = 1;
if(prev_ch == 4) RST_E4 = 1;
if(prev_ch == 5) RST_E5 = 1;
if(prev_ch == 6) RST_E6 = 1;
if(prev_ch == 7) RST_E7 = 1;
if(prev_ch == 8) RST_E8 = 1;
}
if(channel == 1) MOS_E1 = 1;
if(channel == 2) MOS_E2 = 1;
if(channel == 3) MOS_E3 = 1;
if(channel == 4) MOS_E4 = 1;
if(channel == 5) MOS_E5 = 1;
if(channel == 6) MOS_E6 = 1;
if(channel == 7) MOS_E7 = 1;
if(channel == 8) MOS_E8 = 1;
DelayXms(Delay10ms); // 保持10ms,实际大概20ms
if(prev_ch != channel) {
// 复位上一个通道
if(prev_ch == 1) RST_E1 = 0;
if(prev_ch == 2) RST_E2 = 0;
if(prev_ch == 3) RST_E3 = 0;
if(prev_ch == 4) RST_E4 = 0;
if(prev_ch == 5) RST_E5 = 0;
if(prev_ch == 6) RST_E6 = 0;
if(prev_ch == 7) RST_E7 = 0;
if(prev_ch == 8) RST_E8 = 0;
}
if(channel == 1) MOS_E1 = 0;
if(channel == 2) MOS_E2 = 0;
if(channel == 3) MOS_E3 = 0;
if(channel == 4) MOS_E4 = 0;
if(channel == 5) MOS_E5 = 0;
if(channel == 6) MOS_E6 = 0;
if(channel == 7) MOS_E7 = 0;
if(channel == 8) MOS_E8 = 0;
}
// 主函数
void main() {
InitIO();
P_SW2 |= 0x80; // 允许访问扩展寄存器
IOConfigMode();
ResetAllSwitch();
InterruptMode();
EnableIoInterrupt();
EA = 1; // 全局中断使能
while(1);
}
// 中断服务程序(中断号13对应P0/P1/P2/P3/P4/P5中断)
void io_isr() interrupt 13 {
u8 intf0 = P0INTF;
u8 intf2 = P2INTF;
u8 intf4 = P4INTF;
// 处理P0中断(E6, E7)
if(intf0) {
if(intf0 & 0x08) { // P0.3(RST_ALL)中断
DelayXms(Delay1ms);
if(RST_ALL == 1) {
ResetAllSwitch();
DelayXms(Delay10ms);
P0INTF &= ~0x08; // 清除标志
}
}
if(intf0 & 0x04) { // P0.2(E6)中断
DelayXms(Delay1ms);
if(E6 == 1) {
ResetOtherSwitches(6);
prev_ch = 6;
P0INTF &= ~0x04; // 清除标志
}
}
if(intf0 & 0x02) { // P0.1(E7)中断
DelayXms(Delay1ms);
if(E7 == 1) {
ResetOtherSwitches(7);
prev_ch = 7;
P0INTF &= ~0x02; // 清除标志
}
}
}
// 处理P2中断(E2, E3, E4, E5)
if(intf2) {
if(intf2 & 0x10) { // P2.4(E5)中断
DelayXms(Delay1ms);
if(E5 == 1) {
ResetOtherSwitches(5);
prev_ch = 5;
P2INTF &= ~0x10; // 清除标志
}
}
if(intf2 & 0x20) { // P2.5(E4)中断
DelayXms(Delay1ms);
if(E4 == 1) {
ResetOtherSwitches(4);
prev_ch = 4;
P2INTF &= ~0x20; // 清除标志
}
}
if(intf2 & 0x40) { // P2.6(E3)中断
DelayXms(Delay1ms);
if(E3 == 1) {
ResetOtherSwitches(3);
prev_ch = 3;
P2INTF &= ~0x40;
}
}
if(intf2 & 0x80) { // P2.7(E2)中断
DelayXms(Delay1ms);
if(E2 == 1) {
ResetOtherSwitches(2);
prev_ch = 2;
P2INTF &= ~0x80; // 清除标志
}
}
}
// 处理P4中断(E1, E8)
if(intf4) {
if(intf4 & 0x20) { // P4.5(E1)中断
DelayXms(Delay1ms);
if(E1 == 1) {
ResetOtherSwitches(1);
prev_ch = 1;
P4INTF &= ~0x20; // 清除标志
}
}
if(intf4 & 0x40) { // P4.6(E8)中断
DelayXms(Delay1ms);
if(E8 == 1) {
ResetOtherSwitches(8);
prev_ch = 8;
P4INTF &= ~0x40; // 清除标志
}
}
}
}
ISR.ASM文件
CSEG AT 012BH ;P0口中断入口地址
JMP P0INT_ISR
P0INT_ISR:
JMP 006BH ;借用13号中断入口地址
;CSEG AT 0133H ;P1口中断入口地址
;JMP P1INT_ISR
;P1INT_ISR:
;JMP 006BH ;借用13号中断入口地址
CSEG AT 013BH ;P2口中断入口地址
JMP P2INT_ISR
P2INT_ISR:
JMP 006BH ;借用13号中断入口地址
;CSEG AT 0143H ;P3口中断入口地址
;JMP P3INT_ISR
;P3INT_ISR:
;JMP 006BH ;借用13号中断入口地址
CSEG AT 014BH ;P4口中断入口地址
JMP P4INT_ISR
P4INT_ISR:
JMP 006BH ;借用13号中断入口地址
END
;CSEG AT 0153H ;P5口中断入口地址
;JMP P5INT_ISR
;P5INT_ISR:
;JMP 006BH ;借用13号中断入口地址
;END
程序总是会复位其他引脚