/********************************************************************************************************* FILE: TASK.C *********************************************************************************************************/ #include "task.h" #include "ctrl.h" #include "KEY.H" #include "DC2AC.H" #include "modbus.h" #include "WarnCtrl.h" //global variable //任务数据库 TASK_DATA @near TaskDb[]={ {1, TASK_MODE_PERIOD, 10L, 10L, TASK_TIMER, TaskTimer} , {1, TASK_MODE_PERIOD, 100L, 100L, TASK_BLINK, TaskBlinLed}, {0, TASK_MODE_PERIOD, 10L, 10L, TASK_BEEP, TaskBeep}, {1, TASK_MODE_PERIOD, 20l, 20L, TASK_KEY, TaskScanKey}, {0, TASK_MODE_PERIOD, 50L, 50L, TASK_WARN, TaskWarn}, {0, TASK_MODE_PERIOD, 50L, 50L, TASK_STOPMOTOR, TaskStopMotor}, {1, TASK_MODE_PERIOD, PHASE_PRIOD,PHASE_PRIOD,TASK_PHASE,TaskCheckPhase}, {1, TASK_MODE_PERIOD, 1L, 1L, TASK_FREQ, TaskFREQ}, {1, TASK_MODE_PERIOD, 2L, 2L, TASK_FREQ2, TaskFREQMotor}, {1, TASK_MODE_PERIOD, 1000L,1000L, TASK_CHECK_MOTOR,Task_Check_Motor}, {1, TASK_MODE_PERIOD, 500L, 500L, TASK_SENSOR, TaskCheckSensor}, {0, TASK_MODE_PERIOD, 1000L, 1000L, TASK_FEED, Feed}, {1, TASK_MODE_PERIOD, 1000L, 1000L, TASK_POWER_CHECK,Task_Power_Check}, {1, TASK_MODE_PERIOD, 50L, 50L, TASK_CHARGE, TaskChargeBat}, {1, TASK_MODE_PERIOD, 10L, 10L, TASK_CHECK_COIL,TaskCheckBrakeCoil}, {1, TASK_MODE_PERIOD, 10L, 10L, TASK_SEG7, Task_SEG7}, {1, TASK_MODE_PERIOD, 2L, 2L, TASK_COMM, TaskCommTimer}, {0, TASK_MODE_PERIOD, DC_DN_PR, DC_DN_PR, TASK_BREAK, BotCheck}, {1, TASK_MODE_PERIOD, 10L, 10L, TASK_STATE, ManualCtrl}, {1, TASK_MODE_PERIOD, 10L, 10L, TASK_IO, UpdateIO} }; TIMER_DATA TimerData[MAX_TIMER]; UCHAR gc1ms = 0; //1ms到标志,控制多任务处理 的时间隔为1ms UCHAR TMP1msCount = 0; CLK_TypeDef MyCLK @CLK_BaseAddress; const char LeapDays[14]={0,31,29,31,30,31,30,31,31,30,31,30,31,31}; const char NormDays[14]={0,31,28,31,30,31,30,31,31,30,31,30,31,31}; /********************************************************************************************************** 任务调度,在主循环中调用。 由于是模拟多任务,所以要求每个任务的处理时间尽可能短。 ***********************************************************************************************************/ void idle(void) { _asm("nop"); //_asm("WFI"); _asm("nop"); } void TaskProc(void) { unsigned char i; if(!gc1ms) //保证1ms扫描一次 { idle(); } else { if(TMP1msCount>0) { for(i=0;icUse) { switch(cMode) { case TIMER_MODE_TIMER: // timer only case TIMER_MODE_ONCEROUTINE: // timely routine case TIMER_MODE_CYCROUTINE: // cyclely routine break; default: pt->cUse = 0; return -1; // error } pt->lPeriod = lPeriod; // set timer period pt->lLastTime = lPeriod; // get current system time as start timer pt->routine = routine; // user timer's routine pt->cMode = cMode; // timer's work mode pt->cUse = 1; pt->Param1 = Param1; return (i); // return timer number } } #ifdef _DEBUG printf("定时器资源不足,申请不成功\n"); while(1); #endif return (-1); // no timer available } /********************************************************************************************************** FUNCTION: StopTimer PURPOSE: stop timer count ***********************************************************************************************************/ SCHAR StopTimer ( SCHAR * pcTimerNumber ) { if(*pcTimerNumber>=MAX_TIMER || *pcTimerNumber==-1) return -1; // timer number error TimerData[*pcTimerNumber].cUse=0; *pcTimerNumber = -1; return 0; } /*********************************************************************************************************** FUNCTION: StopAllTimer PURPOSE: stop all timer count ************************************************************************************************************/ void StopAllTimer(void) { unsigned char i; for(i=0;icUse) continue; if((--(pt->lLastTime))==0) { switch(pt->cMode) { case TIMER_MODE_TIMER: // timer only pt->cUse=0; break; case TIMER_MODE_CYCROUTINE: // cyclely routine pt->lLastTime+=pt->lPeriod; pt->routine(pt->Param1); // start user's routine break; case TIMER_MODE_ONCEROUTINE: // timer routine once pt->cUse=0; pt->routine(pt->Param1); // start user routine break; default: pt->cUse=0; break; } } } } /********************************************************************************************************** 定时器中断服务程序,定时器0中断1次/10mS. ***********************************************************************************************************/ char T4IntCnt; #ifdef _COSMIC_ @far @interrupt void TIM4_UPD_OVF_IRQHandler(void) #else // _RAISONANCE_ void TIM4_UPD_OVF_IRQHandler(void) interrupt 23 #endif // _COSMIC_ { T4IntCnt=(++T4IntCnt)%10; if(T4IntCnt==0) { if(gc1ms==1) { TMP1msCount++; } gc1ms=1; } TIM4_ClearITPendingBit(TIM4_IT_UPDATE); } GPIO_TypeDef PortD @GPIOD_BaseAddress; GPIO_TypeDef PortC @GPIOC_BaseAddress; GPIO_TypeDef PortA @GPIOA_BaseAddress; #define LEDPORT GPIOD #define LEDBIT 0 extern unsigned char Debug_time; void TaskBlinLed(void) { static unsigned char count =0,i=0; IWDG_ReloadCounter(); count=(++count)%10; if(count==0) { LEDPORT->ODR&=~(1<ODR|=(1<iYear>=2000) /* if after Jan 1, 2000 */ { for(days=0,year=2000;yeariYear;year++) { if((year%4==0 && year%100!=0)||(year%400==0)) days+=366; else days+=365; } for(month=1;monthcMon;month++) { if(((ptm->iYear%4==0) && (ptm->iYear%100!=0))||(ptm->iYear%400==0)) days+=LeapDays[month]; else days+=NormDays[month]; } days+=(ptm->cDay-1); t=days*86400L+ptm->cHour*3600L+ptm->cMin*60L+ptm->cSec; } return t; } /***********************************************/ //localtime, time_t 0=2000-1-1 00:00:00 /***********************************************/ void LocalTime(TIME *t,time_t *tSec) { unsigned long days,year,month,hour,min,sec; days=(*tSec/86400L); hour=(*tSec%86400L)/3600; min=(*tSec%3600L)/60; sec=*tSec%60L; year=2000; while(days>=(((year%4==0 && year%100!=0)||(year%400==0)) ? 366:365)) //if { days-=(((year%4==0 && year%100!=0)||(year%400==0)) ? 366:365); year++; } month=1; while(days>=((year%4==0) ? LeapDays[month]:NormDays[month])) { days-=(((year%4==0 && year%100!=0)||(year%400==0)) ? LeapDays[month]:NormDays[month]); month++; } days++; t->iYear=year; t->cMon=(char)(month); t->cDay=(char)(days); t->cSec=(char)(sec); t->cMin=(char)(min); t->cHour=(char)(hour); } TIM3_TypeDef MyTIM3 @TIM3_BaseAddress; void Init_task_timer(void ) { TIM4_DeInit(); TIM4_TimeBaseInit(TIM4_PRESCALER_16,100L); TIM4_ITConfig(TIM4_IT_UPDATE,ENABLE); TIM4_Cmd(ENABLE); } void InitPLL(void) { uint32_t freq; CLK_DeInit(); CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1); CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, DISABLE); CLK_LSICmd(ENABLE); //CLK_CCOConfig(CLK_OUTPUT_LSI);// } void Init_task(void) { InitPLL(); Init_task_timer(); } void Delay(UINT delayCnt) { while(delayCnt--) { _nop_(); _nop_(); } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval * None */ void assert_failed(u8* file, u32 line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif //unsigned char @near OptionByte[9] = {0xaa,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned char @near OptionByte[9] = {0xaa,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00}; // void ModifyOptionByte(void) { unsigned char opt[9]; opt[0] = *((NEAR uint8_t*)0x4800); opt[1] = *((NEAR uint8_t*)0x4801); opt[2] = *((NEAR uint8_t*)0x4803); opt[3] = *((NEAR uint8_t*)0x4805); opt[4] = *((NEAR uint8_t*)0x4807); opt[5] = *((NEAR uint8_t*)0x4809); opt[6] = *((NEAR uint8_t*)0x480B); opt[7] = *((NEAR uint8_t*)0x480D); opt[8] = *((NEAR uint8_t*)0x487E); if(memcmp(opt,OptionByte,sizeof(OptionByte))!=0) { ProgramOptionByte(); } } void ProgramOptionByte(void) { char flagstatus=0,timeout = 0xFFF; //解锁 do{ FLASH->DUKR = 0xae ; FLASH->DUKR = 0x56; } while(!(FLASH->IAPSR&0x08)); //允许访问 FLASH->CR2 = 0x80; FLASH->NCR2 = 0x7F; *((NEAR uint8_t*)0x4800) = OptionByte[0]; *((NEAR uint8_t*)0x4801) = OptionByte[1]; *((NEAR uint8_t*)0x4802) = ~OptionByte[1]; *((NEAR uint8_t*)0x4803) = OptionByte[2]; *((NEAR uint8_t*)0x4804) = ~OptionByte[2]; *((NEAR uint8_t*)0x4805) = OptionByte[3]; *((NEAR uint8_t*)0x4806) = ~OptionByte[3]; *((NEAR uint8_t*)0x4807) = OptionByte[4]; *((NEAR uint8_t*)0x4808) = ~OptionByte[4]; *((NEAR uint8_t*)0x4809) = OptionByte[5]; *((NEAR uint8_t*)0x480A) = ~OptionByte[5]; *((NEAR uint8_t*)0x480B) = OptionByte[6]; *((NEAR uint8_t*)0x480C) = ~OptionByte[6]; *((NEAR uint8_t*)0x480D) = OptionByte[7]; *((NEAR uint8_t*)0x480E) = ~OptionByte[7]; *((NEAR uint8_t*)0x487E) = OptionByte[8]; *((NEAR uint8_t*)0x487F) = ~OptionByte[8]; while ((flagstatus == 0x00) && (timeout != 0x00)) { flagstatus = (uint8_t)(FLASH->IAPSR & (uint8_t)(FLASH_IAPSR_HVOFF | FLASH_IAPSR_WR_PG_DIS)); timeout--; } /* Disable write access to option bytes */ FLASH->CR2 &= (uint8_t)(~FLASH_CR2_OPT); FLASH->NCR2 |= FLASH_NCR2_NOPT; FLASH->IAPSR &= 0xF7; WWDG->CR = 0x80;//复位stm8 while(1); }