stm8s跳出中断程序c语言,stm8s103 利用中断判断长按短按,长按可以实现进入低功耗 短按1-2s跳出低功耗进入工作,实际情况是短按立马跳出低功耗,请各位大侠帮忙看看。附程序...

声明

#include  "STM8S103F2P.h"

#define uint  unsigned int

#define uchar unsigned char

#define NGI()          _asm("sim");     /* 禁止全局中断 */

#define EGI()          _asm("rim");     /* 使能全局中断 */

#define BitSet(a,b)    (a |= (1<

#define BitClr(a,b)    (a &= ~(1<

#define BitCpl(a,b)    (a^=1<

#define GetBit(a,b)    (((a)>>(b))&0X01)/* 获取变量a第b位 */

stm8_interrupt.c

#include  "lt101.h"

void   Sun_check(void);

//void light_control(void);

typedef void @far (*interrupt_handler_t)(void);

struct interrupt_vector {

unsigned char interrupt_instruction;

interrupt_handler_t interrupt_handler;

};

@far @interrupt void NonHandledInterrupt (void)

{

/* in order to detect unexpected events during development,

it is recommended to set a breakpoint on the following instruction

*/

return;

}

@far @interrupt void PORTA_Interrupt_IRQHandler (void)

{

key_bit=1;//标志位

}

@far @interrupt void TIM4_UPD_OVF_IRQHandler (void)

{

minisecond++;  //10ms

TIM4_SR &= 0xFE;

if((key_bit==1)&&(GetBit(PA_IDR,3))==0)//按键按下 并且处于低电平

{

counter++;                                    //counter10ms加一次,由此值判断长按短按

}

return;

}

extern void _stext();     /* startup routine */

struct interrupt_vector const _vectab[] = {

{0x82, (interrupt_handler_t)_stext}, /* reset */

{0x82, NonHandledInterrupt}, /* trap  */

{0x82, NonHandledInterrupt}, /* irq0  */

{0x82, NonHandledInterrupt}, /* irq1  */

{0x82, NonHandledInterrupt}, /* irq2  */

{0x82, PORTA_Interrupt_IRQHandler}, /* irq3  */

{0x82, NonHandledInterrupt}, /* irq4  */

{0x82, NonHandledInterrupt}, /* irq5  */

{0x82, NonHandledInterrupt}, /* irq6  */

{0x82, NonHandledInterrupt}, /* irq7  */

{0x82, NonHandledInterrupt}, /* irq8  */

{0x82, NonHandledInterrupt}, /* irq9  */

{0x82, NonHandledInterrupt}, /* irq10 */

{0x82, NonHandledInterrupt}, /* irq11 */

{0x82, NonHandledInterrupt}, /* irq12 */

{0x82, NonHandledInterrupt}, /* irq13 */

{0x82, NonHandledInterrupt}, /* irq14 */

{0x82, NonHandledInterrupt}, /* irq15 */

{0x82, NonHandledInterrupt}, /* irq16 */

{0x82, NonHandledInterrupt}, /* irq17 */

{0x82, NonHandledInterrupt}, /* irq18 */

{0x82, NonHandledInterrupt}, /* irq19 */

{0x82, NonHandledInterrupt}, /* irq20 */

{0x82, NonHandledInterrupt}, /* irq21 */

{0x82, NonHandledInterrupt}, /* irq22 */

{0x82, TIM4_UPD_OVF_IRQHandler}, /* irq23 */

{0x82, NonHandledInterrupt}, /* irq24 */

{0x82, NonHandledInterrupt}, /* irq25 */

{0x82, NonHandledInterrupt}, /* irq26 */

{0x82, NonHandledInterrupt}, /* irq27 */

{0x82, NonHandledInterrupt}, /* irq28 */

{0x82, NonHandledInterrupt}, /* irq29 */

};

MAIN.c

/***************************************************************

**************长按进入停机模式,短按开机*********************

****************************************************************

*******/

//过放电路由硬件实现

#include  "lt101.h"

#include  "cpu_init.h"

void Sun_check(void);     //电压采样

void Free_WWDG(void);     //窗口看门狗

void light_control(void); //闪烁控制函数

uint   minisecond;        //light_control 函数用到的light

uint counter=0;

uchar  sun=0;

uchar  work_state=0;      //等于0时工作,1时停止工作

uint   cycle= 100;        //灯亮灭周期时间1s

uchar  lighting_time= 15; //灯亮持续时间150ms

uchar  key_mode=0;        //按键模式

uchar  key_bit=0;         //标志位

main()

