#include "ctrl.h" #include "stm8s_beep.h" #include "task.h" #include "DC2AC.H" #include "key.h" #include "EEPROM.H" #include "WarnCtrl.h" #include "modbus.h" #include "main.h" extern unsigned char Warning_flag; const unsigned char LED7Code[]={ 0xC0, // 0 0xF9, // 1 0xA4, // 2 0xB0, // 3 0x99, // 4 0x92, // 5 0x82, // 6 0xF8, // 7 0x80, // 8 0x90, // 9 0x88, // A 0x83, // B 0xC6, // C 0xA1, // D 0x86, // E 0x8E, // F 0xFF //0x10 }; sIOBuffer SPIIO={0xFF,0xFF,0xFF,0,0xFF}; //DM74HC164 SPI74HC164={0xFF}; IED_DATABASE @near IED; MyTimeOut TimeOut ; #define FIXTIMECNT 100L //25S 50ms*100 = 5S void Translate2(void); void UpdateIO(void) { char i; GPIO_WriteLow(GPIOE, SPI_CS); for(i=0;iODR&=(~0x80); SuspendTask(TASK_BEEP); } } gcBeepTrig=!gcBeepTrig; } /*********************************************************** 激活蜂鸣器任务 ***********************************************************/ void Beep(UCHAR cNumBeep,UINT beepTime) { int a; gcNumBeep=cNumBeep; //gcBeepTrig=1; a=beepTime; //mS //DrvGPIO_Open(E_GPA,PIN_SPK, E_IO_OUTPUT); //DrvGPIO_SetBit(E_GPA,PIN_SPK); ActiveTask(TASK_BEEP,a); } void StopBeep(void) { SetWarningFreq(0); BEEP_Cmd(DISABLE); SuspendTask(TASK_BEEP); } unsigned char gcMotorDir = 0; //方向控制薄码开关 //启动电机运行,1S 后启动位置检测信号 //#define gcPhaseCtrl unsigned char gcPhaseCtrl; signed char gcTimer_Motor_ID = -1; //#define TIME_OVERROLL 40L #define TIME_OVERROLL (IED.OverRollTime) signed char MovMotor(unsigned char cPos) { if(IED.cMoving==1) { return -1; } _nop_(); if(cPos==IED.cPos) { #ifdef _DEBUG printf("电机已经到位,无需执行该命令\n"); #endif return -2; } _nop_(); MOTOR__RUN = 0; switch(cPos) { case POS_TOP: //到顶,方向为向上 IED.Direction=MOTOR_UP; //修正短期行走为0的问题 break; case POS_BOT: IED.Direction=MOTOR_DOWN; //到底,方向为向下 //到底部,超时时间为TimeTopToBot break; case POS_MIDDLE: return -2; case POS_UNKNOWN: default: return -5; } ///////////////////////////////////////////////////// if((IED.Err&ERR_TOP_OVERROLL)&&( MOTOR_UP==IED.Direction)) //上过卷,禁止上行 return -4; if((IED.Err&ERR_BOT_OVERROLL)&&( MOTOR_DOWN==IED.Direction)) //下过卷,禁止下行 return -4; ////////////////////////////////////////////////////// #ifdef _DEBUG // printf("方向%s ",( IED.Direction==MOTOR_UP?"向上":"向下")); #endif //有电源错误,判断运行方向后推出 if(IED.Err&(ErrPhase| //相位错 ErrOverHeat|MAIN_POWER_ERROR| //过热//无主电 COIL_SHORT_ERR|COIL_BREAK_ERR| //刹车线圈坏 ERR_MOTOR_LINE| //电机断线 ERR_RELAY_FAIL| //继电器损坏 ERR_BRAKE_POWER_FAIL )) { return -4; } /////////////////////////////////////////////// UNLockAllMotor(); EnableBrakPower(TRUE); IED.cMoving = 1; //启动电机到位检测任务 IED.BrakeDelayTimerID = StartTimer(TIMER_MODE_ONCEROUTINE, 20L,MotorDelay,0); return 0; } void ErrStopMotor(void) { LockAllMotor(); StopMotor(); } void StopMotor(void) { MOTOR__RUN = 0; ConvertDown(0);//停止逆变 EnableBrakPower(FALSE); StopTimer(&IED.MotorMoveDelayTimerID); SuspendTask(TASK_STOPMOTOR); IED.cMoving = 0; #ifdef _DEBUG printf("StopMotor()电机停止 !\n"); #endif } void GetCurretPos(void) { if(pos_top_bit==0) { IED.cPos = POS_TOP; } else if(pos_bot_bit==0) { IED.cPos = POS_BOT; } else { IED.cPos = POS_UNKNOWN; } #ifdef _DEBUG //printf("Current POS is %d\n",(int)IED.cPos); #endif _nop_(); } void EnableRunCtrl(void) { if(gcPhaseCtrl) //运行方向控制、、 MOTOR__RUN= ~(IED.Direction==MOTOR_UP?1:2); else MOTOR__RUN= (IED.Direction==MOTOR_UP?1:2); } //检测是否到位,到位后停止电机 void TaskStopMotor(void) //TASK_MOTOR { if(Warning_flag==0) Beep(1,200); //防止运行中相序发生变化 EnableRunCtrl(); //位置检测 GetCurretPos(); /////////////////////////////////////////// //到位停止 if(((IED.Direction==MOTOR_UP)&&(pos_top_bit==0)) ////运行方向向上,检测到上到位 停止 ||((IED.Direction==MOTOR_DOWN)&&(pos_bot_bit==0))) //运行方向向下,检测到下到位 停止 { #ifdef _DEBUG printf("电机到位\n上到位=%d,下到位=%d,继电器释放!\n",(int)pos_top_bit,(int)pos_bot_bit); #endif StopMotor(); _nop_(); } // CheckRelay();//检查继电器故障 CheckBrakePower();//检查刹车电源 if(IED.Err&(ERR_BRAKE_POWER_FAIL)) ErrStopMotor(); } void ResumeCheckSensor(void* p) { ActiveTask(TASK_SENSOR,500UL); } //开始报警 void StartWarning(void) { // IED.b_warning = 1; ActiveTask(TASK_WARN,100); #ifdef _DEBUG printf("Start Warning !\n"); #endif } //停止报警 unsigned char StopWarning_flag; void StopWarning(void) { SetWarningFreq(0); IED.b_warning = 0; SuspendTask(TASK_WARN); #ifdef _DEBUG printf("Stop Warning !\n"); #endif } void InitTim2(void) { TIM2_DeInit(); TIM2_TimeBaseInit( TIM2_PRESCALER_16,50000);//50ms TIM2_ITConfig( TIM2_IT_UPDATE , ENABLE); TIM2_SetCounter(0x0000); TIM2_Cmd(ENABLE); } @far @interrupt void TIM2_UPD_OVF_BRK_IRQHandler(void) { static char m; TIM2_ClearITPendingBit(TIM2_IT_UPDATE);//清除中断标记位 if(StopWarning_flag==1) { m++; if(m>=30) { StopWarning_flag=0; GPIO_WriteHigh(GPIOA, GPIO_PIN_2);//关闭3S后重新开启 m=0; } } } #define FREQ_MIN 450L #define FREQ_MAX 1500L //定时器产生的脉冲 //////////////报警控制//////////////////////////// //unsigned int gcFreqCurr = 0; //当前频率 //char gcFreqdir = 1; //频率方向 //报警任务 void TaskWarn(void) { //if(IED.WarnMute^IED.u_WarnState) SetWarningFreq(IED.FreqCurr); //else // SetWarningFreq(0); if(IED.FreqCurr>=FREQ_MAX) { IED.FreqCurr = FREQ_MAX; IED.Freqdir=-1; } if(IED.FreqCurr<=FREQ_MIN) { IED.FreqCurr = FREQ_MIN; IED.Freqdir=1; } IED.FreqCurr+=IED.Freqdir*20; } void MotorDelay(void *p) { IED.BrakeDelayTimerID = -1; EnableRunCtrl(); ActiveTask(TASK_STOPMOTOR,50); ////每50ms检测一次电机是否到位 #ifdef _DEBUG //printf("启动电机!\n"); #endif } //volatile unsigned int INT1Cnt = 0; int HiCnt = 0; int LowCnt = 0; int abs(int x) {return x>0?x:-x;} void TaskCheckPhase(void) { int err; #ifdef _DEBUG //printf("Hicnt=%u,LowCnt=%u\n",(unsigned int)HiCnt,(unsigned int)LowCnt) ; #endif err = abs(HiCnt-LowCnt); if(err<60*PHASE_PRIOD/1000L) { #ifdef _DEBUG printf("缺相错误,停止电机运行\n") ; #endif ErrStopMotor(); IED.Err |= ErrPhase; IED.Err &= (~ERR_BRAKE_POWER_FAIL); IED.Err &= (~ERR_RELAY_FAIL); } else { if(HiCnt>LowCnt) { gcPhaseCtrl =1; //相位反过来了 IED.Err &= (~ErrPhase); #ifdef _DEBUG //printf("相位正确,电机正向运行\n") ; #endif } else { //IED.Err &= (~ErrPhase); IED.Err |= ErrPhase; //锁定这个相位 gcPhaseCtrl =0; //正确相位 #ifdef _DEBUG //printf("相位错误,电机反向运行\n") ; #endif } //IED.Err &= (~ErrPhase); } LowCnt = HiCnt =0; //电机过热保护报错 } char PreEx1,PreEx2; void TaskFREQ(void) { char Ph1,Ph2 ; char PhaseIn = GPIOD->IDR; Ph1 = PhaseIn&0x04; Ph2 = PhaseIn&0x08; if((!Ph1)&&(Ph1!=PreEx1)) //下降沿 { if(Ph2) HiCnt ++; else LowCnt ++; } if((!Ph2)&&(Ph2!=PreEx2)) { if(Ph1) LowCnt ++; else HiCnt ++; } PreEx1 = Ph1; PreEx2 = Ph2; if((pos_bot_bit==0)&&(pos_top_bit==0))//过热保护 { IED.Err |= ErrOverHeat; } else { IED.Err &= (~ErrOverHeat); } } char preIDMode = 3; void checkSetIDMode(void) { //用户模式和检测模式切换 if(preIDMode!=ID_SET) { EEReadStruct(&IED.nId ,sizeof(IED.nId)/sizeof(char),0); checkID(); Beep(1,500); } preIDMode = ID_SET; } #define UNMASKERR 0xFFFFFFFF void MuteError(void) { IED.ErrMute=(IED.Err&UNMASKERR); StopWarning(); } char preLEDMainPower; char preLEDBatPower; char preLEDWarn; char preLEDRUN; #define FEEDSMOKE Feed_Smoke_Relay #define FEEDTEMP Feed_Temp_Relay #define LED_MAINPOWER FeedMainPowerLED void Feed(void) { //电机运行指示灯 if(IED.cMoving==1) FeedDoorRun = 0; else FeedDoorRun = 1; //相位方向为0的时候不关闭主电灯 if((IED.Err&(MAIN_POWER_ERROR|(gcPhaseCtrl?ErrPhase:0)))==0) { LED_MAINPOWER = 0; } else { LED_MAINPOWER = 1; } //报警指示灯 if(Warning_flag==1) { FeedWarnLED = 0; } else { FeedWarnLED = 1; } FeedRightPhaseLED = gcPhaseCtrl?0:1; //中位指示灯 //错误指示灯 if(IED.Err!=0) { // FeedErrLED = 1; IED.ErrMute&=IED.Err; //故障已清除,消除故障消音位为下一次故障声音报警做准备 #ifdef _DEBUG //printf("IED.Err=0X%04X\n",IED.Err); #endif //指定错误声音提示方案 if(IED.Err^IED.ErrMute) Beep(1,300); } else { } if((IED.Err&(BAT_LOW_ERR|BAT_SHORT|BAT_OVER_ERROR))==0) //电池无过压欠压错误.备电指示正常 { LED_BAT = 0; } else { LED_BAT = 1; } // FeedErrFlash(); // } void FeedErrFlash(void) { static char i = 0; i=(++i)%2; if(i==0) { //打开错误灯 if(IED.Err&(ErrPhase|MAIN_POWER_ERROR)) FeedLEDMPowerError = 0; if(IED.Err&(BAT_LOW_ERR|BAT_OVER_ERROR|BAT_SHORT)) FeedLEDBatError = 0; if(IED.Err&(COIL_SHORT_ERR|COIL_BREAK_ERR)) FeedLEDBrakeError = 0; if(IED.Err&ERR_SENSOR_SMOKE) FeedLEDSmokeSensor = 0; if(IED.Err&ERR_SENSOR_TEMP) FeedLEDTempSensor = 0; if(IED.Err&(ERR_TOP_OVERROLL|ERR_BOT_OVERROLL|ErrOverHeat)) FeedLEDOverRollSensor = 0; if(IED.Err& ERR_MOTOR_LINE) FeedLEDMotorError = 0; if(IED.Err& ERR_RELAY_FAIL) //0x2000,//继电器故障 FeedRelayErr = 0; if(IED.Err& ERR_BRAKE_POWER_FAIL)//0x4000 //逆变电源故障 FeedBrakePowerErr = 0; if(IED.Err& ErrPhase) FeedErrPhaseLED = 0; } else { //关闭所有的灯 SPI74HC164 = 0xFF; } } signed char SelftestTimer = -1; int selftestcnt = 4; void SelfTest(void) { if(SelftestTimer==-1) { Beep(3,500); selftestcnt = 4; SelftestTimer = StartTimer(TIMER_MODE_CYCROUTINE,50L,TaskSelfTestLED,0); } } void TaskSelfTestLED(void* param) { FeedMainPowerLED= !FeedMainPowerLED; FeedBatPowerLED = !FeedBatPowerLED ; FeedMidLED = !FeedMidLED; FeedWarnLED = !FeedWarnLED; FeedDoorRun = !FeedDoorRun; SPI74HC164 = ~SPI74HC164; if(selftestcnt==0) { StopTimer(&SelftestTimer); StopWarning(); Beep(1,100); ActiveTask(TASK_FEED,1000L); //ActiveTask(TASK_FEED2,500L); //SetTaskLastTime(TASK_FEED2,1000L); selftestcnt = 4; } if(selftestcnt==4) { SetWarningFreq(1000); } selftestcnt--; } //全部降落 void MotorDown(void *p) { #ifdef _DEBUG printf("MOTOR_DOWN!\n"); #endif MovMotor(POS_BOT);//启动全降信号 IED.MotorMoveDelayTimerID = -1; } void MotorUp(void *p) { #ifdef _DEBUG printf("MOTOR_UP!\n"); #endif MovMotor(POS_TOP);//启动全升信号 IED.MotorMoveDelayTimerID = -1; }