
* IC: PIC12F629 OSC: 片内4MHz
*****************************************************************************/
#include<pic.h>
#define uchar unsigned char
#define uint unsigned int
#define LED1 GPIO0
#define LED2 GPIO1
#define LED3 GPIO2
#define KEY GPIO4
/******************************************************************************
* 芯片配置字
*****************************************************************************/
__CONFIG( FOSC_INTRCIO & WDTE_ON & PWRTE_ON & MCLRE_OFF & BOREN_ON )
/******************************************************************************
* 函数及变量声明
*****************************************************************************/
void interrupt ISR(void) //中断处理
void flash() //LED1 2Hz闪烁函数
uint time = 0 //延时用变量
uchar cnt = 0 //记录按键被按下几次
/******************************************************************************
* 主函数
*****************************************************************************/
void main()
{
//选项寄存器
OPTION_REG = 0x0F /* GPIO上拉使能
* GP2/INT端口电平下降沿触发中断
* TIMER0时钟源选择内部时钟
* TIMER0在GP2/TOCKI电平上升沿递增
* 预分频器分配给WDT
* PS2:PS0= 111 WDT分频比1:128
*/
//中断控制寄存器
INTCON = 0xC0 /* 全局中断 使能
* 外设中断 使能
* TMR0溢出中断 禁止
* GP2/INT外部中断 禁止
* 端口电平变化中断 禁止
* INT中断标志INTF 清零
* 电平变化中断标志GPIF 清零
*/
//中断标志位寄存器
PIR1 = 0x00 /* EEPROM写 *** 作完成中断标志位EEIF 清零
* bit6-4位未用
* 比较器中断标志位CMIF 清零
* bit1 未用
* TMR1溢出中断标志位TMR1IF 清零
*/
//电源控制寄存器
PCON = 0x00 /* bit7-2 未用
* 上电复位标志位 清零
* 欠压复位标志位 清零
*/
//IO端口输入输出配置
CMCON = 0x07 //关闭模拟比较器,使GP<2:0>为数字IO
TRISIO = 0x38 //GP<5:3>输入 GP<2:0>输出
GPIO = 0x3F //GP<2:0>输出高电平
WPU = 0x30 //GP<5:4>内部弱上拉开启
IOC = 0x30 //GP<5:4>端口电平变化中断使能
//Timer1控制
TMR1H = 0x3C //使TMR1溢出时间为50000个周期 (50ms)
TMR1L = 0xB0
PIE1 = 0x01 //TMR1IE 计时器1溢出中断使能
T1CON = 0x01 //TMR1ON 使能Timer1
//主循环
while(1)
{
if(KEY == 0) //如果按键按下
{
time = 0
while(!KEY) //等待按键被松开,由中断函数计数
if(time<60) //按下时间不足50ms*60=3000毫秒
{
cnt++ //按键次数加1,改变工作状态
if(cnt>3)
{
cnt = 0
}
}
else if(time >= 60 && time < 100) //按住时间3秒到5秒之间
{
LED2 = !LED2 //LED2亮灭状态翻转
}
else if(time >=100) //按住时间达到5秒
{
LED3 = !LED3 //LED3亮灭状态翻转
}
}
switch(cnt) //检测按键按下次数
{
case 0: LED1 = 1 break //LED1熄灭
case 1: LED1 = !LED1 break //LED1低亮
case 2: LED1 = 0 break //LED1高亮
case 3: flash() break //LED1闪烁
default: break
}
}
}
/******************************************************************************
* 中断处理函数
*****************************************************************************/
void interrupt ISR(void)
{
if(TMR1IE&&TMR1IF) //定时器1溢出中断
{
asm ("CLRWDT") //定时喂狗
++time //延时计数
TMR1H = 0x3C //重设TIMER1初始值使TMR1溢出时间为50000个时钟周期
TMR1L = 0xB0
TMR1IF = 0 //定时器1溢出中断标志位清零
}
}
/******************************************************************************
* LED1闪烁函数
*****************************************************************************/
void flash()
{
time = 0
if(time%4 == 0)
{
LED1 = !LED1
}
}
通过电容保持状态的断电换挡电路:长时间断电复原
短时间断电切换下一档
档位自己改一下延迟就行了,上面那个是试验程序,请用下面那个正式的程序改
http://www.besttorch.com/viewthread.php?tid=500&extra=page%3D1
如果要EEP记忆,那参考这个程序:
http://lidcheng.blog.163.com/blog/static/25358209200741685127131/
原是手电调光,通电后写下一档数据,如果一秒内关闭,下次再开就是下一档
如果通电超过1秒,写回当前数据,关闭再开维持当前档
如果不要维持当前档,去掉1秒后的那个写入 就可以了
依然要把延迟程序换成合适的,删除多余的组即可
延时计算器:
http://www.besttorch.com/viewthread.php?tid=863&extra=page%3D4
输入需要延时长度,比如1秒一次闪烁,那就是0.5秒延迟。
做一个子程序,替换掉那些调光PWM的NOP延时即可
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)