{

NGI();        /*禁止中断*/

CLK_Init();   /*时钟初始化*/

GPIO_Init();  /*端口初始化*/

EXTI_Init();/*外部中断触发方式*/

Tim4_Init();/*定时器初始化*/

ADC_Init();

WWDG_Init();  /*窗口看门狗初始化*/

EGI();

while (1)

{

Free_WWDG();      /*喂狗*/

Sun_check();      /*ADC采样*/

light_control();  /*灯闪烁程序*/if(counter>300)   /*判断按键按下大于3S*/

{

Free_WWDG();      /*喂狗*/

counter=0;        /*清空计数*/

key_bit=0;        /*清空标志位*/

BitClr(PC_ODR,6); /*清空按键*/

key_mode=0;       /*清空按键*/

_asm("halt");     /*进入到低功耗模式*/

FLASH_CR1 = 0x080;

}

if((counter>100)&&(counter<200))/*若按键按下1-2s*/

{

Sun_check();

light_control();

}

}

}/***************************************************************

************** ADC 采样 用来判断白天黑夜的**********************

***************************************************************/

void Sun_check(void)

{

unsigned char i;

unsigned int AD_Value;

ADC_CSR  = 0x05;//选择通道AIN5

ADC_CR1 |= 0x01;         /* First set ADON to power on the ADC module.    */

i = 12;                   /* Wait >7us to ensure the ADC power on finished.*/

while(i--);

ADC_CR1 |= 0x01;         /* Set ADON again to start AD convert.           */

while(!(ADC_CSR & 0x80));/* Waiting for AD convert finished (EOP=1).      */

AD_Value = ((((unsigned int)ADC_DRH)<<2)+ADC_DRL);

if(AD_Value > 25)

sun = 1;

if(AD_Value < 20)

sun = 0;

}

/****************************************************************

*********************灯闪烁控制**********************************

*****************************************************************

****************************************************************/

void light_control(void)

{

if(sun == 0)

{

if(minisecond <= lighting_time)

{

BitSet(PC_ODR,6);//输出高电平,灯亮持续时间lighting_time}

if(minisecond > lighting_time)

{

BitClr(PC_ODR,6);   //输出低电平,灯灭

}

if(minisecond > cycle)          //周期时间cycle

{

Sun_check();minisecond = 0;

}

}

if(sun == 1)                          //检测到白天

{

if(minisecond > 100)

{

BitClr(PC_ODR,6);  //输出低电平

Sun_check();minisecond = 0;

}

}

}

/****************wwdg**************

*************窗口看门狗——喂狗程序**************

***********************************/

void Free_WWDG(void)

{

if((WWDG_CR&0X7F)<=WWDG_WR)//小于窗口值才能喂狗

WWDG_CR|=0X7F;   //重新喂狗

}

初始化函数

#include  "cpu_init.h"

void CLK_Init(void)

{

// CLK_ICKR = 0X08;//enable LSI

CLK_SWCR = CLK_SWCR | 0x02;    // SWEN = 1

CLK_SWR = 0XD2;//chose LSI 128K

while((CLK_SWCR & 0x08) == 0); // 等待切换成功

CLK_SWCR = CLK_SWCR & 0xFD;    // 清除切换

CLK_CKDIVR = 0X00; //Fmaster=128KHZ, Fcpu=128KHZ/128=1k

CLK_PCKENR1 = 0x10;//T4

CLK_PCKENR2 = 0x08;//ADC

}

void GPIO_Init(void)

{

/*PA3:KEY  */

BitClr(PA_DDR,3); //PA3 Input.

BitSet(PA_CR1,3); //

BitSet(PA_CR2,3); //Enable extern interrupt

/*PC3:KEY   */

BitSet(PC_DDR,3); //PC3 Output.

BitSet(PC_CR1,3); //pull up

BitClr(PC_CR2,6); //

/*PC6

tongue.gifOUT*/

BitSet(PC_DDR,6); //PC6 Output.

BitSet(PC_CR1,6); //pull up

BitClr(PC_CR2,6); //

/*PD5:ADC  */

BitClr(PD_DDR,5); //PD5 Input. .

BitClr(PD_CR1,5); //

BitClr(PD_CR2,5); //Output speed up to 2MHz.

}

void Tim4_Init(void)

{

TIM4_IER = 0x00;

TIM4_EGR = 0x01;

TIM4_PSCR =0x03;//128k/8

TIM4_CNTR =0;

TIM4_ARR  =160;

TIM4_CR1 = 0x01;

TIM4_SR &= 0xFE;

TIM4_IER = 0x01;

}

void ADC_Init(void)

{

ADC_CR2  = 0x00;

ADC_CR1  = 0x00;

ADC_TDRL = 0x20;

}

void WWDG_Init(void)

{

//窗口看门狗在计数值降到0x3f时产生复位,而且不能在大于窗口值时喂狗。

//否则复位

WWDG_WR=0x60;      //看门狗窗口值,窗口值必须在0x3F以上,但必须小于计数值,否则无法喂狗

WWDG_CR=0x7F;       //看门狗计数值

WWDG_CR|=0x80;    //使能窗口看门狗

//  128k主频,计数值0x7F 最大延长时间为 (64 * (12288 / 128000)) = 6.14s

//看门狗

}

void EXTI_Init(void)

{

EXTI_CR1=0X02;//PA口下降沿触发

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值