芯启元 发表于 2026-7-3 16:03:00

68-普通IO口中断-休眠唤醒,STC32G144K246实验箱演示程序

68-普通IO口中断-休眠唤醒,STC32G144K246实验箱演示程序
主程序main.C代码如下(汇编版本在附件中):


/*---------------------------------------------------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com-----------------------------------------*/
/*---------------------------------------------------------------------*/

/*************功能说明    **************

本例程基于STC32G144K246为主控芯片的实验箱进行编写测试。

使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。

edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。

显示效果为: 上电后跑马灯显示2秒, 然后进入睡眠模式.

按板上的P32、P33、P34、P35按键唤醒, 继续显示2秒后再进入睡眠模式.

下载时, 选择时钟 48MHz (用户可自行修改频率).

******************************************/

#include "..\..\comm\STC32G144K246.h"

typedef   unsigned char    u8;
typedef   unsigned int    u16;
typedef   unsigned long   u32;

/****************用户定义宏****************/

#define MAIN_Fosc       48000000UL
#define Baudrate      115200L
#define TM            (65536 -(MAIN_Fosc/Baudrate/4))
#define PrintUart       1      //1:printf 使用 UART1; 2:printf 使用 UART2

/****************本地常量声明**************/

u8 code ledNum[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

/****************本地变量声明**************/

u8 ledIndex;
u16 msecond;    //1000ms计数
u8 ioIndex;

/****************本地函数声明**************/

void delay_ms(u16 ms);
void UartInit(void);

/******************** 主函数 **************************/
void main(void)
{
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0x00;   P0M0 = 0xff;   //设置为推挽输出
    P3M1 = 0x3c;   P3M0 = 0x00;   //设置P3.5~P3.2为高阻输入
    P4M1 = 0x00;   P4M0 = 0x02;   //设置P4.1为推挽输出
   
    P3PU |= 0x3c;   //开启P3.5~P3.2内部上拉电阻

    P41 = 0;    //LED Power On

    //PnIM2,PnIM1,PnIM0000:下降沿中断; 001:上升沿中断; 010:低电平中断; 011:高电平中断; 100:边沿中断
//    P0IM0 = 0x00;//边沿中断
//    P0IM1 = 0x00;
//    P0IM2 = 0xff;
//    P0INTE = 0xff; //使能 P0 口中断
//    P0WKUE = 0xff; //使能 P0 口中断唤醒

//    P1IM0 = 0xff;//上升沿中断
//    P1IM1 = 0x00;
//    P1IM2 = 0x00;
//    P1INTE = 0xff; //使能 P1 口中断
//    P1WKUE = 0xff; //使能 P1 口中断唤醒

//    P2IM0 = 0x00;//下降沿中断
//    P2IM1 = 0x00;
//    P2IM2 = 0x00;
//    P2INTE = 0xff; //使能 P2 口中断
//    P2WKUE = 0xff; //使能 P2 口中断唤醒

    P3IM0 = 0x00;//下降沿中断
    P3IM1 = 0x00;
    P3IM2 = 0x00;
    P3INTE = 0x3c; //使能 P3.2~P3.5 口中断
    P3WKUE = 0x3c; //使能 P3.2~P3.5 口中断唤醒

//    P4IM0 = 0x00;//下降沿中断
//    P4IM1 = 0x00;
//    P4IM2 = 0x00;
//    P4INTE = 0xff; //使能 P4 口中断
//    P4WKUE = 0xff; //使能 P4 口中断唤醒

//    P5IM0 = 0x00;//下降沿中断
//    P5IM1 = 0x00;
//    P5IM2 = 0x00;
//    P5INTE = 0xff; //使能 P5 口中断
//    P5WKUE = 0xff; //使能 P5 口中断唤醒

//    P6IM0 = 0x00;//下降沿中断
//    P6IM1 = 0x00;
//    P6IM2 = 0x00;
//    P6INTE = 0xff; //使能 P6 口中断
//    P6WKUE = 0xff; //使能 P6 口中断唤醒

//    P7IM0 = 0x00;//下降沿中断
//    P7IM1 = 0x00;
//    P7IM2 = 0x00;
//    P7INTE = 0xff; //使能 P7 口中断
//    P7WKUE = 0xff; //使能 P7 口中断唤醒

//    P8IM0 = 0x00;//下降沿中断
//    P8IM1 = 0x00;
//    P8IM2 = 0x00;
//    P8INTE = 0xff; //使能 P8 口中断
//    P8WKUE = 0xff; //使能 P8 口中断唤醒

//    P9IM0 = 0x00;//下降沿中断
//    P9IM1 = 0x00;
//    P9IM2 = 0x00;
//    P9INTE = 0xff; //使能 P9 口中断
//    P9WKUE = 0xff; //使能 P9 口中断唤醒

//    PAIM0 = 0x00;//下降沿中断
//    PAIM1 = 0x00;
//    PAIM2 = 0x00;
//    PAINTE = 0xff; //使能 PA 口中断
//    PAWKUE = 0xff; //使能 PA 口中断唤醒

//    PBIM0 = 0x00;//下降沿中断
//    PBIM1 = 0x00;
//    PBIM2 = 0x00;
//    PBINTE = 0xff; //使能 PB 口中断
//    PBWKUE = 0xff; //使能 PB 口中断唤醒

    UartInit();
   
//    IRCDB = 0x10;

    P0INTF = 0;   //清中断标志
    P1INTF = 0;
    P2INTF = 0;
    P3INTF = 0;
    P4INTF = 0;
    P5INTF = 0;
    P6INTF = 0;
    P7INTF = 0;
    P8INTF = 0;
    P9INTF = 0;
    PAINTF = 0;
    PBINTF = 0;

    EA = 1;   //允许总中断

    while(1)
    {
      delay_ms(100);      //延时100ms
      //跑马灯指示工作状态
      P0 = ~ledNum;    //输出低驱动
      ledIndex++;
      if(ledIndex > 7)
      {
            ledIndex = 0;
      }

      //2秒后MCU进入休眠状态
      if(++msecond >= 20)
      {
            msecond = 0;    //清计数

            P0 = 0xff;      //先关闭显示,省电
            printf("MCU Sleep.\r\n");

            PD = 1;         //Sleep
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            _nop_();
            printf("MCU wakeup from P%02X.\r\n", ioIndex);
      }
    }
}

//========================================================================
//========================================================================
void P0INT_ISR() interrupt P0INT_VECTOR
{
    u8 intf;

    intf = P0INTF; //P0 口中断
    if (intf)
    {
      P0INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x00;
      if (intf & 0x02) ioIndex = 0x01;
      if (intf & 0x04) ioIndex = 0x02;
      if (intf & 0x08) ioIndex = 0x03;
      if (intf & 0x10) ioIndex = 0x04;
      if (intf & 0x20) ioIndex = 0x05;
      if (intf & 0x40) ioIndex = 0x06;
      if (intf & 0x80) ioIndex = 0x07;
    }
}

void P1INT_ISR() interrupt P1INT_VECTOR
{
    u8 intf;

    intf = P1INTF; //P1 口中断
    if (intf)
    {
      P1INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x10;
      if (intf & 0x02) ioIndex = 0x11;
      if (intf & 0x04) ioIndex = 0x12;
      if (intf & 0x08) ioIndex = 0x13;
      if (intf & 0x10) ioIndex = 0x14;
      if (intf & 0x20) ioIndex = 0x15;
      if (intf & 0x40) ioIndex = 0x16;
      if (intf & 0x80) ioIndex = 0x17;
    }
}

void P2INT_ISR() interrupt P2INT_VECTOR
{
    u8 intf;

    intf = P2INTF; //P2 口中断
    if (intf)
    {
      P2INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x20;
      if (intf & 0x02) ioIndex = 0x21;
      if (intf & 0x04) ioIndex = 0x22;
      if (intf & 0x08) ioIndex = 0x23;
      if (intf & 0x10) ioIndex = 0x24;
      if (intf & 0x20) ioIndex = 0x25;
      if (intf & 0x40) ioIndex = 0x26;
      if (intf & 0x80) ioIndex = 0x27;
    }
}

void P3INT_ISR() interrupt P3INT_VECTOR
{
    u8 intf;

    intf = P3INTF; //P3 口中断
    if (intf)
    {
      P3INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x30;
      if (intf & 0x02) ioIndex = 0x31;
      if (intf & 0x04) ioIndex = 0x32;
      if (intf & 0x08) ioIndex = 0x33;
      if (intf & 0x10) ioIndex = 0x34;
      if (intf & 0x20) ioIndex = 0x35;
      if (intf & 0x40) ioIndex = 0x36;
      if (intf & 0x80) ioIndex = 0x37;
    }
}

void P4INT_ISR() interrupt P4INT_VECTOR
{
    u8 intf;

    intf = P4INTF; //P4 口中断
    if (intf)
    {
      P4INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x40;
      if (intf & 0x02) ioIndex = 0x41;
      if (intf & 0x04) ioIndex = 0x42;
      if (intf & 0x08) ioIndex = 0x43;
      if (intf & 0x10) ioIndex = 0x44;
      if (intf & 0x20) ioIndex = 0x45;
      if (intf & 0x40) ioIndex = 0x46;
      if (intf & 0x80) ioIndex = 0x47;
    }
}

void P5INT_ISR() interrupt P5INT_VECTOR
{
    u8 intf;

    intf = P5INTF; //P5 口中断
    if (intf)
    {
      P5INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x50;
      if (intf & 0x02) ioIndex = 0x51;
      if (intf & 0x04) ioIndex = 0x52;
      if (intf & 0x08) ioIndex = 0x53;
      if (intf & 0x10) ioIndex = 0x54;
      if (intf & 0x20) ioIndex = 0x55;
      if (intf & 0x40) ioIndex = 0x56;
      if (intf & 0x80) ioIndex = 0x57;
    }
}

void P6INT_ISR() interrupt P6INT_VECTOR
{
    u8 intf;

    intf = P6INTF; //P6 口中断
    if (intf)
    {
      P6INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x60;
      if (intf & 0x02) ioIndex = 0x61;
      if (intf & 0x04) ioIndex = 0x62;
      if (intf & 0x08) ioIndex = 0x63;
      if (intf & 0x10) ioIndex = 0x64;
      if (intf & 0x20) ioIndex = 0x65;
      if (intf & 0x40) ioIndex = 0x66;
      if (intf & 0x80) ioIndex = 0x67;
    }
}

void P7INT_ISR() interrupt P7INT_VECTOR
{
    u8 intf;

    intf = P7INTF; //P7 口中断
    if (intf)
    {
      P7INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x70;
      if (intf & 0x02) ioIndex = 0x71;
      if (intf & 0x04) ioIndex = 0x72;
      if (intf & 0x08) ioIndex = 0x73;
      if (intf & 0x10) ioIndex = 0x74;
      if (intf & 0x20) ioIndex = 0x75;
      if (intf & 0x40) ioIndex = 0x76;
      if (intf & 0x80) ioIndex = 0x77;
    }
}

void P8INT_ISR() interrupt P8INT_VECTOR
{
    u8 intf;

    intf = P8INTF; //P8 口中断
    if (intf)
    {
      P8INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x80;
      if (intf & 0x02) ioIndex = 0x81;
      if (intf & 0x04) ioIndex = 0x82;
      if (intf & 0x08) ioIndex = 0x83;
      if (intf & 0x10) ioIndex = 0x84;
      if (intf & 0x20) ioIndex = 0x85;
      if (intf & 0x40) ioIndex = 0x86;
      if (intf & 0x80) ioIndex = 0x87;
    }
}

void P9INT_ISR() interrupt P9INT_VECTOR
{
    u8 intf;

    intf = P9INTF; //P9 口中断
    if (intf)
    {
      P9INTF = 0x00;
      if (intf & 0x01) ioIndex = 0x90;
      if (intf & 0x02) ioIndex = 0x91;
      if (intf & 0x04) ioIndex = 0x92;
      if (intf & 0x08) ioIndex = 0x93;
      if (intf & 0x10) ioIndex = 0x94;
      if (intf & 0x20) ioIndex = 0x95;
      if (intf & 0x40) ioIndex = 0x96;
      if (intf & 0x80) ioIndex = 0x97;
    }
}

void PAINT_ISR() interrupt PAINT_VECTOR
{
    u8 intf;

    intf = PAINTF; //PA 口中断
    if (intf)
    {
      PAINTF = 0x00;
      if (intf & 0x01) ioIndex = 0xa0;
      if (intf & 0x02) ioIndex = 0xa1;
      if (intf & 0x04) ioIndex = 0xa2;
      if (intf & 0x08) ioIndex = 0xa3;
      if (intf & 0x10) ioIndex = 0xa4;
      if (intf & 0x20) ioIndex = 0xa5;
      if (intf & 0x40) ioIndex = 0xa6;
      if (intf & 0x80) ioIndex = 0xa7;
    }
}

void PBINT_ISR() interrupt PBINT_VECTOR
{
    u8 intf;

    intf = PBINTF; //PB 口中断
    if (intf)
    {
      PBINTF = 0x00;
      if (intf & 0x01) ioIndex = 0xb0;
      if (intf & 0x02) ioIndex = 0xb1;
      if (intf & 0x04) ioIndex = 0xb2;
      if (intf & 0x08) ioIndex = 0xb3;
      if (intf & 0x10) ioIndex = 0xb4;
      if (intf & 0x20) ioIndex = 0xb5;
      if (intf & 0x40) ioIndex = 0xb6;
      if (intf & 0x80) ioIndex = 0xb7;
    }
}

//========================================================================
// 函数: void delay_ms(unsigned int ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数.
// 返回: none.
// 版本: VER1.0
// 日期: 2025-11-01
// 备注: 由于芯片使能了Cache功能,软件延时时间可能不太准确
//========================================================================
void delay_ms(u16 ms)
{
    u16 i;
    do{
      i = MAIN_Fosc / 6000;
      while(--i);
    }while(--ms);
}

/******************** 串口打印函数 ********************/
void UartInit(void)
{
#if(PrintUart == 1)
    S1_S1 = 0;      //UART1 switch to, 00: P3.0 P3.1, 01: P3.6 P3.7, 10: P1.6 P1.7, 11: P4.3 P4.4
    S1_S0 = 0;
    SCON = (SCON & 0x3f) | 0x40;
    T1x12 = 1;      //定时器时钟1T模式
    S1BRT = 0;      //串口1选择定时器1为波特率发生器
    TL1= TM;
    TH1= TM>>8;
    TR1 = 1;      //定时器1开始计时

//    SCON = (SCON & 0x3f) | 0x40;
//    T2L= TM;
//    T2H= TM>>8;
//    AUXR |= 0x15;   //串口1选择定时器2为波特率发生器
#else
    S2_S = 0;       //UART2 switch to: 0: P1.0 P1.1,1: P4.6 P4.7
    S2CON = (SCON & 0x3f) | 0x40;
    T2L= TM;
    T2H= TM>>8;
    AUXR |= 0x14;   //定时器2时钟1T模式,开始计时
#endif
}

void UartPutc(unsigned char dat)
{
#if(PrintUart == 1)
    SBUF = dat;
    while(TI==0);
    TI = 0;
#else
    S2BUF= dat;
    while(S2TI == 0);
    S2TI = 0;       //Clear Tx flag
#endif
}

char putchar(char c)
{
    UartPutc(c);
    return c;
}



页: [1]
查看完整版本: 68-普通IO口中断-休眠唤醒,STC32G144K246实验箱演示程序