例2:一个SWI演示例程(STC12C5AxxS2单片机)
#include #include sbit LED = P1^0; //定义软件中断使用的中断号, 可选0~9 #define SWI_NUM 1 //使用外部中断0作软中断 #if SWI_NUM == 0 #define SWI_IRQ() IE0 = 1 #define CLEAR_SWI() //IE0 = 0 //使用T0中断作软件中断 #elif SWI_NUM == 1 #define SWI_IRQ() TF0 = 1 #define CLEAR_SWI() TF0 = 0 //使用外部中断1作软中断 #elif SWI_NUM == 2 #define SWI_IRQ() IE1 = 1 #define CLEAR_SWI() //IE1 = 0 //使用T1中断作软件中断 #elif SWI_NUM == 3 #define SWI_IRQ() TF1 = 1 #define CLEAR_SWI() TF1 = 0 //使用UART中断作软件中断 #elif SWI_NUM == 4 #define SWI_IRQ() RI = 1 #define CLEAR_SWI() RI = 0 //使用ADC中断作软件中断 #elif SWI_NUM == 5 #define SWI_IRQ() ADC_CONTR = 0x10 #define CLEAR_SWI() ADC_CONTR = 0x00 //使用LVD中断作软件中断 #elif SWI_NUM == 6 #define SWI_IRQ() PCON |= 0x20 #define CLEAR_SWI() PCON &= 0xDF //使用PCA中断作软件中断 #elif SWI_NUM == 7 #define SWI_IRQ() CF = 1 #define CLEAR_SWI() CF = 0 //使用UART2中断作软件中断 #elif SWI_NUM == 8 #define SWI_IRQ() S2CON |= 0x01 #define CLEAR_SWI() S2CON &= 0xFE //使用SPI中断作软件中断 #elif SWI_NUM == 9 #define SWI_IRQ() SPDAT = 0xFF #define CLEAR_SWI() SPSTAT = 0xC0 #endif #ifdef SWI_NUM unsigned char FunctionNum;// unsigned char * InputParameter; unsigned char * OutputParameter; #define SWI(a,b,c) \\ FunctionNum=a; \\ InputParameter = (unsigned char *)&b \\ OutputParameter = (unsigned char *)&c; \\ SWI_IRQ(); \\ _nop_(); #endif void SwiFunction_Init(void) { //将硬件中断源置于高优先级, IP = 0xFF; IP2 = 0xFF; IPH = 0x00; IPH2 = 0x00; //将软中断所使用的中断源置于低优先级 #if SWI_NUM < 8 IP &= ~(0x01<#include #include void Set_LED0(void); void Set_LED1(void); sbit LED = P1^0; //定义软件中断使用的中断号 省略,同例2 #ifdef SWI_NUM unsigned char FunctionNum; void (*Func_CallBack)(void); #define SWI(a,b) \\ FunctionNum=a; \\ Func_CallBack = (void *)b; \\ SWI_IRQ(); \\ _nop_(); #endif void SwiFunction_Init(void){//省略,代码同例2} void Set_LED0(void){LED = 0;} void Set_LED1(void){LED = 1;} void main(void) { unsigned char SwiFun_Num; int i; P0 = 0xFF; P1 = 0xFF; P2 = 0xFF; P3 = 0xFF; SwiFunction_Init();//初始化软中断功能 SwiFun_Num = 0; while(1) { SwiFun_Num++; //申请软中断服务 if(LED ==1) SWI(SwiFun_Num,Set_LED0); Else SWI(SwiFun_Num,Set_LED1); for(i=0;i<32767;i++) _nop_(); } } #ifdef SWI_NUM void SWI_ISR(void) interrupt SWI_NUM {//软中断服务函数,提供的服务是执行指定的功能函数 CLEAR_SWI();//清除可能需要清除的标志 Func_CallBack();//执行指定的功能函数 FunctionNum = 0;//清除申请功能号 } #endif 例程4:一个SWI演示例程,互斥访问I2C总线(STC12C5AxxS2单片机)
typedef struct Swi_List * SwiNode; typedef struct Swi_List{ unsigned int TimeDelay;//延迟多少时间开始执行,等于0表示立即执行 void (*Func)(unsigned char * pInOut);//执行的函数入口地址 unsigned char * pInOut;//执行函数的数据输入输出地址 SwiNode NextNode;//下一个节点的地址 }; SwiNode SWI_Head_Node;//系统内核使用的指针变量 #ifdef SWI_NUM unsigned char FunctionNum; SwiNode SwiIRQNode; #define SWI(a,b) \\ FunctionNum = a; \\ SwiIRQNode = b; \\ SWI_IRQ(); \\ _nop_(); #endif uint8 IICRead(uint8 *Ret,uint8 Addr,uint8 NByte) {//硬件上操作总线,完成读取功能 (省略) } uint8 IICWrite(uint8 Addr,uint8 *Data,uint8 NByte) {//硬件上操作总线,完成写入功能 (省略) } void PCF8563Read(uint8 *Data) { uint8 NByte; NByte = *Data++; IICWrite(PCF8563Addr,Data,1); IICRead(Data - 1,PCF8563Addr,NByte); } void PCF8563Write(uint8 *Data) { uint8 NByte; NByte = *Data++; NByte++; IICWrite(PCF8563Addr,Data,NByte); } void Get_Temperature(int *RegTemperature) {//读传感器的温度,传感器的地址由*RegTemperature指定 uint8 SensorAddr; uint8 TempReg[2]; SensorAddr = (uint8 *) RegTemperature;//访问的传感器地址 TempReg[0] = SENSOR_REG_TEMPERATURE; 访问传感器的温度值寄存器 IICWrite(WRITE_SENSOR_ADDR0+(SensorAddr&0x07)*2,TempReg,1);//写一个字节 IICRead(Temp, READ_SENSOR_ADDR0+(SensorAddr&0x07)*2,2);//读两个字节 *RegTemperature = (Temp [0]<<8)+ Temp [1];