Flowers_World
分类: 嵌入式
2016-05-25 10:19:27
/*****************************************
//说明:PM1和PM2和PM0的切换,用睡眠定时器(因为睡眠定时器计时时间到后,响应睡眠定时器中断,电源模式会自动从PM1/PM2切换到PM0)。在PM3下,睡眠定时器不起作用,因为32K的晶振都关闭了,故从PM3切换到PM0,用的是外部IO中断。
“设置睡眠定时器的定时间隔”这一步一定要在“设置电源模式”之前,因为进入睡眠后系统就不会继续执行程序了。
读取睡眠定时器的当前计数值,顺序必须遵循:读ST0 → 读ST1 → 读ST2
写入睡眠定时器的比较值,顺序必须遵循:写ST2 → 写ST1 → 写ST0
当定时器的计数值=比较值时,产生中断)
*****************************************/
#include
#define uint unsigned int
#define uchar unsigned char
#define uint8 unsigned char
#define uint32 unsigned long
#define LED_ON 0
#define LED_OFF 1
#define gled P1_0
#define rled P1_1
#define crystal 0 //石英晶振
#define rc 1 //RC晶振
#define s1 P0_1
//延时函数
void delay(uint n)
{
uint i,j;
for(i=0;i<50;i++)
for(j=0;j
void initKey(void)
{
P0SEL &= ~0X02;
P0DIR &= ~0X02;
P0IEN |= 0X02;
IEN1 |= 0X20;
EA = 1;
}
void initled(void)
{
P1SEL &= ~0X03; //P1_0,P1_1接口设为通用接口模式
P1DIR |= 0X03; //P1_0,P1_1接口设为输出模式
rled = 1;
gled = 1;
}
//设置主时钟
void set_main_clock(source)
{
if(source)
{
CLKCONCMD |= 0X40; //选择16MHZ RCOSC为系统时钟源
while(!(CLKCONSTA & 0X40)); //等待时钟稳定
}else
{
CLKCONCMD &= ~0X40; //选择32MHZ XOSC为系统时钟源
while(CLKCONSTA & 0X40); //等待时钟稳定
}
}
//设置系统低速时钟
void set_low_clock(source)
{
if(source)
CLKCONCMD |= 0X80; //选择32KHZ RCOSC为低速时钟源
else
CLKCONCMD &= ~0X80; //选择32KHZ XOSC为低速时钟源
}
//初始化睡眠定时器
void init_sleep_timer(void)
{
ST2 = 0X00;
ST1 = 0X00;
ST0 = 0X00; //设置计数值
EA = 1; //开中断
STIE = 1; //使能睡眠定时器中断
STIF = 0; //清除睡眠定时器中断标志
}
//led闪烁函数
void blink_led(void)
{
gled = 1;
uchar jj = 10;
while(jj--)
{
rled = !rled;
delay(10000);
}
rled = 1;
gled = 0;
}
//设置睡眠时间
void set_st_period(uint sec)
{
uint32 sleeptimer = 0;
//把ST2:ST1:ST0赋值给sleeptimer
sleeptimer |= (uint32)ST0;
sleeptimer |= ((uint32)ST1 << 8);
sleeptimer |= ((uint32)ST2 << 16);
sleeptimer += ((uint32)sec * (uint32)32768); //低速频率为32.768KHZ,故每秒定时器计数32768次 如果低速时钟为32K呢
//把加N秒的计数值赋给ST2:ST1:ST0
ST2 = (uint8)(sleeptimer >> 16);
ST1 = (uint8)(sleeptimer >> 8);
ST0 = (uint8)sleeptimer;
}
void set_powermode(uchar mode)
{
uchar i;
if(mode<4)
{
SLEEPCMD &= ~0X03;
SLEEPCMD |= mode;
for(i=0;i<4;i++);
PCON = 1;
}
else
PCON = 0;
}
void main(void)
{
set_main_clock(crystal);
set_low_clock(crystal);
initled();
init_sleep_timer();
gled = LED_ON;
delay(50000);
//进入PM1模式
gled = LED_OFF;
set_st_period(5);
set_powermode(1);
rled = LED_ON;
delay(50000);
//进入PM2模式
rled = LED_OFF;
set_st_period(5);
set_powermode(2);
gled = LED_ON;
delay(50000);
gled = LED_OFF;
initKey(); //初始化按键
set_powermode(3);
rled = LED_ON;
while(1);
}
//睡眠定时器中断函数
#pragma vector = ST_VECTOR
__interrupt void ST_ISR(void)
{
EA = 0;
STIF = 0; //标志清除
EA = 1;
}
//P0中断函数
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
EA = 0;
P0IF = 0;
P0IFG &= ~0X02;
set_powermode(4); //只要响应了IO中断,就会从PM1/PM2/PM3恢复到PM0,故本句也可以取消。
EA = 1;
}