关于STC8A8K64D4省电模式不能唤醒求教
#include "stc8a8k64d4.h"#define MAIN_Fosc 45000000 //定义主时钟
#define Timer0_Reload (MAIN_Fosc / 1000) //Timer 0 中断频率, 1000次/秒
#defineBacklightDelayDefaultValue 10
#define LCD_LED P50
int time1s = 0;
int BacklightDelay;
//========================================================================
// 函数: void delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2021-3-9
// 备注:
//========================================================================
void delay1ms(u16 ms)
{
u16 i;
do
{
i = MAIN_Fosc / 10000;
while(--i); //10T per loop
}
while(--ms);
}
void GPIO_Init()
{
LCD_LED = 0;
P0M0 = 0x80;
P0M1 = 0x66; //P01、P02、P05、P06模拟输入 P07推挽输出
P1M0 = 0x01;
P1M1 = 0x08; //P13模拟输入 P10推挽输出
P2M1 = 0x00;
P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00;
P3M0 = 0x00; //设置为准双向口
P4M0 = 0x00;
P4M1 = 0x00; //P43推挽输出
P5M0 = 0x01;
P5M1 = 0x00; //P50推挽输出,设置为准双向口
P6M1 = 0x00;
P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00;
P7M0 = 0x00; //设置为准双向口
}
//========================================================================
// 函数: void Timer0_init(void)
// 描述: timer0初始化函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void Timer0_init(void)
{
TR0 = 0; //停止计数
#if (Timer0_Reload < 64) // 如果用户设置值不合适, 则不启动定时器
#error "Timer0设置的中断过快!"
#elif ((Timer0_Reload/12) < 65536UL) // 如果用户设置值不合适, 则不启动定时器
ET0 = 1; //允许中断
//PT0 = 1; //高优先级中断
TMOD &= ~0x03;
TMOD |= 0;//工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
//TMOD |=0x04;//对外计数或分频
TMOD &= ~0x04;//定时
//INT_CLKO |=0x01;//输出时钟
INTCLKO &= ~0x01;//不输出时钟
#if (Timer0_Reload < 65536UL)
AUXR |=0x80;//1T mode
TH0 = (u8)((65536UL - Timer0_Reload) / 256);
TL0 = (u8)((65536UL - Timer0_Reload) % 256);
#else
AUXR &= ~0x80;//12T mode
TH0 = (u8)((65536UL - Timer0_Reload / 12) / 256);
TL0 = (u8)((65536UL - Timer0_Reload / 12) % 256);
#endif
TR0 = 1; //开始运行
EA =1;
#else
#error "Timer0设置的中断过慢!"
#endif
}
//========================================================================
// 函数: void SetWakeUpTime(u16 SetTime)
// 描述: 唤醒定时器设置时间值函数。
// 参数: SetTime: 要设置的时间值(睡眠的时间), 单位为ms.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-7-15
// 备注:
//========================================================================
void SetWakeUpTime(u16 SetTime)
{
if(SetTime >= 16000) SetTime = 15999; //限制最大值
SetTime = (u16)(((u32)SetTime * 32768) / 16000); //重装值 = Fwkt/16 * SetTime/1000 = Fwkt * SetTime / 16000
if(SetTime > 0) SetTime--;
WKTCL = (u8)SetTime;
WKTCH = (u8)(SetTime >> 8) | 0x80;
}
/******************** 主函数 **************************/
void main(void)
{
GPIO_Init();
BacklightDelay = BacklightDelayDefaultValue;
Timer0_init();
LCD_LED = 1;;//点亮背光
while(1)
{
if(BacklightDelay)
{
if(!LCD_LED)
{
LCD_LED = 1;
}
}
else
{
if(LCD_LED)
{
LCD_LED = 0;
}
SetWakeUpTime(10000); //时间值 ms, 小于16000
while(!P32); //等待外中断为高电平
delay1ms(10); //delay 10ms
IE0= 0; //外中断0标志位
IT0 = 1; //INT0 下降沿中断
EX0 = 1; //INT0 Enable
EA= 1; //Enable all interrupt
PCON |= 0x02; //Sleep
_nop_();
_nop_();
_nop_();
_nop_();
EX0 = 0; //INT0 Disable
BacklightDelay = BacklightDelayDefaultValue;
}
}
}
/********************* INT0中断函数 *************************/
void INT0_int (void) interrupt 0 //进中断时已经清除标志
{
}
//========================================================================
// 函数: void timer0_int (void) interrupt TIMER0_VECTOR
// 描述:timer0中断函数.
// 参数: none.
// 返回: none.
// 版本: V1.0, 2015-1-12
//========================================================================
void timer0_int(void) interrupt 1
{
time1s++;
if (time1s>=1000)
{
time1s=0;
if(BacklightDelay)
BacklightDelay--;
}
}
要实现的功能就是10s钟后关闭背光,10秒钟后掉电唤醒背光,唤醒10秒,或者外部按键唤醒10秒,然后再次进入休眠状态。烧录板子调试的时候发现10秒钟后能进入睡眠状态,但是10秒钟后掉电唤醒不能正常唤醒,电流下降的1ma以下;如果这个时候用外部触发唤醒,电流上升到6ma,但是10秒钟后不会再次进入睡眠状态(电流还是6ma)。 如果屏蔽掉外部中断唤醒,程序能正常10秒钟亮屏然后进入睡眠,10秒后唤醒,正常循环工作 10秒,唤醒,用带RTC功能的 STC8H8K64U
另外刚看到,你跑的是 40MHz
神农鼎 发表于 2024-3-21 12:25
10秒,唤醒,用带RTC功能的 STC8H8K64U
我需要的不是准确的10秒唤醒,1到10秒都可以;现在遇到的问题是掉电唤醒定时器和外部中断唤醒一起用到时候,程序就跑飞了 #define MAIN_Fosc 45000000 //定义主时钟
1, 将上面的等待时间设到最长时间
2, 将下面的 NOP 等待时间设到最长时间
PCON |= 0x02; //Sleep
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
神农鼎 发表于 2024-3-21 12:32
#define MAIN_Fosc 45000000 //定义主时钟
PCON |= 0x02; //Sleep
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
EX0 = 0; //INT0 Disable
BacklightDelay = 3;//BacklightDelayDefaultValue; 新修改的地方
加了几个空操作后,确实是掉电唤醒定时器和外部中断都能唤醒,但是出现了新的问题:通过掉电唤醒定时器唤醒系统时,再次进入睡眠的时间是3秒;通过外部中断唤醒系统时,再次进入睡眠的时间是10秒,也就是说系统没进行到BacklightDelay = 3;这一步,直接是重新运行了。不知道我表达是否清楚了,这是怎么回事呢? 329008861 发表于 2024-3-21 14:21
PCON |= 0x02; //Sleep
_nop_();
_nop_();
/********************* INT0中断函数 *************************/
void INT0_int (void) interrupt 0 //进中断时已经清除标志
{
_nop_();
_nop_();
_nop_();
............
}
在外部中断里加了一堆空操作后程序正常运行了,感谢大神的解答 看来中断唤醒后要给点时间让设备回复正常
页:
[1]
2