ZigBee-CC2530单片机 - 低功耗运行
程序源码
#include "ioCC2530.h"
#define LED1 P1_0 // P1_0定义为P1_0
#define LED2 P1_1 // P1_0定义为P1_1
#define SW1 P1_2 //SW1端口宏定义
enum SYSCLK_SRC
{
RC_16MHz,XOSC_32MHz
};
enum POWERMODE
{
PM_IDLE,PM_1,PM_2,PM_3
};
/**************************************************************
函数名称:delay
功 能:软件延时
入口参数:time--延时循环执行次数
出口参数:无
返 回 值:无
**************************************************************/
void delay(unsigned int time)
{
unsigned int i;
unsigned char j;
for(i = 0;i < time;i++)
for(j = 0;j < 240;j++)
{
asm("NOP");//asm用来在C代码中嵌入汇编语言操作,汇
asm("NOP");//编命令nop是空操作,消耗1个指令周期。
asm("NOP");
}
}
/**************************************************************
函数名称:BlankLed
功 能:闪烁LED灯
入口参数:led--要进行闪烁的LED灯,取值1~4
出口参数:无
返 回 值:无
**************************************************************/
void BlankLed(unsigned char led)
{
unsigned char i;
switch(led)
{
case 1:
for(i=0;i<=5;i++)
{
LED1 = 1;
delay(500);
LED1 = 0;
delay(500);
}
break;
case 2:
for(i=0;i<=5;i++)
{
LED2 = 1;
delay(500);
LED2 = 0;
delay(500);
}
break;
}
}
/**************************************************************
函数名称:SystemClockSourceSelect
功能:选择系统时钟源(主时钟源)
入口参数:source
XOSC_32MHz 32MHz晶体振荡器
RC_16MHz 16MHz RC振荡器
出口参数:无
返回值:无
**************************************************************/
void SystemClockSourceSelect(enum SYSCLK_SRC source)
{
unsigned char clkconcmd,clkconsta;
if(source == RC_16MHz)
{
CLKCONCMD &= 0x80;
CLKCONCMD |= 0x49;
}
else if(source == XOSC_32MHz)
{
CLKCONCMD &= 0x80;
}
/* 等待所选择的系统时钟源(主时钟源)稳定 */
clkconcmd = CLKCONCMD; // 读取时钟控制寄存器CLKCONCMD
do
{
clkconsta = CLKCONSTA; // 读取时钟状态寄存器CLKCONSTA
} while(clkconsta != clkconcmd); // 直到选择的系统时钟源(主时钟源)已经稳定
}
/**************************************************************
函数名称:SetPowerMode
功能:设置功耗模式
入口参数:pm
PM_IDLE 空闲模式
PM_1 功耗模式PM1
PM_2 功耗模式PM2
PM_3 功耗模式PM3
出口参数:无
返回值:无
**************************************************************/
void SetPowerMode(enum POWERMODE pm)
{
/* 空闲模式 */
if(pm == PM_IDLE)
{
SLEEPCMD &= ~0x03;
}
/* 功耗模式PM3*/
else if(pm == PM_3)
{
SLEEPCMD |= ~0x03;
}
/* 其他功耗模式,即功耗模式PM1或PM2*/
else
{
SLEEPCMD &= ~0x03;
SLEEPCMD |= pm;
}
/* 进入所选择的功耗模式 */
PCON |= 0x01;
asm("NOP");
}
/**************************************************************
函数名称:SetSleepTime
功能:设置睡眠时间,即设置睡眠定时器的比较值。
入口参数:sec 唤醒功耗模式IDLE,PM1或PM2的时间。
出口参数:无
返回值:无
**************************************************************/
void SetSleepTime(unsigned short sec)
{
unsigned long sleeptime = 0;
/* 读取睡眠定时器的当前计数值 */
sleeptime |= ST0;
sleeptime |= (unsigned long)ST1 << 8;
sleeptime |= (unsigned long)ST2 << 16;
/* 根据指定的睡眠时间计算出应设置的比较值 */
sleeptime += ((unsigned long)sec * (unsigned long)32753);
/* 设置比较值 */
while((STLOAD & 0x01) == 0); // 等待允许加载新的比较值
ST2 = (unsigned char)(sleeptime >> 16);
ST1 = (unsigned char)(sleeptime >> 8);
ST0 = (unsigned char) sleeptime;
}
/**************************************************************
函数名称:initIO
功能:初始化系统IO
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void initIO()
{
P1SEL &= ~0x1F; // 设置LED、SW1为普通IO口
P1DIR |= 0x03 ; // 设置LED为输出
P1DIR &= ~0X04; //Sw1按键在 P1.2,设定为输入
LED1 = 0; //灭 LED
LED2 = 0; //灭 LED
PICTL &= ~0x02; //配置P1口的中断边沿为上升沿产生中断
P1IFG &= ~0x04; // 清除P1.2中断标志
P1IF =0; // 清除P1口中断标志
}
/**************************************************************
函数名称:ST_ISR
功能:睡眠定时器中断服务函数
入口参数:无
出口参数:无
返回值:无
**************************************************************/
#pragma vector=ST_VECTOR
__interrupt void ST_ISR(void)
{
EA=0; //关全局中断
STIF=0; //睡眠定时器中断标志清0
STIE=0; // 禁止睡眠定时器中断
EA = 1; // 使能全局中断
}
/**************************************************************
函数名称:main
功能:程序主函数
入口参数:无
出口参数:无
返回值:无
**************************************************************/
void main(void)
{
SystemClockSourceSelect(XOSC_32MHz); // 选择32MHz晶体振荡器作为系统时钟源(主时钟源)
initIO(); //初始化IO
/* 使能全局中断 */
EA = 1;
while(1)
{
/* 功耗模式:主动模式 */
LED1=0; //LED1灯灭
LED2=0; //LED2灯灭
/* 功耗模式:空闲模式 */
BlankLed(1); //LED1闪烁5次
SetSleepTime(2); // 设置睡眠时间为2秒
IRCON &= ~0x80; // 清除睡眠定时器中断标志
IEN0 |= (0x01 << 5); // 使能睡眠定时器中断
SetPowerMode(PM_IDLE); // 进入空闲模式
/* 功耗模式:主动模式 */
BlankLed(2); //LED2闪烁5次
/* 功耗模式:PM1 */
SetSleepTime(3); // 设置睡眠时间为3秒
IRCON &= ~0x80; // 清除睡眠定时器中断标志
IEN0 |= (0x01 << 5); // 使能睡眠定时器中断
SetPowerMode(PM_1); // 进入功耗模式PM1
/* 功耗模式:主动模式 */
BlankLed(1); //LED1闪烁5次
/* 功耗模式:PM2 */
SetSleepTime(4); // 设置睡眠时间为4秒
IRCON &= ~0x80; // 清除睡眠定时器中断标志
IEN0 |= (0x01 << 5); // 使能睡眠定时器中断
SetPowerMode(PM_2); // 进入功耗模式PM2
/* 功耗模式:主动模式 */
BlankLed(2); //LED2闪烁5次
/* 功耗模式:PM3 */
P1IEN |=0x04; //使能P1.2中断
IEN2 |= 0x10; //使能P1口中断
SetPowerMode(PM_3); // 进入功耗模式PM3
}
}
/**************************************************************
函数名称:EINT_ISR
功能:外部中断服务函数
入口参数:无
出口参数:无
返回值:无
**************************************************************/
#pragma vector=P1INT_VECTOR
__interrupt void EINT_ISR(void)
{
EA = 0; // 关闭全局中断
/* 若是P1.2产生的中断 */
if(P1IFG & 0x04)
{
/* 等待用户释放按键,并消抖 */
while(SW1 == 0); //低电平有效
delay(100);
while(SW1 == 0);
P1IFG &= ~0x04; // 清除P1.2中断标志
P1IF =0; // 清除P1口中断标志
P1IEN &= ~ 0x04; //禁止P1.2中断
IEN2 &= ~ 0x10; //禁止P1口中断
}
EA = 1; // 使能全局中断
}