用的是stm8s103f3p6芯片,
外部按键并上拉电阻,用的是PD5口,设置PD5为浮空输入。
内部用了定时器4,手册显示定时器4功耗最低,16分频,系统时钟是HSI默认8分频2M,定时器16分频就是125k,做了1ms中断,定时器工作正常。
外部中断相应后查看是刚唤醒还是要执行停机操作,因为我是一个按键控制开关机的,开机后控制电机和指示灯
停机功耗30ua,
在不断开关过程中,偶尔会出现刚唤醒就又停机了,或者刚执行停机就自己又醒来了,我在外部中断程序中去了按键抖动了,不知道问题在哪里,请大侠们指点,下面是我的代码
/* -------------------------------------------------------------------------- */
/* ROUTINE NAME: GPIO_Init */
/* INPUT/OUTPUT: None. */
/* DESCRIPTION: Initialize GPIOs. */
/* IN: None. */
/* OUT: None. */
/* -------------------------------------------------------------------------- */
void GPIO_Init(void)
{
PA_DDR = 0xff; //all output
PA_CR1 = 0x00;//OD
PA_CR2 = 0X00;//disable interrupt
PB_DDR = 0xff;//all output
PB_CR1 = 0X00;//OD
PB_CR2 = 0X00;//disable interrupt
PC_DDR = 0xff;
PC_CR1 = MOTOR_IO;//motor PP
PC_CR2 = 0X00;
PD_DDR = 0xff & ~KEY;
PD_CR1 = 0;
PD_CR2 = 1 << 5;//key2 enable ex interrupt
PA_ODR = 0x00;
PB_ODR = power_IO;//power is high
PC_ODR = LED_BIT0 | LED_BIT1;
PD_ODR = KEY;
}
/* -------------------------------------------------------------------------- */
/* ROUTINE NAME: CLK_Init */
/* INPUT/OUTPUT: None. */
/* DESCRIPTION: Initialize the clock source */
/* -------------------------------------------------------------------------- */
void CLK_Init(void)
{
/* Configure HSI prescaler*/
CLK_PCKENR1 = 1 << 4;//除了timer4,其他外设时钟全部关闭
CLK_PCKENR2 = 0x00;
CLK_CKDIVR = 0x018; /* 默认选项,内部RC16M,8分频*/
/* Configure CPU clock prescaler */
//CLK_CKDIVR |= 0x01; /* 001: fCPU=fMASTER/2. */
}
/* -------------------------------------------------------------------------- */
/* ROUTINE NAME: TIM_Init */
/* INPUT/OUTPUT: None. */
/* DESCRIPTION: Initialize the TIM4. */
/* -------------------------------------------------------------------------- */
void TIM4_Init(void)
{
TIM4_ARR = 125;//1ms 125*8=1000
TIM4_PSCR = 0x04; /*16分频,125K 计数加一=8us */
TIM4_IER |= 0x01; //enable
TIM4_CR1 |= 0x01; //开始计数
}
//主函数
void main(void)
{
uchar key,i;
unsigned char *state;
//设置一个存储地址
state = (unsigned char *)0x4000;
CLK_Init(); //初始化时钟
GPIO_Init(); //初始化io
TIM4_Init(); //初始化定时器2
//EXTI_CR1 = 0x80; //外部中断只在下降沿触发
_asm("rim");
if(system_state == 0)//通电默认停机状态
{
LED0_OFF;//关闭所有设备
LED1_OFF;
MOTOR_OFF;
MOTOR_POWER_OFF;
_asm("halt"); //进入停机
}
while (1)
{}
/*******************D口外部中断*******************************/
@far @interrupt void EXTI3_Interrupt(void)
{
uint i = 50000;
while((PD_IDR & (1 << 5)) == 0);//等待按键抬起
while(i--);//延时50ms去抖动
if(system_state == 0)//刚唤醒
{
system_state = 1;//将系统状态位标志位run
MOTOR_POWER_ON;
MOTOR_ON;
LED0_ON;//默认高速
LED1_OFF;
halt_bit = 0;
}
else//执行停机操作
{
LED0_OFF;//关闭所有设备
LED1_OFF;
MOTOR_OFF;
MOTOR_POWER_OFF;
//halt_bit = 1; //标记准备停机,在中断外执行
system_state = 0; //将系统状态位标志位halt
_asm("halt");
}
return;
}
/*******************定时器4中断 1ms*******************************/
@far @interrupt void TIM4_Interrupt (void)
{
TIM4_SR=0x00;//清除中断标志位
} |