📄 power.c
字号:
/*****************************************************************************
*
* $Log: D:\VM700\software\power.c $
*
* 1 03-11-17 19:51 Wang Guanping
* Begin to edit the source code.
*****************************************************************************/
#define GLOBALS_POWER
#include "include.h"
static int8u Power_Timer;
static bool EI_PowerOff_Request;
static void EnterPowerOff(void);
extern void PwmAdjust(int8u index);
extern void DisplayAvInStr(void);
extern void MCU_IO_Init(void);
extern void Enable_TimerB(void);
static bool CheckPowerOn(MESSAGE_ID nMsg);
extern int8u Video_Format_mem;
/*
需要响应和处理的事件如下:
1.面板和遥控器上的POWER按键开关
2.ACC熄灭后关机,开启后开机
3.防盗检测到后关机
4.电压低电后关机
5.非防盗和低电的情况下,检测到外部唤醒信号后开机
6.上电时通知外围设备
7.断电时通知外围设备
8.上电时要通知LCD回位
9.断电时要通知LCD回位,并且只有在回位后MCU才能降频运行
10.低电检测分为两个部分:
一个是正常的A/D转换,每隔50毫秒采样一次,数值精确,速度慢
一个是电压异常中断,当电压发生异常波动,高于上限值或者低于下限值时产生中断,速度快,只能表示电压异常
*/
extern void Osd_Init_Start(void); //jief add
extern void CCFL_Power(bool bPower);
//TFT IC initialization: RB5,TFT_4094
//MTV018,UPD16431的初始化在各自的驱动程序里
//将下列参数写入到外围设备之中
//nAspect
//nRB5
extern void TFT_Device_Init(void)
{
LoadT100TestPara(ParaDataNtscCvbs,TOTAL);
if(Video_Format_mem==CVBS_PAL)
Load_PAL_to_T100();
else if(Video_Format_mem==CVBS_SECAM)
Load_SECAM_to_T100();
#if ADD_PALM
else if(Video_Format_mem==CVBS_PALM)
Load_PALM_to_T100();
#endif
else
Load_NTSC_to_T100();
SetWatchDog;
#if POWER_ON_LOGO==0
//070313;OSDInit();
#else
T100I2CWriteByte(TW100,0x18,0x3f);//Switch Analog Source Mux to YUV
//T100I2CWriteByte(TW100+4,0x00,0x01);//Switch Analog Source Mux to CVBS
T100I2CWriteByte(TW100,0xC2,0x12);//0213.avoid ghost shape;
#endif
//T100I2CWriteByte(TW100+4,0x07,0x24); //Set Auto Blue Screen On
//ShowAllFonts();
gobal_user_para.brightness=nBright;
gobal_user_para.contrast=nContrast;
gobal_user_para.color=nColor;
gobal_user_para.tint=nTint;
if(DimmerFuncSet==0) nAutoDimmer_Flag=0;
gobal_user_para.setup_dimmer.option=nAutoDimmer_Flag;
gobal_user_para.setup_dimmer.dimmer=nDimmer;
gobal_user_para.lcd_mode=nAspect;
gobal_user_para.mirror=nMirror;
gobal_user_para.source=nSource;
gobal_user_para.volume=nVolume;
gobal_user_para.language=nLanguage;
gobal_user_para.blue=nBlueScreen;
/* if(nBlueScreen)
T100I2CWriteByte(TW100+4,0x07,0x24);//full blue screen;
else
T100I2CWriteByte(TW100+4,0x07,0x04);
*/
//SetAutoBlueScreen();
//??? if not to do as below,display will be abnormal at start.
/*{
if(nAspect==NORMAL)
PostMessage(ScreenMsgQueue,MSG_LCD_SCALE,FULL);
PostMessage(ScreenMsgQueue,MSG_LCD_SCALE,(int16u)nAspect);
}*/
Delay_ms(5);
RB5_Init();
return;
}
/*
时序要求:
B+打开后,延时200MS打开TFT,再延时50MS打开CCFL,之后才能设置ABRT
异常关机时,快速对B+放电后,再关闭其它设备。放电持续时间为200MS,以免耗电。关机后延时2S再回收显示屏。
按键关机时,对B+正常关机而不是放电。
按键关机后,只有按键或者WAKEUP才能开机
*/
//系统设备电源M5V控制
//SWITCH_ON信号用来安全的打开/关闭电源
//SWITCH_OFF信号用来快速的放电、关闭电源,该信号本身消耗电流很大,因此不能长久的置为有效,
//在放电完毕后应该设置SWITCH_ON,将SWITCH_OFF复位,
//当SWITCH_OFF=1时,SWITCH_ON信号可以不起作用
// SWITCH_OFF,SWITCH_ON
// 0 0 = NORMAL POWER OFF
// 0 1 = NORMAL POWER ON
// 1 0 = QUICKLY POWER DOWN
// 1 1 = QUICKLY POWER DOWN, DO NOT USE THIS STATE
static void M5V_SW(bool bPower) //该模块控制所有电源
{
if(bPower==false)
Clr_SWITCH_ON
else
Set_SWITCH_ON
return;
}
extern void CCFL_Power(bool bPower)
{
if(bPower==false)
{
Clr_CCFL_EN;
return;
}
Clr_CCFL_EN;
Delay_ms(10);
Set_CCFL_EN;
Delay_ms(10);
Clr_CCFL_EN;
Delay_ms(10);
Set_CCFL_EN;
return;
}
//电池电压检测(A/D)
//根据电压的绝对值来判断是否应该开机
//static int8u nSampleBattery;
//机器电源打开时,开关电源充电,有可能将B+拉低,因此在等待电源稳定的时间内
//(INITIAL_STEP1)不要响应B+异常中断。
//同时需要在主循环里面监视B+异常的持续时间,若时间过长,要马上关机
//ACC,B+都是沿触发中断,外部的尖脉冲有可能错误触发中断,
//因此需要消抖处理
//检测,电压异常
//当ACC,B+公用一个中断源时,先发生的中断会屏蔽后来的中断,
//因此后发生的信号只能依靠扫描的方式进行检测
/*extern void Battery_Abnormal_Detect(void)
{
if(nPowerState==INITIAL_STEP1)return;
//沿信号要复位采样计数器
nSampleBattery=N_SAMPLE_VOLTAGE;
if(F_PowerStatus_Val()==0)return;//已经检测完,不再检测
for(Sample=0;;)
{
//循环体执行时间:12 instruction cycle
//正常情况下,B_DET_H=L, B_DET_L=H
if(_B_H_DET_Val==0&&_B_L_DET_Val) //先进中断,再检测I/O
{
return;
}
Sample--;
if(Sample==0)break;
}
//现在检测到电压异常,检测完成,要求关机。到底是高电压异常,还是低电压异常,不判断。
EmergencyPowerDown();
return;
}*/
//060929.带ZENER DIODE;
//#define V0 0x98 //最低开机电压;
//#define V1 0xcc //最高开机电压;
//#define V2 0xc4 //最低关机电压;
//061008.带ZENER DIODE;
//#define V0 0x98 //最低开机电压;
//#define V1 0xcc+8 //最高开机电压;
//#define V2 0xc4+4 //最低关机电压;
//061009.ONLY DIVIDE VOLTAGE BY TWO RESISTORS:100K/20K=5:1
#if 0
#define V0 ((255/5*8+3)/6-1) //最低关机电压;9V
#define V1 ((255/5*8+3)/6+12) //最低开机电压;9.5V
#define V2 ((255/5*16+3)/6) //最高开机电压;16V
#define V3 ((255/5*16+3)/6+8) //最低关机电压;17V 0xff/5V*17V/6
#endif
//#define V0 ( Div((255/5*8+3),6)-1 ) //最低关机电压;9V
//#define V1 ( Div((255/5*8+3),6)+12 ) //最低开机电压;9.5V
//#define V2 ( Div((255/5*16+3),6) ) //最高开机电压;16V
//#define V3 ( Div((255/5*16+3),6)+8 ) //最低关机电压;17V 0xff/5V*17V/6
#define V0 0x48 //最低关机电压;9V
#define V1 0x4C //最低开机电压;9.5V
#define V2 0x84 //最高开机电压;16V
#define V3 0x8C //最低关机电压;17V 0xff/5V*17V/6
extern void Battery_Abnormal_Detect(void)
{
int8u i;
int8u HighV=0;
//if(nPowerState<SYSTEM_RUN)return;
for(i=0;i<4;i++)
{
HighV+=(ADC_8b(10)>>2);
}
#if VOLTAGE_DETECT==0
HighV=V1+5;//debug;
#endif
if(HighV>=V1&&HighV<=V2)//061011.
{
F_PowerStatus_Set();
if(nPowerState==POWER_OFF&&PowerOffSource==BATTERY_POWER_OFF)//&&BatteryFailTimer==0)
Send_Power_On();
}
if(HighV>=V3||HighV<=V0) //061011.
{
F_PowerStatus_Clr();
if(nPowerState!=POWER_OFF)
{
EnterPowerOff();//060819.
Send_Power_Off();
PowerOffSource=BATTERY_POWER_OFF;
nPowerState=POWER_OFF;
}
}
}
static void CheckPowerOff(MESSAGE_ID nMsg)
{
if(EI_PowerOff_Request)
{
EI_PowerOff_Request=false;
nMsg=MSG_POWER_OFF;
}
if(nMsg==MSG_POWER_OFF)
{
Power_Timer=0;
//阻止除POWER之外的其它按键
Clr_Machine_Power();
Disable_TimerA();
ClrBit(Video_Flag,F_SysMenu);
MCU_IO_Refresh();
EnterPowerOff();
nPowerState=POWER_OFF;//debug;
}
}
//电池电压异常中断
//只有在异常时才会中断,中断的唯一目的是快速关机,并马上保存eeprom
//异常有两个来源:ACC失效,B+异常。
//在这里判断关机信号的来源,进行关机的处理。
//由于是双向触发,只有在可能导致关机的事件发生时,
//才需要中断响应和处理,开机的事件可以通过扫描来识别
void ISR_EI1()
{
return;//debug;0212;
/* MCCSR=0B00000010;// Fcpu=Fosc2
//nPC无用,在这里用作临时变量
nPC=nPF^PFDR;
//记忆EI1中断端口的值,以便在中断发生后判断中断来源
nPF&=0b11111000;
nPF|=(PFDR&0b00000111);
if(ValBit(nPC,_ACC_DET))
{
nPC=0;
ACC_Off_Detect();
return;
}
nPC=0;
Battery_Abnormal_Detect();
*/
}
#if D_ADD_ACC_DETECT
static void ACC_Off_Detect(void)
{
//沿信号要复位采样计数器
nSampleACC=N_SAMPLE_ACC;
if(ValBit(Det_Flag,F_ACC_Det)==0)return;
for(Sample=0;;)
{
//循环体执行时间:12 instruction cycle
if(ACC_OFF_DET_Val==0)
{
return;
}
Sample--;
if(Sample==0)break;
}
ClrBit(Det_Flag,F_ACC_Det);
nCloseACCTimer=MAX_IGNITION_TIME;
Send_Power_Off();
CheckPowerOff(MSG_POWER_OFF);
return;
}
static void ACC_Detect()
{
bool port;
port = ACC_OFF_DET_Val; //采样
//if(gobal_user_para.source==1)return;//AV2时不进行ACC检测控制
if(nSampleACC)nSampleACC--;
if(nSampleACC==0)
{
//多次采样确认
if(port)
ACC_Off_Detect();//管脚变为invalid
else
{
if (ValBit(Setting_Flag,F_On_Off)
&&Machine_Power()==0&&F_PowerStatus_Val())
{
Send_Power_On();
}
SetBit(Det_Flag,F_ACC_Det);
}
}
if(ValBit(Det_Flag,F_ACC_Det))
{
nSampleACC=N_SAMPLE_ACC;
if(port)
ACC_Off_Detect();//管脚变为invalid
return;
}
if(port)
{
//端口电平与标志位一致 :=invalid
nSampleACC = N_SAMPLE_ACC;
return;
}
}
#endif
extern bool T100aIsInReset(void)
{
if(!Main_Power())return false;
if(nPowerState<=INITIAL_STEP2)
return true;
return false;
}
//系统全速运行
static void SystemPowerUp()
{
MCCSR=0B00000010;// Fcpu=Fosc2
CCFL_Power(false);
M5V_SW(true);
Enable_TimerA();
return;
}
static bool CheckPowerOn(MESSAGE_ID nMsg)
{
EI_PowerOff_Request=false;
if(/*060918.PowerOffSource!=KEY_POWER_OFF||*/nMsg==MSG_POWER_ON)
{
MCCSR=0B00000010;// Fcpu=Fosc2
nPowerState=SWITCH_ON_DELAY;
//nPowerState=RESET_POWER_UP; //070113.
Power_Timer=0;
return true;
}
return false;
}
static void EnterPowerOff(void)
{
//zyq.the following sentence is moved to below in order to avoid flashing before screen close.
Disable_TimerA();
I2C_Disable();
ADC_Disable;
Power_Timer=0;
MCU_IO_Refresh();
ClearMessage(PwrMsgQueue);
ClearMessage(OsdMsgQueue);
nPowerState=POWER_OFF;
//070108.SetBit(Sys_Flag,F_SystemWait);
//BatteryFailTimer=200;
return;
}
//本函数的入口只有两个消息和标志位g_Flag.F_MachineState
//其它所有底层中断和检测函数,都必须通过这个途径来和本函数进行交互
//需要处理的对象如下:
//SWITCH_ON,SWITCH_OFF
//ACC,LOCK,_POSITION_SW
//B+ FAILURE,B+ VOLTAGE AD CONVERTER
//TFT,CCFL,ABRT,TV_PCON,BEEP
//Fcpu
//MUTE1,MUTE2
extern void PowerManage()
{
MESSAGE nMsg;
Battery_Abnormal_Detect(); //060819.
#if D_ADD_ACC_DETECT
ACC_Detect();
#endif
if(nPowerState<INITIAL_STEP4)
{
Adject_Volume(0);
Mute_Audio_Set;
}
nMsg=*GetMessage(PwrMsgQueue);
//Time slot is 12ms
Power_Timer++;
//061107.ClrBit(Sys_Flag,F_SystemWait);
switch(nPowerState)
{
case RESET_POWER_UP:
//Mute_Audio_Set;
if(Power_Timer>=42)
{
MCCSR=0B00000010;// Fcpu=Fosc2
PowerOffSource=POWER_ON;
nPowerState=SWITCH_ON_DELAY;
Power_Timer=0;
CheckPowerOff(nMsg.ID);
CCFL_Power(false);
}
break;
case SWITCH_ON_DELAY:
//Mute_Audio_Set;
//ClrBit(Setting_Flag,F_Audio_Mute);//060920.
#if 0
if(ValBit(Det_Flag,F_ACC_Det)==0)
{
Send_Power_Off();
CheckPowerOff(MSG_POWER_OFF);//power off!
break;
}
#endif
#if ResetJudge==ResetJudgeNew
CCFL_Power(false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -