小蹦蹦 发表于 2025-3-5 02:29:47

【已解决】求救!8H2K17U,普通IO无法唤醒STOP模式 | 已解决!

大神求救!
问题是这样的,我用的是8H2K17U,手册上写的是支持I/O 中断唤醒功能,我使用P1.4、P1.5、P1.6三个IO口,上拉到VCC,按下按键后到GND,预期目标是在没有按键按下的时候单片机保持在STOP模式下,当按下按键后唤醒单片机串口发送键值,发完键值后继续进入STOP模式。配置了P1IM1 = 0x00;   P1IM0 = 0x00;(下降沿)P1WKUE = 0x70;,在进入STOP模式后,按键无法唤醒,不知道是为啥,下面贴上代码,大神帮看看,谢谢!

IO配置代码:
void App_GPIO_Init_Work(void)//全部引脚工作
{
/************************设置IO口工作模式*******************************/
    P0M1 = 0xFF;   P0M0 = 0x00;   //设置P0口为高阻输入
    P1M1 = 0xFF;   P1M0 = 0x70;   //设置P1口为部分开漏,部分高阻输入
      /*   B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PnM1111111110xFF */
      /*PnM0011100000x70 */
      /*   阻 漏 漏 漏 阻 阻 阻 阻       */
    P2M1 = 0xFF;   P2M0 = 0x00;   //设置P2口为高阻输入
    P3M1 = 0x1F;   P3M0 = 0x08;   //设置P3口为部分高阻输入,部分准双向口
      /*   B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PnM1000111110x1F */
      /*PnM0000010000x08 */
      /*   双 双 双 阻 漏 阻 阻 阻       */
    P4M1 = 0xFF;   P4M0 = 0x00;   //设置P4口为高阻输入
    P5M1 = 0xFF;   P5M0 = 0x00;   //设置P5口为高阻输入
/************************设置数字信号输入使能**************************/
    P0IE = 0x00;
    P1IE = 0x70;
      /*   B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PnIE011100000x70 */
      /*   否 能 能 能 否 否 否 否       */
    P2IE = 0x00;
    P3IE = 0xE0;
      /*   B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PnIE111000000xE0 */
      /*   能 能 能 否 否 否 否 否       */
    P4IE = 0x00;
    P5IE = 0x00;
    CE = 0;
}

void App_GPIO_Init_Sleep(void)//休眠状态
{
/************************设置IO口工作模式*******************************/
    P0M1 = 0xFF;   P0M0 = 0x00;   //设置P0口为高阻输入
    P1M1 = 0xFF;   P1M0 = 0x70;   //设置P1口为部分开漏,部分高阻输入
      /*   B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PnM1111111110xFF */
      /*PnM0011100000x70 */
      /*   阻 漏 漏 漏 阻 阻 阻 阻       */
    P2M1 = 0xFF;   P2M0 = 0x00;   //设置P2口为高阻输入
    P3M1 = 0xFF;   P3M0 = 0x00;   //设置P3口为高阻输入
    P4M1 = 0xFF;   P4M0 = 0x00;   //设置P4口为高阻输入
    P5M1 = 0xFF;   P5M0 = 0x00;   //设置P5口为高阻输入
/************************设置数字信号输入使能**************************/
    P0IE = 0x00;
    P1IE = 0x00;
    P2IE = 0x00;
    P3IE = 0x00;
    P4IE = 0x00;
    P5IE = 0x00;
}

void App_GPIO_Init(void)//IO口中断配置
{
/**************************设置中断模式配置(下降沿)****************************/
    P0IM1 = 0x00;   P0IM0 = 0x00;
    P1IM1 = 0x00;   P1IM0 = 0x00;
    P2IM1 = 0x00;   P2IM0 = 0x00;
    P3IM1 = 0x00;   P3IM0 = 0x00;
    P4IM1 = 0x00;   P4IM0 = 0x00;
    P5IM1 = 0x00;   P5IM0 = 0x00;
/************************设置中断掉电唤醒使能*************************/
    P0WKUE = 0x00;
    P1WKUE = 0x70;
      /*       B7 B6 B5 B4 B3 B2 B1 B0       */
      /*PNWKUE011100000x70 */
      /*       否 能 能 能 否 否 否 否       */
    P2WKUE = 0x00;
    P3WKUE = 0x00;
    P4WKUE = 0x00;
    P5WKUE = 0x00;
/****************************设置中断使能******************************/
    P0INTE = 0x00;
    P1INTE = 0x70;
      /*       B7 B6 B5 B4 B3 B2 B1 B0       */
      /*P1INTE011100000x70 */
      /*       否 能 能 能 否 否 否 否       */
    P2INTE = 0x00;
    P3INTE = 0x00;
    P4INTE = 0x00;
    P5INTE = 0x00;
   
    P1INTF = 0x00;//清中断标志
    EA = 1;
}

//由于中断向量大于 31,在 KEIL 中无法直接编译
//必须借用第 13 号中断入口地址
void common_isr() interrupt 13
{
    if (P1INTF & 0x10)//P1.4-K1上翻中断
    {
      B_Alarm = 1;
      key = 1;
    }
    if (P1INTF & 0x20)//P1.5-K2首页中断
    {
      B_Alarm = 1;
      key = 2;
    }
    if (P1INTF & 0x40)//P1.6-K3下翻中断
    {
      B_Alarm = 1;
      key = 3;
    }
    P1INTF = 0x00;//清中断标志
}


