HyunYong_7782 发表于 2025-11-25 10:38:07

休眠后会自己被唤醒

// 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]
查看完整版本: 休眠后会自己被唤醒