电源管理代码


#include "ioCC2530.h"
#define LED1 P1_0
#define LED2 P1_1
#define LED3 P1_3
#define LED4 P1_4
#define SW P1_2
/********************定义数据类型***************************/
#define uchar unsigned char
#define uint16 unsigned short int //占用1个字节
#define uint32 unsigned long int //占用2个字节
/*****************参数类型定义(枚举型)********************/
enum SYSCLK_SRC{RC_16M,XOSC_32M}; //系统时钟源参数
enum POWER_MODE{PM_IDLE,PM_1,PM_2,PM_3}; //系统电源管理模式参数
/********************************************
函数名称:System_Init()
函数功能:系统初始化(IO、LED、外部中断)
入口参数:无
出口参数:无
返 回 值:无
********************************************/
void System_Init()
{
P1SEL = 0x00; // (P1SEL &= ~0x1F)
P1DIR |= 0x1B; // 0入1出
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
PICTL &= ~0x02; //配置P1_2为上升沿触发中断
P1IFG &= ~0x04; //清除P1_2为中断标识
P1IF = 0; //清除P1中断标识
}
/********************************************
函数名称:ClockSourceSelcet()
功 能:系统时钟选择
入口参数:时钟选择(Source:XOSC_32M 或 RC_16M)
出口参数:无
返 回 值:无
********************************************/
void SystemClockSourceSelcet(enum SYSCLK_SRC Source)
{
uchar CLKconcmd; //用于读取晶振配置值
uchar CLKconsta; //用于读取晶振实时振动值
if(Source == XOSC_32M) //传递过来的是32M
{
CLKCONCMD &= 0x80;
}
else if(Source == RC_16M) //传递过来的是16M
{
CLKCONCMD &= 0x80;
CLKCONCMD |= 0x49;
}
CLKconcmd = CLKCONCMD; //读取晶振配置值
do
{
CLKconsta = CLKCONSTA; //读取实时振动值
}while(CLKconsta != CLKconcmd); //判断晶振实时振动值是否达到配置值(等待时钟配置)
}
/********************************************
函数名称:delay()
功 能:软件延时
入口参数:time--延时循环执行次数
出口参数:无
返 回 值:无
********************************************/
void delay(unsigned int time)
{
short int i;
uchar j;
for(i = 0; i < time; i++)
{ for(j = 0; j < 240; j++)
{ asm("NOP"); // asm是内嵌汇编,nop是空操作,执行一个指令周期
asm("NOP");
asm("NOP");
}
}
}
/********************************************
函数名称:LED_Blink()
功 能:根据需要闪烁的LEDx(LED1、LED2、LED3、LED4),进行对应控制
入口参数:LED1、LED2、LED3、LED4
出口参数:无
返 回 值:无
********************************************/
void LED_Blink(uchar LEDx)
{
uchar i;
switch(LEDx)
{
case 1:
for(i=0;i<5;i++)
{
LED1 = 1;
delay(2000);
LED1 = 0;
delay(2000);
}
break;
case 2:
for(i=0;i<5;i++)
{
LED2 = 1;
delay(2000);
LED2 = 0;
delay(2000);
}
break;
case 3:
for(i=0;i<5;i++)
{
LED3 = 1;
delay(2000);
LED3 = 0;
delay(2000);
}
break;
case 4:
for(i=0;i<5;i++)
{
LED4 = 1;
delay(2000);
LED4 = 0;
delay(2000);
}
break;
}
}
/********************************************
函数名称:POWER_MODE_Set()
功 能:配置电源管理工作模式
入口参数:四种工作模式:PM_IDLE、PM_1、PM_2、PM_3
出口参数:无
返 回 值:无
********************************************/
void POWER_MODE_Set(enum POWER_MODE PM)
{
if(PM == PM_IDLE) //空闲模式
{
SLEEPCMD &= ~0x03;
}
else if(PM == PM_1) //模式1
{
SLEEPCMD &= ~0x20;
}
else if(PM == PM_2) //模式2
{
SLEEPCMD &= ~0x01;
}
else if(PM == PM_3) //模式3
{
SLEEPCMD &= ~0x00;
}
PCON |= 0x01; //模式配置完毕,强制进入所选电源管理模式
}
/********************************************
函数名称:SLEEP_Timer_Set()
功 能:配置睡眠定时器
入口参数:定时时间值
出口参数:无
返 回 值:无
********************************************/
void SLEEP_Timer_Set(uint16 sec)
{
uint32 sleeptime = 0;
sleeptime |= (uint32)ST0; //取出ST寄存器系列中ST0的值(低8位)
sleeptime |= (uint32)ST1 << 8; //取出ST系列寄存器中ST1的值(中8位)
sleeptime |= (uint32)ST2 << 16; //取出ST系列寄存器中ST2的值(高8位)
/*************以上程序,即为读取睡眠定时器当前实时值 ST0、ST1、ST2至sleeptime**********/
/*************以下程序,即为计算下一次需要唤醒的时间值 = 上述所读取的值 + sec值*********************/
sleeptime = sleeptime +(uint32)sec * (uint32)32753; //定时器比较值
while((STLOAD & 0x01) == 0); //等待到该为允许被导入
/*********以下程序,即为定时器比较值被配置**********/
ST0 = (uchar)sleeptime; //将32位的sleeptime,只保留最低8位
ST1 = (uchar)(sleeptime >> 8); //将32位的sleeptime,只保留最中8位
ST2 = (uchar)(sleeptime >> 16); //将32位的sleeptime,只保留最高8位
}
/********************************************
函数名称:SLEEP_ISR()
功 能:睡眠定时器中断服务函数
入口参数:无
出口参数:无
返 回 值:无
********************************************/
#pragma vector = ST_VECTOR
__interrupt void SLEEP_ISR()
{
EA = 0;
STIF = 0; //清除睡眠定时器中断标识
STIE = 0; //禁止睡眠定时器进入中断
EA = 1;
}
/********************************************
函数名称:P1_EINT_ISR()
功 能:睡眠外部中断服务函数
入口参数:无
出口参数:无
返 回 值:无
********************************************/
#pragma vector = P1INT_VECTOR
__interrupt void P1_EINT_ISR()
{
EA = 0;
if(P1IFG & 0x04) //判断是否是P1.2中断来
{
if(SW == 0) //判断按钮(SW)是否按下(低电平有效)
{
delay(100); //延迟消抖
while(SW == 0);
P1IFG &= ~0x04; //清楚P1.2外部中断标识
P1IF = 0; //清楚P1端口组中断标识
}
}
EA = 1;
}
/********************************************
函数名称:IRClear()
功 能:睡眠定时器中断标识清楚
入口参数:无
出口参数:无
返 回 值:无
********************************************/
void IRClear()
{
IRCON &= ~0x80;
IEN0 |= (0x01 << 5);
}
/********************************************
函数名称:main()
功 能:程序主函数
入口参数:无
出口参数:无
返 回 值:无
********************************************/
void main()
{
SystemClockSourceSelcet(XOSC_32M); //设置时钟频率
System_Init(); //系统初始化(IO、LED、外部中断)
while(1)
{
/*************************设置空闲模式*************************/
LED_Blink(1);
SLEEP_Timer_Set(2); //设置睡眠定时器时间间隔2s
IRClear();
POWER_MODE_Set(PM_IDLE); //设置电源管理进入空闲模式
/*************************PM_1模式设置*************************/
LED_Blink(2);
SLEEP_Timer_Set(3); //设置睡眠定时器时间间隔3s
IRClear();
POWER_MODE_Set(PM_1); //设置电源管理进入空闲模式
/*************************PM_2模式设置*************************/
LED_Blink(3);
SLEEP_Timer_Set(4); //设置睡眠定时器时间间隔4s
IRClear();
POWER_MODE_Set(PM_2); //设置电源管理进入空闲模式
/*************************PM_3模式设置*************************/
LED_Blink(4);
POWER_MODE_Set(PM_2); //设置电源管理进入空闲模式
P1IEN |= 0x04; //使能P1.2中断功能
IEN2|= 0x10; //使能P1端口组中断
POWER_MODE_Set(PM_2); //设置电源管理进入空闲模式
}
}

