在停机状态,用外中断来唤醒时,只能唤醒一次,为什么这样?????????? #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; //关中断 } |
从零开始操作STM8寄存器(风驰iCreate奉献)
【中文资料】初学STM8库函数的中文帮助软件
绝对经典的中文STM8学习手册,淘宝上学习板资料,友情大放送!
【原创教程】风驰iCreate独家开源STM8 27个例程和10多万字的pdf教程
STM8的LCD1602 4线驱动,为什么不工作
【精华资料】由零开始开发STM8
STM8S 的触摸库是如何在主程序中查询键的呢、
【精华资料】STM8的C语言编程1-14讲完整版
【精品教程】STM8系列单片机入门教程系列
STM8 第一次进中断不准【悬赏问答】
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;
}
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);
}
你的程序延时时间太短,或许你根本看不到现象。下面是我根据你的大致意思写的一段代码,亲测可用。
实现功能如下:
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;
}
RE:STM8外中断唤醒有问题
RE:STM8外中断唤醒有问题
RE:STM8外中断唤醒有问题
RE:STM8外中断唤醒有问题
RE:STM8外中断唤醒有问题
回复:STM8外中断唤醒有问题
没有清除中断标志吧STM8S没有中断标志啊
回复:STM8外中断唤醒有问题
调试下看看程序跑到哪儿去了,是后来一直卡死在中断里面么
都唤不醒了,哪知道程序跑到哪了
RE:STM8外中断唤醒有问题
回复:STM8外中断唤醒有问题
你程序对中断不起作用了吗
是啊,只能唤醒一次,我也搞不明白什么意思
#include "iostm8s003f3.h"
if (temp>20)
这都是什么东东?
大侠,你能唤醒几次啊
开定时器试试,还能唤醒不