- 打卡等级:以坛为家II
- 打卡总天数:457
- 最近打卡:2025-05-03 11:39:19
金牌会员
- 积分
- 2107
|
本帖最后由 wjhhhhh 于 2024-9-8 09:59 编辑
STC32G12K128 设置的闹钟,到点能触发RTC中断,不能退出掉电休眠,而外部中断0(按下连接P32按键接地)能退出掉电休眠,串口1接收到数据(RXT有低电平)也能退出掉电休眠 。 进入休眠的PCON=0x02 或者DP=1 必须设置二次,否则不能休眠。 哪里没弄好?请各位指教。谢谢
RTC0906.rar
(2.49 KB, 下载次数: 54)
#include "STC32G.h"
#include "stdio.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
/****************************** 用户定义宏 ***********************************/
#define MAIN_Fosc 22118400L //定义主时钟
#define Baudrate 19200L
#define TM (65536 -(MAIN_Fosc/Baudrate/4))
/**********************************/
bit B_1s;
bit B_Alarm; //闹钟标志
bit busy; //串口忙,
bit huan_xing; //唤醒
bit q_t=1;
/*****Uart1Init********************************/
void Uart1Init(void) //19200bps@22.1184MHz
{ SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xE0; //设置定时初始值
T2H = 0xFE; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES=1;
}
/*=======发字节 ===========*/
void Uart1Send(u8 dat)
{ while (busy);
busy = 1;
SBUF = dat;
}
/***RTC初始化***********/
void RTC_config(void)
{
INIYEAR = 21; //Y:2021
INIMONTH = 12; //M:12
INIDAY = 31; //D:31
INIHOUR = 23; //H:23
INIMIN = 59; //M:59
INISEC = 58; //S:50
INISSEC = 0; //S/128:0
ALAHOUR = 0; //闹钟小时
ALAMIN = 0; //闹钟分钟
ALASEC = 15; //闹钟秒 第15秒闹钟时间到
// 第15秒闹钟时间到
X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
while (!(X32KCR & 1)); //等待时钟稳定
RTCCFG = 0x01; //选择外部32K时钟源,触发RTC寄存器初始化
RTCIF = 0x00; //清中断标志
RTCIEN = 0x88; //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
RTCCR = 0x01; //RTC使能
//RTCCFG |= 0x01; //触发RTC寄存器初始化---20240513PDF910/875页
while(RTCCFG & 0x01); //等待初始化完成,需要在 "RTC使能" 之后判断.
}
/*=======延时函数 大约1mS===========*/
void delay_ms(u16 ms)
{ u16 i;
do
{i = MAIN_Fosc / 6000;
while(--i) ;
}while(--ms);
}
//掉电休眠前设置I/O口
void S_sleep(void)
{ Uart1Send(0x8C);Uart1Send(0x8C);
delay_ms(10);
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
P0=0xFF;P1=0xFF;P2=0xFF;P3=0xFF;
P4=0xFF;P5=0xFF;P6=0xFF;P7=0xFF;
// 基本成功 全部IO口双向 8.4 mA 掉电1.85uA
//2024.9.4 VCC=4V 全部IO口高阻 8.26mA 掉电34 uA
//-----------------------
//P0=0x00;P1=0x00;P2=0x00;P3=0x00; //不能退出掉电?
//P4=0x00;P5=0x00;P6=0x00;P7=0x00;
// 全部IO口双向 8.4 mA 掉电2.0xuA
//2024.9.4 VCC=4V 全部IO口高阻 8.26mA 掉电37uA
P0IE = 0x00;//关闭所有I/0口的数字通道
P1IE = 0x00;
P2IE = 0x00;
//P3IE = 0x00;
P3IE |= 0x84;//P3数字通道需要唤醒脚P32(INT0调试用)?
P4IE = 0x00;
P5IE = 0x00;
P6IE = 0x00;
P7IE = 0x00;
//PD=1;//掉电休眠 PD=1或PCON=0x02都可以,都必须两次 !?
//PD=1;//2024.9.6w这里必须两次!?前后都加多个nop都不行
PCON=0x02;
PCON=0x02;
}
/***不能漏掉汇编那一段!!********************************/
void main(void)
{ WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00;//设置为准双向口
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
Uart1Init();
RTC_config();
IT0=1; //IT0下降沿中断
EX0=1; //使能IT0 中断
P27=0; // 标记
P21=0;
EA = 1; //打开总中断
Uart1Send(0x1A);Uart1Send(0x2A);Uart1Send(0x3A);Uart1Send(0x4A);
while(1)
{
if(huan_xing==1)
{P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
P0IE = 0xFF;//使能所有I/0口的数字通道
P1IE = 0xFF;
P2IE = 0xFF;
P3IE = 0xFF;
P4IE = 0xFF;
P5IE = 0xFF;
P6IE = 0xFF;
P7IE = 0xFF;
}
if(B_1s)
{B_1s = 0;
Uart1Send(0xBB);Uart1Send(0xBB);
Uart1Send(YEAR);Uart1Send(MONTH);Uart1Send(DAY);
Uart1Send(HOUR);Uart1Send(MIN);Uart1Send(SEC);
if(q_t==1){P20=0;P27=1;}
else {P20=1;P27=0;}
if(SEC==8) //第八秒开始掉电休眠
{_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
S_sleep();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
if(B_Alarm)
{B_Alarm = 0;
Uart1Send(0xAA);Uart1Send(0xAA);Uart1Send(0xAA);Uart1Send(0xAA);
}
if(P35==0)//按下 P35键 进入掉电休眠
{huan_xing=0;
Uart1Send(0x1C);Uart1Send(0x1C);
delay_ms(10);
S_sleep();
}
}
}
/***P32 外部中断0 中断退出掉电 ****interrupt 0************************************ */
void EX_0_interr() interrupt 0
{huan_xing=1;
}
/******************** RTC中断函数 *********************/
void RTC_Isr() interrupt 13
{
if(RTCIF & 0x80) //闹钟中断 休眠开源 播放立体声音乐
{
RTCIF &= ~0x80;
B_Alarm = 1;
}
if(RTCIF & 0x08) //秒中断
{
RTCIF &= ~0x08;
B_1s = 1;
}
}
/*******interrupt 4******** *************************** */
void Uart1Isr() interrupt 4
{ if (TI)
{ TI = 0;
busy = 0;
}
if (RI)
{RI = 0;
huan_xing=1; //只要有中断发生就退出掉电?
}
}
|
|