main代码:
#define MAIN_Fosc5529600L   //定义主时钟
#define CE         P35      //无线模块片选,高电平或悬空SLEEP,低电平唤醒
#define LED      P33      //LED灯,0亮,1不亮
#define K1         P14
#define K2         P15
#define K3         P16

bit B_Alarm = 0;       //唤醒标志,1醒,0没醒
unsigned char key = 0; //哪个按键按下,0没有,1=K1,2=K2,3=K3
unsigned char send = 0; //发送键值标志,1发送了,0没发送
/********************** 主函数 ************************/
void main(void)
{
    Delay_ms(10);
    BSP_Configuration();//硬件驱动初始化函数
    LED = 1;
    Delay_ms(10);
    App_STC8_Sleep();//开始休眠

    while(1)
    {
      if(B_Alarm)//休眠醒来
      {
            B_Alarm = 0;//清除休眠标志
            P1INTE = 0x00;//禁止中断
            App_GPIO_Init_Work();//全部引脚工作
            Delay_ms(100);//等待无线模块醒来
            if(key == 1)
            {
                App_UART1_SendByte(0x01);
            }
            else if(key == 2)
            {
                App_UART1_SendByte(0x02);
            }
            else if(key == 3)
            {
                App_UART1_SendByte(0x03);
            }
            key = 0;//清除键值
            P1INTE = 0x70;//允许中断
            send = 1;//已发送键值
            Delay_ms(100);//等待无线模块发送完
      }
      
      if((K1==0)||(K2==0)||(K3==0))//亮灯
      {
            LED = 0;
      }
      if((K1==1)&&(K2==1)&&(K3==1))//灭灯
      {
            LED = 1;
          if(send == 1)//如果发送了键值才休眠
            {
                send = 0;//清发送标志
                App_STC8_Sleep();//开始休眠
            }
      }
    }
}

void App_STC8_Sleep(void)
{
    _nop_();
    _nop_();
    App_GPIO_Init_Sleep();//休眠前配置引脚
    PCON |= (1<<1);       //进入掉电模式
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
}

/***********************************************************************
*   函 数 Name: BSP_Configuration
*   功能说明: 初始化硬件设备。配置CPU寄存器和外设的寄存器并初始化一些全局变量。
***********************************************************************/
void BSP_Configuration(void)
{
    P_SW2 |= 0x80;
    App_GPIO_Init_Work();//全部引脚工作
    App_GPIO_Init();
    App_UART1_Init();
    EA = 1;//打开总中断
}

国芯人工智能 发表于 2025-3-5 02:33:00

针对您描述的STC8H2K17U无法通过I/O中断唤醒STOP模式的问题,建议从以下几个方面进行排查:

1. **I/O配置**:确保P1.4、P1.5、P1.6已正确配置为输入模式,且上拉电阻正常。检查P1M1和P1M0寄存器,确保设置为准双向或输入模式。

2. **中断配置**:确认P1IM0和P1IM1寄存器已正确配置为下降沿触发。P1IM1 = 0x00; P1IM0 = 0x00; 表示下降沿触发,但需确保其他相关中断设置无误。

3. **唤醒使能**:P1WKUE寄存器应正确使能对应引脚。P1WKUE = 0x70; 已使能P1.4、P1.5、P1.6,但建议检查是否在进入STOP模式前正确设置了该寄存器。

4. **电源管理**:确保STOP模式下的电源管理配置正确,且系统时钟在唤醒后能正常恢复。

5. **硬件检查**:确认按键电路和连接无问题,按键按下时电平确实能拉低到GND。

建议逐步排查上述问题,并确保代码逻辑无误。如有必要,可参考STC官方手册或技术支持进一步确认。

[本文内容由国芯人工智能辅助生成,仅供参考]

小蹦蹦 发表于 2025-3-5 02:37:22

备注掉两句App_STC8_Sleep();的话,按键发送键值是正常的,加上这两句之后,进入STOP模式后就唤醒不了,我测了电流(因为有无线模块,所以电流大一些),不加进入休眠的语句有20多毫安电流(单片机+无线模块一起工作),进入休眠后大概20微安电流(单片机+无线模块一起休眠),按下一个按键大概500微安(单片机+无线模块一起休眠+1个按键上拉电阻接地的电流)

王昱顺 发表于 2025-3-5 06:05:43

小蹦蹦 发表于 2025-3-5 02:37
备注掉两句App_STC8_Sleep();的话,按键发送键值是正常的,加上这两句之后,进入STOP模式后就唤醒不了,我 ...
是这样的,配置休眠前的引脚配置中,错误将所有引脚的数字输入都关闭了。
数字输入关闭后,引脚就不能读取到外部电平了,自然也无法唤醒
修改睡眠前初始化引脚时,保留需要唤醒对应I/O的数字输入即可
同时在唤醒后,需要将所有的I/O的数字输入再恢复,否则都无法读取到外部电平

小蹦蹦 发表于 2025-3-5 13:15:12

王昱顺 发表于 2025-3-5 06:05
是这样的,配置休眠前的引脚配置中,错误将所有引脚的数字输入都关闭了。
数字输入关闭后,引脚就不能读取 ...
已解决!感谢大神!
在休眠引脚配置里把3个按键打开数字信号输入使能后就可以正常唤醒了。
之前没考虑到IO中断也需要数字信号使能,大神不愧是大神,非常感谢
{:4_201:}
页: [1]
查看完整版本: 【已解决】求救!8H2K17U,普通IO无法唤醒STOP模式 | 已解决!