Всем привет!
Может кто придумает или знает как быть с ситуацией.
STC8H1K08 после ухода в Power-down и последующего пробуждения из него по прерыванию INT0 процессор перестаёт вызывать прерывания по векторам

Я тут даже набросал "маленько" кода, который проявляет себя во всей красе. Может я чего не так понимаю и делаю....
Спойлер
Код:
#include <stdio.h>
#include <intrins.h>
#include <STC/STC8H.H>
typedef bit bit_type;
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
typedef signed long int32_t;
static volatile bit_type by_isr = 0;
static volatile uint32_t data SysTick;
#define LED_TOGGLE() P12 ^= 1
#define LED_ON() P12 |= 1
#define LED_OFF() P12 &= ~1
#define BUTTON_PRESSED() (!P32)
#define IE0_VECTOR 0
#define TF0_VECTOR 1
#define INTERRUPT(name, vector) void name(void) interrupt vector
INTERRUPT(INT0_ISR, IE0_VECTOR)
{
by_isr = 1;
//LED_TOGGLE();
}
INTERRUPT(TMR0_ISR, TF0_VECTOR)
{
++SysTick;
//LED_TOGGLE();
}
void Delay200ms(void) //@36.250MHz
{
unsigned char i, j, k;
i = 37;
j = 200;
k = 122;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay50ms(void) //@36.250MHz
{
unsigned char data i, j, k;
i = 10;
j = 50;
k = 220;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
static void Timer0_Init(void) //1ms@36.250MHz
{
AUXR |= 0x80; //Timer clock is 1T mode
TMOD &= 0xF0; //Set timer work mode
TL0 = 0x66; //Initial timer value
TH0 = 0x72; //Initial timer value
TF0 = 0; //Clear TF0 flag
TR0 = 1; //Timer0 start run
ET0 = 1; //Enable timer0 interrupt
}
static void PWMInit(void)
{
EAXSFR();
PWMA_ENO = 0x00;
PWMA_IOAUX = 0x00;
PWMA_CR1 = 0x00;
PWMA_PS = 0xFF;
PWMB_CCER2 &= ~0x30; //CC8P = 0, CC8E = 0
PWMB_CCMR4 = 0x60; //OC8M = 110 - PWM Mode 1
PWMB_CCER2 = 0x10; //CC8E = 1, CC8P = 0
PWMB_CCR8H = 0x19; //???????????
PWMB_CCR8L = 0xEC;
PWMB_ARRH = 0x33; //???????????
PWMB_ARRL = 0xD9; // 500
PWMB_IOAUX &= ~0x40; //AUX8P = 0 - PWM8 output is directly controlled by ENO8P
PWMB_BKR |= 0x80; //MOEB = 1 - Main output enable
PWMB_CR1 &= ~0x01; //CENB = 1 - Enable the counter
EAXRAM();
}
static void Beep(void)
{
EAXSFR();
PWMB_ENO |= 0x40;
PWMB_CR1 |= 0x01;
EAXRAM();
Delay50ms();
EAXSFR();
PWMB_CR1 &= ~0x01;
PWMB_ENO &= ~0x40;
EAXRAM();
}
void main(void)
{
P1 = 0x30;
P1M0 = 0x45;
P1M1 = 0x02;
P3 = 0x02;
P3M0 = 0x12;
P3M1 = 0x0D;
P5 = 0x00;
P5M0 = 0x10;
P5M1 = 0x00;
EAXSFR();
P1PU = 0x00;
P1NCS= 0x02;
P3PU = 0x00;
P3NCS= 0x00;
P5PU = 0x00;
P5NCS= 0x00;
P5IE = 0xff;
IRCBAND = 1; //SEL = 1, 35MHz
XOSCCR = 0;
X32KCR = 0;
if ((HIRCCR & 0x80) == 0)
{
HIRCCR = 0x80; //ENIRC = 1, IRCST = RO.
while ((HIRCCR & 0x01) == 0);
}
CLKDIV = 0; //MCLK/1
CLKSEL = 0x00; //MCKSEL = 00 -> internal high speed high precision IRC
MCLKOCR &= ~0x80; //0xFD; //MCLKO_S = 1 (Main clock output to P1.6), MCLKODIV = 125
// MCLKOCR = 124;
ADCTIM = 0xFF;
EAXRAM();
Timer0_Init();
PWMInit();
EA = 1;
Delay200ms();
Delay200ms();
Delay200ms();
while(1)
{
uint8_t cnt = 15;
while (--cnt)
{
LED_TOGGLE();
Delay200ms();
}
by_isr = 0;
IE0 = 0;
IT0 = 1;
EX0 = 1;
EA = 1;
LED_OFF();
WKTCL = 0xFE;
WKTCH = 0x8F; //4095 ~ 2sec
while(1)
{
NOP(4);
PCON |= 0x02;
NOP(8);
LED_TOGGLE();
if (by_isr || BUTTON_PRESSED())
{
LED_TOGGLE();
//Delay200ms();
break;
}
}
//by_isr = 0;
//LED_TOGGLE();
EA = 0;
EX0 = 0;
IT0 = 0;
IE0 = 0;
EA = 1;
Beep();
Delay200ms();
}
}
Логика простая, после включения моргаем 15 раз диодом и уходим в сон, в ходе которого иногда просыпаемся и моргаем диодом (выходит раз в 2 секунды).
Если во время сна Жамкнуть кнопочку на порту Р3.2, то проц выйдет мгновенно из сна как бы по прерыванию INT0, но в само прерывание он уже не зайдёт, выйдет он в строке
NOP(8); (кстати без NOP() не уходит в сон, 8 подобрано экспериментально, у китайцев в примере 4, у меня с 4мя не спит) и далее по условию
BUTTON_PRESSED() прервёт замкнутый цикл сна, пикнет и снова будет моргать 15 раз и снова по кругу. Так вот второй круг уже по кнопке уже не проснётся, потому что прерывания больше не работают. так же SysTick прерывание больше не вызывается. При этом биты EA - общее разрошение прерываний стоит, а так же флаги IE0 и TF0 тоже в еденице, что должно как бы вызывать переходи к прерываниям, но этого не происходит.
Так вот я нашёл косяк в проце? (Сразу, может кто всречал Errata к ним?) или я всё не так делаю?
Ах да, 1 из 10ти раз вместо выхода из сна, можно получить System Reset, но прерывания тоже не работают в нём.