|
|
最近搞个灯,要求很简单,于是用NY8单片机,不是能赚大钱的项目,程序发出来供观众围观.
//器件型号:NY8A052E SOP8
//振荡器: I_HRC 4MHZ 4T模式 开看门狗
//
//引脚定义:
// --------------------------
// VDD--------|1(VDD) (VSS) 8|--------GND
// M_KEY ------|2(PB5) (PB0/INT)7|--------蓝灯
// ---------|3(PB4) (PB1)6|--------绿灯
// ---------|4(PB3/RSTB) (PB2)5|--------红灯
// --------------------------
// NY8A052ES8
//说明:上电开机进入睡眠模式,通过PB5中断唤醒,唤醒后蓝灯常亮,定时器控制红灯和绿灯闪烁。
//在正常模式下通过KEY按下再次进入睡眠模式
#include <ny8.h>
//#include <stdint.h>
#include "ny8_constant.h"
#define UPDATE_REG(x) __asm__("MOVR _" #x ",F")
volatile unsigned int t0_num,t1_num; //定时器计数变量
volatile unsigned char key_down;
volatile unsigned char key_up;
#define M_KEY PORTBbits.PB5 //平时是高电平,低电平触发
#define LED_R PORTBbits.PB2
#define LED_G PORTBbits.PB1
#define LED_B PORTBbits.PB0
unsigned char flag;
__sbit sleep_flag = flag:0;
__sbit _key_flag = flag:1;
//------------------------------------------------//
//函 数 名:delayms(uchar time);
//入口参数:time
//出口参数:无
//函数作用:延时
//说 明:4M4T时一个循环1mS
void delayms( unsigned char time)
{
unsigned char i; //volatile
while(time--)
{
i = 163;
while(i > 0)
{
CLRWDT();
i--;
}
}
}
//T0初始化 //数据手册21,22,42
void time0_init(void)
{
T0MD = 0x03;
TMR0 = 0x30;
INTE |= (1<<0);
INTF = 0;
PCON1 |= (1<<0);
}
void time1_init(void)
{
TMRH = 0;
TMR1 = 0x3f;
T1CR1 = C_TMR1_Reload | C_TMR1_En;
T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Div16;
INTE |= C_INT_TMR1;
INTF = 0;
}
void device_init(void)
{
DISI(); //暂禁止所有中断(关闭总中断)
INTE = 0x00; //中断使能寄存器,关闭所有外设的中断
PCON1 = 0x00; //关闭定时器,关闭总中断
PCON = 0x08; //关看门狗
INTF = 0; //清除所有中断标志
delayms(64); //上电64ms延时
}
void io_init(void)
{
BPHCON &= ~(1<<5); // 启用PB5拉高电阻
BWUCON = 0x20; // C_PB5_Wakeup;启用PB5输入更改唤醒功能
IOSTB = 0x20; // C_PB5_Input 将PB5设置为输入模式,其他设置为输出模式
M_KEY = 1;
LED_R = 0;
LED_G = 0;
LED_B = 0;
UPDATE_REG(PORTB);
INTF = 0;
}
//! interrupt service routine
void isr(void) __interrupt(0)
{
if(INTFbits.T0IF) //定时器0中断
{
INTFbits.T0IF=0;
TMR0 = 0x30; //重装初始值
t0_num ++ ; //将定时计数变自动增加1
if( t0_num > 10 ) //20mS
{
LED_R ^= 1;
t0_num = 0;
}
}
if(INTFbits.T1IF)
{
INTFbits.T1IF=0; //T1中断位清0
t1_num ++ ;//将定时计数变自动增加1
if( t1_num > 500 ) //500mS
{
LED_G ^= 1;
t1_num = 0;
}
CLRWDT();
}
if(INTFbits.PBIF)
{
INTFbits.PBIF=0;
}
}
void KeyScan(void)
{
if(0 == M_KEY) //按键按下
{
key_up = 0;
if( 0 ==_key_flag )
{
key_down++;
if(key_down & 0x80)
{
_key_flag = 1;
sleep_flag = sleep_flag^1;//按一次按键翻转一次'休眠/运行'状态
}
}
}
else //按键没按过/已经松开
{
key_down = 0;
if( 1 ==_key_flag ) //如果有按键标志存在
{
key_up++;
if( key_up & 0x80)//延时程序
{
_key_flag = 0;
}
}
}
}
void main(void)
{
device_init();
io_init();
time0_init();
time1_init();
ENI();
CLRWDT();
t0_num = 0;
t1_num = 0;
sleep_flag = 0;
_key_flag = 0;
while(1)
{
if( ( 0 == sleep_flag ) && ( 1 == M_KEY ) )//设个进休眠的条件
{
PCONbits.WDTEN = 0;
INTE|=(1<<1);
io_init();
SLEEP();
NOP();
INTE = 0;
PCONbits.WDTEN = 1;
UPDATE_REG(PORTB);//重新读一次端口
}
LED_B = 1;
KeyScan();
}
}
|
评分
-
查看全部评分
|