休眠后会自己被唤醒
// TT-002休眠后自己被唤醒#include "STC8Hxxx.h"
// 引脚定义
sbit Battery_voltage_ADC = P1^0;
sbit Motor_voltage_ADC = P1^1;
sbit motor_switch = P1^3;
sbit PWMB_Signal = P5^4;
sbit TK = P3^7;
sbit LEDR = P3^6;
sbit LEDG = P3^5;
sbit LEDB = P3^4;
sbit sheet_switch = P3^3;
sbit base = P3^2;
sbit charge_switch = P3^1;
sbit Sheet_Current_ADC = P3^0;
// 宏定义
#define MAIN_Fosc 30000000L
// 全局变量
u16 xdata TK_cnt;
u16 xdata TK_zero;
u16 code T_KeyPress = {1300,2000,900,800,900,1000,1100,1400,1000,1200,900,1200,750,900,1300,10000};
u16 code T_KeyState = {0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
bitB_TK_Lowpass = 0;
bitWakeup_FirstScan = 0;
u8 ch;
u8 read_cnt = 0;
u8 i;
u16KeyState = 0;
// 延时函数
void delay_ms(u8 ms)
{
u16 i;
do { i = MAIN_Fosc / 10000; while(--i); } while(--ms);
}
// 触摸初始化(仅上电时用)
void TK_Init(void)
{
TSCHEN1 = 0x00;
TSCHEN2 = 0x80;
TSCFG1= (7<<4) + 6;
TSCFG2= 1;
TSRT = 0x00;
TSWUTC= 255;
IE2 |= 0x80;
IRC32KCR = 0x80;
while(!(IRC32KCR & 1));
delay_ms(50);
B_TK_Lowpass = 0;
for(read_cnt=0; read_cnt<10; read_cnt++)
{
TSCTRL = (1<<7) + (1<<6);
delay_ms(50);
}
for(i=0; i<16; i++) TK_zero = TK_cnt;
B_TK_Lowpass = 1;
KeyState = 0;
TSTH15 = TK_zero - T_KeyPress/2;
}
// Timer0 初始化
void Timer0_Init(void)
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TL0 = 0x2C; //设置定时初始值
TH0 = 0xCF; //设置定时初始值
TF0 = 0;
TR0 = 1;
ET0 = 1;
}
// 唤醒
void IO_Wakeup(void)
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
TSCTRL = (1<<7) + (1<<3) + (1<<2); // 重开触摸模块
P3M0 = 0x7a; P3M1 = 0x85; P3IE = 0x04;
P5M0 |= 0x10; P5M1 &= ~0x10; P5IE &= ~0x10;
P1M0 = (P1M0 & ~0x03) | 0x08;
P1M1 = (P1M1 & ~0x08) | 0x03; P1IE &= ~0x0b;
motor_switch = 0;
sheet_switch = 0;
PWMB_Signal= 0;
charge_switch = 0;
LEDR = 0; LEDB = 0; // 蓝灯灭,表示已唤醒
for(i=0; i<16; i++) TK_zero += 300;
B_TK_Lowpass = 1;
Wakeup_FirstScan = 1;
KeyState = 0;
}
// 进入休眠
void IO_Sleep(void)
{
P5M0 &= ~0x10; P5M1 |= 0x10;
P1M0 &= ~0x0b; P1M1 |= 0x0b;
P3M0 = 0x00; P3M1 = 0xff;
TSCTRL = (1<<3) + (1<<2);
}
// 主函数
void main(void)
{
P_SW2 |= 0x80;
EA = 1;
charge_switch = 0; sheet_switch = 0;
LEDR = 1; LEDG = 0; LEDB = 1;
motor_switch = 0; PWMB_Signal = 0;
P3M0 = 0x7a; P3M1 = 0x85; P3IE = 0x04;
P5M0 |= 0x10; P5M1 &= ~0x10; P5IE &= ~0x10;
P1M0 = (P1M0 & ~0x03) | 0x08;
P1M1 = (P1M1 & ~0x08) | 0x03; P1IE &= ~0x0b;
IRCDB = 0x10;
IAP_TPS = 0x30;
TK_Init();
Timer0_Init();
IO_Sleep();
PCON |= 0x02; // 进入Power-down
IO_Wakeup(); // 触摸唤醒后从这里继续
while(1)
{
if(KeyState & 0x8000) LEDG = 1; // K15按下(含长按)时灯常亮
else LEDG = 0; // 释放时灯灭
}
}
// 触摸中断服务
void TKSU_ISR(void) interrupt TKSU_VECTOR
{
if(TSSTA2 & 0x40) TSSTA2 |= 0x40;
if(TSSTA2 & 0x80)
{
TSSTA2 |= 0x80;
ch = TSSTA1 & 0x0F;
if(!B_TK_Lowpass) TK_cnt = TSDAT;
else TK_cnt = (TK_cnt >> 1) + (TSDAT >> 1);
}
}
// Timer0 中断(5ms)
void Timer0_Isr(void) interrupt 1
{
TSCTRL = (1<<7) + (1<<6); // 触发下一次扫描
if(Wakeup_FirstScan)
{
Wakeup_FirstScan = 0;
for(i=0; i<16; i++) TK_zero = TK_cnt + 80;
TSTH15 = TK_zero - T_KeyPress/2;
return;
}
if(++read_cnt >= 3)
{
read_cnt = 0;
for(i=0; i<16; i++)
{
if(TK_zero > TK_cnt)
{
if((TK_zero - TK_cnt) >= T_KeyPress/4)
KeyState |=T_KeyState;
else if((TK_zero - TK_cnt) <= T_KeyPress/8)
KeyState &= ~T_KeyState;
}
else
{
KeyState &= ~T_KeyState;
if((TK_cnt - TK_zero) > 100) TK_zero += 100;
else TK_zero += 10;
}
}
}
}用的STC8H1K17T
之前的触摸按键长按虽然可以用了
但是发现一个方便的方案把原有的
if(TK_zero > TK_cnt)
{
if((TK_zero - TK_cnt) >= T_KeyPress/4)
KeyState |=T_KeyState;
else if((TK_zero - TK_cnt) <= T_KeyPress/8)
KeyState &= ~T_KeyState;
}原先是/2 /3 通过修改为/4 /8 且屏蔽TK_zero--;以后 可以做到长按-即使长时间触摸仍然是正常的
但是随之移植到程序中出现一个问题,查询了规格书,STOP模式只能被中断或者触摸唤醒
但是实际的过程中当我看到指示灯亮起后 熄灭进入休眠模式 设备竟然能够自己唤醒 换设备 换芯片 仍然会有这个问题 怀疑是程序中某项配置的问题
但是对比了以往的休眠方式是一致的
即使有问题 STOP模式应该也无法自动唤醒才对
用回以前休眠的程序却能解决问题 是不是触摸的配置不能这么修改呢
页:
[1]