你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8外中断唤醒有问题

[复制链接]
hificwc-319059 提问时间:2014-7-16 18:02 /
在停机状态,用外中断来唤醒时,只能唤醒一次,为什么这样??????????
 

#include  "iostm8s003f3.h"
#define  nop() asm("nop")
#define K1  PD_IDR_IDR4  //按键
#define LED PD_ODR_ODR2  //LED指示,低亮
void delay(unsigned char i)
{
 unsigned char j;
 j=255;
 while(i--)
 {
  while(j--);
 }
}
void main()
{
 unsigned char temp;
 delay(10);
 PD_CR1 |= 0x10;  //PD4上拉输入
 PD_CR1 |= 0x4;  //
 PD_DDR |= 0x4;  //PD2设置为输出 
 LED=0;
 asm("RIM");  //开总中断
  while(1)
 {
  LED=0;//灯亮;
  delay(255);
  while (!K1)
  {
   temp=0;//延时清0
      delay(255);
   LED=!LED;
  }
  temp++;
  if (temp>20)//按键没按下时,延时再停机
  {
   temp=0;
   PD_CR2 |= 0x10;  //开PD4中断
   EXTI_CR1 = 0x80; //PD4下降沿中断;
   LED=1;//关灯
   asm("halt");  //停机
   nop();nop();nop();nop();nop();
   PD_CR2 = 0x0; //   
  }
 }

#pragma vector=0x08//
__interrupt void EXTI_PD()//PD外中断
{
 nop();
 PD_CR2 = 0x0; //关中断    
}
收藏 1 评论22 发布时间:2014-7-16 18:02

举报

22个回答
zhuoyemp4 回答时间:2015-5-13 09:57:20
开定时器照样可以唤醒,实现功能:T2每进中断让PD口输出翻转,10次后进入halt,PB1外部中断唤醒,唤醒时让PC口翻转。看到的现象就是LED以1s间隔闪烁,闪10次后停机,用PB1按键唤醒后PC口输出取反,PD口LED接着闪烁。
void initcpu();
void Init_GPIO(void);
void delay(unsigned char ms);
void  Tim2INIT(void);
unsigned int i;
u8 TIM1S;

int main()
{
      Init_GPIO();  
      initcpu();
        Tim2INIT();
        enableInterrupts();
        while(1)
        {  
          if(TIM1S>10)
             {
               TIM1S=0;
               GPIOD->ODR=0x08;//进入Halt前关掉LED
               GPIOB->CR2=0x02; //PB1使能外部中断
               halt();  //进入halt模式
             }
        }
}

void Init_GPIO(void)
{
  GPIOB->DDR=0x00;
  GPIOB->CR1=0x02;  //PB1上拉输入
  GPIOB->CR2=0x00;  //PB禁止外部中断
  EXTI->CR1 = 0x08;  //PB1下降沿触发
  
  GPIOC->DDR=0x08;
  GPIOC->CR1=0x08;
  GPIOC->CR2=0x00;
  GPIOC->ODR=0x00;
  
  GPIOD->DDR=0x08;
  GPIOD->CR1=0x08;
  GPIOD->CR2=0x00;
  GPIOD->ODR=0x00;  //LED低亮
}
void initcpu()
{
       
        //CLK->CKDIVR&= (uint8_t)(~0x18);/*时钟复位*/
        CLK->CKDIVR= (uint8_t)0x01;   /*设置时钟为内部16M高速时钟*/
        disableInterrupts();  //close all interrupt
}


void delay(unsigned char i)
{
  unsigned int j;
  j=65535;
  while(i--)
  {
    while(j--);
  }
}
void  Tim2INIT(void)
{
        CLK->PCKENR1|=0x20;
        TIM2->ARRH=0xf4;
        TIM2->ARRL=0x24;
        TIM2->CNTRH=0x00;
        TIM2->CNTRL=0x00;
        TIM2->PSCR=0x08;//256分频
        TIM2->CR1=0x80;
        TIM2->EGR=0x00;
        TIM2->IER|=0x01;
        TIM2->CR1|=0x01;   
}

INTERRUPT_HANDLER(TIM2_UPD_OVF_TRG_BRK_IRQHandler,13)
{
      TIM2->SR1 &= 0xfe;
          TIM1S++;
       GPIOD->ODR=~GPIOD->ODR;
      return;
       
}

INTERRUPT_HANDLER(EXTI1_IRQHandler,4)  //PB1外部中断
{
       GPIOB->CR2=0x00; //PB禁止外部中断
       GPIOC->ODR=~GPIOC->ODR;
      return;
        
}
apple1 回答时间:2015-5-12 15:06:14
zhuoyemp4 发表于 2015-5-12 08:40
什么意思,你的意思是用定时器唤醒?在Halt模式下,只能通过外部中断唤醒,在active-halt模式下,可以用A ...

MAIN.C file
*
* Copyright (c) 2002-2005 STMicroelectronics
*/

#include "stm8l15x.h"
#include "stm8l15x_tim2.h"
#include "stm8l15x_usart.h"

#define TIM2_PERIOD    999
#define TIM2_PRESCALER   2

int Nms=0,base100us=0;
int Ns=0,base1ms=0;
_Bool  LEDFLAG;



void SYSCLK_Config(void)
{
   CLK->SWR=0x01;
   CLK->CKDIVR=0x02;         //16MHz /64       
}
void UART_CONFIG(void)
{
   
       
        CLK->PCKENR1|=0x20;

        USART_Init(USART1,9600,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_Mode_Tx|USART_Mode_Rx);
    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        USART1->CR1 &= (uint8_t)(~USART_CR1_USARTD);


}
void TIM2_Config(void)
{
     u16 TIM2_Period;  
         TIM2_Period=TIM2_PERIOD;
         CLK->PCKENR1|=0x01;
         TIM2->ARRH = (uint8_t)(TIM2_Period >> 8) ;
         TIM2->ARRL = (uint8_t)(TIM2_Period);
         /* Set the Prescaler value */
         TIM2->PSCR = (uint8_t)TIM2_PRESCALER;
         /* Select the Counter Mode*/
         TIM2->CR1 &= (uint8_t)((uint8_t)(~TIM_CR1_CMS)) & ((uint8_t)(~TIM_CR1_DIR));
         TIM2->CR1 |= (uint8_t)(TIM2_CounterMode_Up);
         /* Generate an update event to reload the Prescaler value immediately */
         TIM2->EGR = TIM2_EventSource_Update;
         TIM2->IER |= (uint8_t)TIM2_IT_Update;//ENABLE IT
        TIM2->CR1 |= 0x01;

}

main()
{
        SYSCLK_Config();
        TIM2_Config();
        UART_CONFIG();
        CFG->GCR=0x00;
        GPIOB->DDR=0X02;
        GPIOB->CR1=0X06;
GPIOB->CR2=0X06;// allow pb2  trige  interrupter
        _asm("rim");
GPIOB->ODR|=0X02;
Ns=0;
while (1)
        {
               
               
if(LEDFLAG)GPIOB->ODR|=0X02;
else GPIOB->ODR&=~0X02;
if(Nms>1000)
{
        Nms=0;
printf("\r \n main fun running");
}

if(Ns>5)
{
        Ns=0;
        printf("\r\n halt");
        GPIOB->CR2|=0X04;
        GPIOB->ODR&=~0X02;
        _asm("halt");
}


}
}
@far @interrupt void TIM2_1ms_interrupter (void)
{
       TIM2->SR1=0X00;

//LEDFLAG=~LEDFLAG;
                   Nms++;
                base1ms++;
           if(base1ms==1000)
                   {
LEDFLAG=~LEDFLAG;
                   base1ms=0;
                Ns++;
                   }
         
}

@far @interrupt void PB2_interrupter(void)
{
          EXTI->SR1&=~0X04;
GPIOB->CR2&=~0X04;



}
char putchar(char c)
{
                  USART_SendData8(USART1, (unsigned char) c);
        while (!(USART1->SR & USART_FLAG_TXE));
       
        return (c);
}
zhuoyemp4 回答时间:2015-5-9 13:54:46
本帖最后由 zhuoyemp4 于 2015-5-9 14:26 编辑

你的程序延时时间太短,或许你根本看不到现象。下面是我根据你的大致意思写的一段代码,亲测可用。
实现功能如下:
LED闪烁10次,
使能PB1外部中断,
LED灭,
进入Halt模式,(LED是灭的状态,不会闪,直到有外部中断唤醒后又闪烁)

这时候可通过PB1口的按键唤醒MCU,
按一次按键进入外部中断服务程序,禁止外部中断,
LED亮,
延时,
LED灭,
延时,中断服务程序返回;
LED亮,
长延时
LED灭
长延时;

一次唤醒结束;

#include "stm8s_conf.h"
#define K1  (GPIOB->IDR&0x02)  //按键PB1

void initcpu();
void Init_GPIO(void);
void delay(unsigned char i);
unsigned int temp;
int main( )
{
        initcpu();
        Init_GPIO();
        while(1)
        {


            GPIOD->ODR=~GPIOD->ODR;
            delay(10);
            GPIOD->ODR=~GPIOD->ODR;
            delay(10);


          if(K1)
          {
            delay(10);
            temp++;
            if(temp>=10)
            {
                temp=0;
               GPIOD->ODR=0x08;//进入Halt前关掉LED
               GPIOB->CR2=0x02; //PB1使能外部中断
               halt();  //进入halt模式
               GPIOD->ODR=~GPIOD->ODR;
               delay(200);
               GPIOD->ODR=~GPIOD->ODR;
               delay(200);
            }
          }

        }
}

void Init_GPIO(void)
{
  GPIOB->DDR=0x00;
  GPIOB->CR1=0x02;  //PB1上拉输入
  GPIOB->CR2=0x00;  //PB禁止外部中断
  EXTI->CR1 = 0x08;  //PB1下降沿触发

  GPIOD->DDR=0x08;
  GPIOD->CR1=0x08;
  GPIOD->CR2=0x00;
  GPIOD->ODR=0x00;  //LED低亮
}
void initcpu()
{
        
        CLK->CKDIVR&= (uint8_t)(~0x18);/*时钟复位*/
        CLK->CKDIVR|= (uint8_t)0x00;   /*设置时钟为内部16M高速时钟*/
        enableInterrupts();
}


void delay(unsigned char i)
{
unsigned int j;
j=65535;
while(i--)
{
  while(j--);
}
}

INTERRUPT_HANDLER(EXTI1_IRQHandler,4)  //PB1外部中断
{
            GPIOB->CR2=0x00; //PB禁止外部中断
            GPIOD->ODR=~GPIOD->ODR;
            delay(50);
            GPIOD->ODR=~GPIOD->ODR;
            delay(50);

      return;
        
}

巅峰残狼 回答时间:2014-7-17 16:34:47

RE:STM8外中断唤醒有问题

你初始化的时候开的是总中断,一次外部中断触发之后你关闭了中断,那下次再触发按键的时候总中断开了吗?你把开总中断这一步放到第一个while大循环中试试
hificwc-319059 回答时间:2014-7-20 10:26:52

RE:STM8外中断唤醒有问题

总中断开了又没关,不可能外中断后,总中断自动关了吧??
zykzyk-93033 回答时间:2014-7-20 10:54:43

RE:STM8外中断唤醒有问题

没有清除中断标志吧
有缘于你 回答时间:2014-7-20 18:36:27

RE:STM8外中断唤醒有问题

调试下看看程序跑到哪儿去了,是后来一直卡死在中断里面么
feixiang20 回答时间:2014-7-23 02:32:45

RE:STM8外中断唤醒有问题

一般不会自动中断或关闭吧
hificwc-319059 回答时间:2014-7-23 09:20:42

回复:STM8外中断唤醒有问题

回复第 4 楼 于2014-07-20 10:54:43发表:
没有清除中断标志吧STM8S没有中断标志啊 
hificwc-319059 回答时间:2014-7-23 09:21:29

回复:STM8外中断唤醒有问题

回复第 5 楼 于2014-07-20 18:36:27发表:
调试下看看程序跑到哪儿去了,是后来一直卡死在中断里面么
 
都唤不醒了,哪知道程序跑到哪了
 
aaa999kk 回答时间:2014-7-24 15:57:39

RE:STM8外中断唤醒有问题

你程序对中断不起作用了吗
hificwc-319059 回答时间:2014-7-25 10:42:37

回复:STM8外中断唤醒有问题

回复第 9 楼 于2014-07-24 15:57:39发表:
你程序对中断不起作用了吗
 
是啊,只能唤醒一次,我也搞不明白什么意思
 
apple1 回答时间:2015-5-8 17:35:47
楼主解决了吗
zhuoyemp4 回答时间:2015-5-9 10:27:26
怎么你的代码这么奇葩呢?
#include  "iostm8s003f3.h"
if (temp>20)
这都是什么东东?
apple1 回答时间:2015-5-11 20:28:25
zhuoyemp4 发表于 2015-5-9 13:54
你的程序延时时间太短,或许你根本看不到现象。下面是我根据你的大致意思写的一段代码,亲测可用。
实现功 ...

大侠,你能唤醒几次啊
apple1 回答时间:2015-5-11 20:29:55
zhuoyemp4 发表于 2015-5-9 13:54
你的程序延时时间太短,或许你根本看不到现象。下面是我根据你的大致意思写的一段代码,亲测可用。
实现功 ...

开定时器试试,还能唤醒不
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版