单片机反复进入休眠唤醒导致死机问题-辉芒微FMD 62F80X
辉芒微FMD 62F80X芯片出现了按键反复开机关机操作,反复进入休眠退出,会有死机现象,死机后有时会几秒几十后自动唤醒, 有时候发现唤醒不了,怀疑是唤醒端口电平抖动执行SLEEP()时出现了问题,后来在SLEEP()前加上判断端口条件,暂时没有发现死机现象。
原来的会死机休眠程序:
void Sleep_Charge()
{
Close_All();
PWM_SET(0);
ONOFF_Display(0);//关显示
DYP_POWER=1;
//用于充电 口检测;充电口如果没有用到AN,则不需要这个操作;(只用高低电平2.2K:5.1K)
ADC_IN_MODE= 0;//TRISA0 = 0;
ADC_IN=0; //ADC_IN,用于快速判断充电口插拨,去除充电口的残留电压,以免因充电口的残留电压而影响高低电平的判断
delay_ms(100);
ADC_IN_MODE= 1;//TRISA0 = 1;
delay_ms(100);
Send_String('S','l','e','e','p',' ');
OSCCON = 0B11110001; // IRCF=1111=16MHZ/128; 切换了慢时钟,会死机过十秒左右会自动进入休眠
GIE=0;
TIM1CCER1 =0B00000000;
TIM1CCER2 =0B00000000;
TIM1CCMR1 =0B00000000; //CC1禁止输出
TIM1CCMR2 =0B00000000; //CC2禁止输出
TIM1CCMR3 =0B00000000; //CC3通道被配置为输出
TIM1CCMR4 =0B00000000; //CC4通道被配置为输出
CKOCON = 0B00000000;
TIM2CR1 = 0B00000000; //预载允许,边沿对齐向上计数器,计数器使能
TIM2IER = 0B00000000;
TIM1IER = 0B00000000;
//没有配置好这个TIM4不更新中断,可能会导致程序跑飞
TIM4CR1 = 0B00000000; //预载允许(BIT.7:0,NO), TIM4时钟选择位(BIT[5,4]:00,00:系统时钟/主时钟) , 边沿对齐向上计数器,计数器使能
TIM4IER = 0B00000000; //BIT.0: T4UIF:更新中断标记,0:不更新
ADCON0 = 0X00;
ADCON1 = 0X00;
ADON = 0;
URLCR = 0B00000000; //8位数据,停止位1,无奇偶校验
URMCR = 0B00000000;
INTCON= 0B00000000;
PCKEN = 0B00000000; //打开UART时钟
if((DC_sleep_Flag==1)&&(ADC_IN==1))
{
Charge_flag=1;
Wake_up_init();
ONOFF=1;
}
else
{
ONOFF=0;
CKOCON = 0B00000000;
INTCON=0;
PIR1=0;//慢时钟测量完成中断标志位,
EPIF0=0XFF;
EPIE0=0B10000001;//只有充电口和电源开关能唤醒;//EPIE0=0B10001111;//EPIE0=0B10000001;
PEIE= 1;//打开外设中断
NOP();
NOP();
NOP();
NOP();
SLEEP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
PEIE= 0;
EPIE0=0;
delay_us(1);
if(ADC_IN==1)
{
Charge_flag=1;
Wake_up_init();
ONOFF=1;
DYP_POWER=0;
}
else
{
if(ONOFF_KEY_IN==0)//
{
Charge_flag=0;
Wake_up_init();
ONOFF=1;
DYP_POWER=0;
}
}
}
}
现在的休眠程序: if(ONOFF_KEY_IN==1){}// 1.l暂时未发现死?
void Sleep_Charge()
{
Close_All();
PWM_SET(0);
ONOFF_Display(0);//关显示
DYP_POWER=1;
//用于充电 口检测;充电口如果没有用到AN,则不需要这个操作;(只用高低电平2.2K:5.1K)
ADC_IN_MODE= 0;//TRISA0 = 0;
ADC_IN=0; //ADC_IN,用于快速判断充电口插拨,去除充电口的残留电压,以免因充电口的残留电压而影响高低电平的判断
delay_ms(100);
ADC_IN_MODE= 1;//TRISA0 = 1;
delay_ms(100);
Send_String('S','l','e','e','p',' ');
OSCCON = 0B11110001; // IRCF=1111=16MHZ/128; 切换了慢时钟,会死机过十秒左右会自动进入休眠
GIE=0;
TIM1CCER1 =0B00000000;
TIM1CCER2 =0B00000000;
TIM1CCMR1 =0B00000000; //CC1禁止输出
TIM1CCMR2 =0B00000000; //CC2禁止输出
TIM1CCMR3 =0B00000000; //CC3通道被配置为输出
TIM1CCMR4 =0B00000000; //CC4通道被配置为输出
CKOCON = 0B00000000;
TIM2CR1 = 0B00000000; //预载允许,边沿对齐向上计数器,计数器使能
TIM2IER = 0B00000000;
TIM1IER = 0B00000000;
//没有配置好这个TIM4不更新中断,可能会导致程序跑飞
TIM4CR1 = 0B00000000; //预载允许(BIT.7:0,NO), TIM4时钟选择位(BIT[5,4]:00,00:系统时钟/主时钟) , 边沿对齐向上计数器,计数器使能
TIM4IER = 0B00000000; //BIT.0: T4UIF:更新中断标记,0:不更新
ADCON0 = 0X00;
ADCON1 = 0X00;
ADON = 0;
URLCR = 0B00000000; //8位数据,停止位1,无奇偶校验
URMCR = 0B00000000;
INTCON= 0B00000000;
PCKEN = 0B00000000; //打开UART时钟
if((DC_sleep_Flag==1)&&(ADC_IN==1))
{
Charge_flag=1;
Wake_up_init();
ONOFF=1;
}
else
{
ONOFF=0;
CKOCON = 0B00000000;
INTCON=0;
PIR1=0;//慢时钟测量完成中断标志位,
EPIF0=0XFF;
EPIE0=0B10000001;//只有充电口和电源开关能唤醒;//EPIE0=0B10001111;//EPIE0=0B10000001;
PEIE= 1;//打开外设中断
if(ONOFF_KEY_IN==1)// 1.l暂时未发现死?
{
NOP();
NOP();
NOP();
NOP();
SLEEP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
PEIE= 0;
EPIE0=0;
delay_us(1);
if(ADC_IN==1)
{
Charge_flag=1;
Wake_up_init();
ONOFF=1;
DYP_POWER=0;
}
else
{
if(ONOFF_KEY_IN==0)//
{
Charge_flag=0;
Wake_up_init();
ONOFF=1;
DYP_POWER=0;
}
}
}
else//2.加上没有死机
{
Charge_flag=0;
Wake_up_init();
ONOFF=1;
DYP_POWER=0;
}
}
}