1.在类中声明ISP()<br />class SystemObj<br />{<br />public:<br />//................<br />//类成员函数做中断函数<br /> static void HibernateISR(void);//必须声明为静态函数!!!<br /> static void SysTickISR(void);//必须声明为静态函数!!!<br />public:<br /> volatile unsigned int RamTest;<br /> union<br /> {<br /> volatile unsigned char WorkFlag;<br /> struct<br /> {<br /> unsigned char Watchdog: 1;//允许喂狗<br /> unsigned char SysTickFlag: 1;//节拍中断<br /> unsigned char MainLoopFlag: 1;//主循环运行<br /> unsigned char MainWatchdog: 1;//主循环喂狗<br /> };<br /> };<br />};<br /><br />class UartObj {<br />public:<br />//.........<br />//类成员函数做中断函数<br /> static void UART0ISR(void);//必须声明为静态函数!!!<br />};<br /><br />2.构造类成员函数<br />//5mS定时中断服务程序(类成员函数做中断函数)<br />//static//此处不能加static!!!<br />//类成员变量必须指明实际的类!!!(System.MainWatchdog 不能写成MainWatchdog)<br />void SystemObj::SysTickISR(void)<br />{<br /> Keyboard.Exec();//"零耗时键盘"消抖及运行命令<br /> if (System.Watchdog)//允许喂狗<br /> {<br /> if (!System.MainWatchdog)//中断喂狗论<br /> {<br /> if (!System.SysTickFlag && System.MainLoopFlag)//主程序在工作<br /> {<br /> WatchdogIntClear(WATCHDOG_BASE);//真正的硬件喂狗!!!<br /> }<br /> }<br /> }<br /> System.SysTickFlag = true;//通知主循环节拍中断正常工作<br />}<br /><br />//休眠激活中断服务程序(类成员函数做中断函数)<br />//static//此处不能加static!!!<br />void SystemObj::HibernateISR(void)<br />{<br /> HWREG(HIB_CTL) &= ~ HIB_CTL_HIBREQ;<br /> HibernateIntClear(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT |<br /> HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_RTC_MATCH_1);<br />}<br /><br />//串口中断服务程序(类成员函数做中断函数)<br />//static//此处不能加static!!!<br />void UartObj::UART0ISR(void)<br />{<br /><br /> unsigned long ulStatus;<br /> ulStatus = UARTIntStatus(UART0_BASE, true);<br /> UARTIntClear(UART0_BASE, ulStatus);<br /> while(UARTCharsAvail(UART0_BASE))<br /> {<br /> UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));<br /> }<br />}<br /><br />3.在startup.c内的中断向量表内填写需要中断的类成员函数地址<br />__root static const uVectorEntry g_pfnVectors[] @ "INTVEC" =<br />{<br /> { .ulPtr = __sfe( "CSTACK" ) },<br /> __program_start, // The reset handler<br />// ResetISR, // The reset handler<br /> NmiSR, // The NMI handler<br /> FaultISR, // The hard fault handler<br /> IntDefaultHandler, // The MPU fault handler<br /> IntDefaultHandler, // The bus fault handler<br /> IntDefaultHandler, // The usage fault handler<br /> 0, // Reserved<br /> 0, // Reserved<br /> 0, // Reserved<br /> 0, // Reserved<br /> IntDefaultHandler, // SVCall handler<br /> IntDefaultHandler, // Debug monitor handler<br /> 0, // Reserved<br /> IntDefaultHandler, // The PendSV handler<br /> &SystemObj::SysTickISR, // The SysTick handler<br />//不能用下列写法<br />// &System.SysTickISR, // The SysTick handler<br />//...................<br /> &UartObj::UART0ISR, // UART0 Rx and Tx<br />//不能用下列写法<br />// &Uart.UART0ISR, // UART0 Rx and Tx<br /> IntDefaultHandler, // UART1 Rx and Tx<br />//...................<br /> IntDefaultHandler, // Ethernet<br /> &SystemObj::HibernateISR // Hibernate<br />//不能用下列写法<br />// &System.HibernateISR // Hibernate<br />};<br /><br /><br />可以看出IAR实在不如GCC~~~不过还是能过得去的~~~<br /><br />请看:<br />//static//此处不能加static!!!<br />//类成员变量必须指明实际的类!!!(System.MainWatchdog 不能写成MainWatchdog)<br />void SystemObj::SysTickISR(void)<br />{<br /> Keyboard.Exec();//"零耗时键盘"消抖及运行命令<br /> if (System.Watchdog)//允许喂狗<br />//...................<br /><br />哈哈~~~看看gcc的2个步骤吧(它隐含了中断向量表)<br />1.在类中声明ISP()<br />class AdcObj {<br />public:<br />//................<br />//类成员函数做中断函数<br /> void SIG_ADC(void) __attribute__ ((signal));<br />private:<br /> unsigned char AdcNum;//加volatile将增大空间72个字节<br /> unsigned char AdcCount;//加volatile将增大空间4个字节<br /> volatile unsigned int AdcSum[8];//不改变<br /> unsigned int AdcMax[8];//加volatile将增大空间4个字节<br /> volatile unsigned int AdcMin[8];//不改变<br />};<br /><br />2.构造类成员函数<br />void AdcObj::SIG_ADC(void)<br />{<br />unsigned int adcval;<br /> adcval = ADC & 0x3ff;//取ADC转换电压,并保存<br /> SetAdcChNum(AdcNum + 1);//设置新通道<br />/*-----------------------------------------------------------<br /> 求最大值,最小值,累加和(0,5不用侧)<br />------------------------------------------------------------*/<br /> if (AdcNum & 1) {//偶数不测试<br /> AdcSum[AdcNum] += adcval;//存累加和<br /> if (adcval > AdcMax[AdcNum]) {<br /> AdcMax[AdcNum] = adcval;//最大值<br /> }<br /> if (adcval < AdcMin[AdcNum]) {<br /> AdcMin[AdcNum] = adcval;//存最小值<br /> }<br /> }<br />//...........................<br />}<br /><br />可以看出gcc才是最完美的类成员函数做中断函数~~~<br />而IAR的类成员函数做中断函数后不能访问自己类的其他成员实在倒塌~~~<br /><br />哈哈~~~估计是菜农还没彻底将其倒塌...估计还要求助TestCode同志~~~
|