STC32G12K128省电模式唤醒
这段代码在main的主循环中一直进入省电模式,只有当P2.1上触发中断之后,中断会串口打印数据,随后退出省电模式,执行PD=1后面的代码,但是实际情况是中断触发之后,中断函数中的打印能有,但是while循环中的打印有时候有,有时候没有,请问这个是什么问题神农鼎 发表于 2025-12-2 15:56
我看到了,STC32G12K128的普通IO口最好不要上升沿、下降沿中断,
但是有2个原因:
1.硬件已经设计好了,现在要唤醒的中断就在这个引脚上面;
2.从PD模式下面普通IO唤醒只能使用上升、下降沿中断,不能使用高低电平的中断吧
神农鼎 发表于 2025-12-2 15:56
这个IO中断优先级会对唤醒有影响吗?需要额外配置下吗?
可以改用:
STC32G8K64-LQFP48/32/TSSOP20
STC8H8K64U-LQFP64/48/32/TSSOP20
我遇到过相同问题,因为串口还没发完就进入省电模式了,解决办法是等串口发送完毕再进入省电模式
因为printf只是装载数据到缓冲区,然后串口中断和硬件在“后台”发送
以下例程供参考,基于本人编写的“串口收发框架,带不断电下载功能”:
https://www.stcaimcu.com/thread-16321-1-1.html
关键代码:
逻辑:
整个数据包发送完毕后,发送长度变量会在串口中断内清零,printf后要等待该变量为0再进入省电模式
例程:
#include <AI8H.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#define RXD P30
#define TXD P31
#define FOSC 24000000UL
#define BAUD 9600UL //波特率
#define TMRF 200UL //定时器频率
#define BRT (0x10000-(FOSC/BAUD+2)/4) //波特率发生器值
#define TMR (0x10000-FOSC/TMRF/12) //定时器值
#define R_Buf_Len 64 //Uart1接收缓存长度
#define T_Buf_Len 64 //Uart1发送缓存长度
#define R 0 //485接收
#define T 1 //485发送
unsigned char RP; //Uart1接收指针
unsigned char TP; //Uart1发送指针
unsigned char Uart_R_Len; //Uart1接收长度
unsigned char Uart_T_Len; //Uart1发送长度
unsigned char xdata R_Buf; //Uart1接收缓存
unsigned char xdata T_Buf; //Uart1发送缓存
char USER_STCISPCMD[]="@STCISP#"; //下载命令(用户自定义,可修改,必须和ISP软件中设置的一致)
void Delay_ms(unsigned char ms)
{
unsigned int i;
do
{
i=FOSC/10000;
while(--i); //10T per loop
}
while(--ms);
}
void UART_Send(unsigned int x)
{
TP=0;
Uart_T_Len=x;
TI=1;
}
void Uart_Printf(unsigned char *v,...)
{
va_list ap;
va_start(ap,v);
while(Uart_T_Len);
UART_Send(vsprintf(T_Buf,v,ap));
va_end(ap);
}
void UART_Return(unsigned char temp)
{
memcpy(T_Buf,R_Buf,temp);
UART_Send(temp);
}
void Init(void)
{
P_SW2|=EAXFR;
P0M1=0x00; P0M0=0x00; //设置IO模式
P1M1=0x00; P1M0=0x00; //设置IO模式
P2M1=0x00; P2M0=0x00; //设置IO模式
P3M1=0x00; P3M0=0x00; //设置IO模式
P4M1=0x00; P4M0=0x00; //设置IO模式
P5M1=0x00; P5M0=0x00; //设置IO模式
P6M1=0x00; P6M0=0x00; //设置IO模式
P7M1=0x00; P7M0=0x00; //设置IO模式
AUXR=0x40; //设置定时器0时钟为12T模式,设置定时器1为1T模式,设置定时器1为波特率发生器
TMOD=0x01; //设置定时器0为16位不自动重装载模式,设置定时器1为16位自动重装载模式
TH0=TMR>>8; //设置定时器0初始值
TL0=TMR; //设置定时器0初始值
TF0=0; //清除TF0中断标志位
ET0=1; //启用定时器0中断
SCON=0x50; //设置UART1模式为8位数据可变波特率
TH1=BRT>>8; //设置UART1波特率
TL1=BRT; //设置UART1波特率
TR1=1; //打开定时器1
ES=1; //启用UART1中断
EA=1; //启用总中断
}
void main(void)
{
Init();
Uart_Printf("Start\r\n");
RSTCFG&=~0x40;
RSTFLAG=0x14;
// ELVD=1;
Uart_Printf("RSTCFG= 0x%02bX\r\n",RSTCFG);
Uart_Printf("RSTFLAG = 0x%02bX\r\n",RSTFLAG);
Uart_Printf("IE = 0x%02bX\r\n",IE);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
P32=!P32;
Delay_ms(250);
Delay_ms(250);
Uart_Printf("PD\r\n");
while(Uart_T_Len);
_nop_();
_nop_();
_nop_();
_nop_();
PCON|=0x02;
_nop_();
_nop_();
_nop_();
_nop_();
while(1)
{
Uart_Printf("Running\r\n");
Delay_ms(250);
Delay_ms(250);
Delay_ms(250);
Delay_ms(250);
}
}
void Uart_Start(void)
{
TL0=0x00;
TH0=0xEE;
TR0=1;
}
void Uart_Stop(void)
{
TR0=0;
TL0=0x00;
TH0=0xEE;
RP=0;
memset(R_Buf,0x00,sizeof R_Buf);
}
void TMR0_Isr(void) interrupt TMR0_VECTOR
{
UART_Return(RP); //超时原样返回
Uart_Stop();
}
void UART1_Isr(void) interrupt UART1_VECTOR
{
if(RI)
{
RI=0;
Uart_Start();
R_Buf=SBUF;
if((RP==sizeof USER_STCISPCMD-2)&&(memcmp(R_Buf,USER_STCISPCMD,sizeof USER_STCISPCMD-1)==0)) //收到用户命令后复位到ISP区
{
IAP_CONTR=0x60;
}
if(RP==R_Buf_Len-1)
{
Uart_Stop();
}
else if(TR0)
{
RP++;
}
}
if(TI)
{
TI=0;
if(TP==Uart_T_Len)
{
// TR=R; //485软件收发控制
TP=0;
Uart_T_Len=0;
}
if(Uart_T_Len!=0)
{
// TR=T; //485软件收发控制
SBUF=(T_Buf);
TP++;
}
}
}
void LVD_Isr(void) interrupt LVD_VECTOR
{
RSTFLAG=0x10;
}
DebugLab 发表于 2025-12-2 18:13
我遇到过相同问题,因为串口还没发完就进入省电模式了,解决办法是等串口发送完毕再进入省电模式
因为print ...
好的,我试一下,不过今天早上发现这套代码省电模式唤醒之后的串口打印又有了,昨天下午还是不行的,中断触发之后只有中断函数中的打印会触发,只是放了一个晚上,程序完全没动过{:yun:}
页:
[1]