PIC12F629不用外振即可正常运行,低成本首选,原理如下:按键按一次LED1低亮,按两次LED2亮,按三次LED3亮,一直循环, 按键长按3秒松开则可以计入自动循环模式,再次长按3秒则退出,进入待机模式;2脚接轻触开关到地,可以做为设置键(原理图来自网上故VDD接﹢5V,漏画,SET设置键没有画,有时间修正下原理图),用来设置每个LED亮的时间,互不影响!源码已经编译通过,洞洞板做了一个PCB, 正常运行,新手贴勿喷。
单片机源程序如下:
/******************************************************************************
设计要求:按一次按键是打开第一个摄像头,按两次开第二个摄像头,按三次打开第三个摄像头,
长按3秒则开启循环模式,每次开启时间30秒,一直循环,直到按下按键为止.
* IC: PIC12F629 OSC: 片内4MHz
*****************************************************************************/
#include
#define uchar unsigned char
#define uint unsigned int
#define LED1 GPIO0
#define LED2 GPIO1
#define LED3 GPIO2
#define KEY GPIO4
#define SET GPIO5
__CONFIG(FOSC_INTRCIO & WDTE_ON & PWRTE_ON & MCLRE_OFF & BOREN_ON);
/********* 配置字 ************/
void interrupt ISR( void) ;
void delay(uint x);
void IOinit (void) ;
void TMR1init(void) ;
uint time = 0;
uint t =0;
uchar cnt =0;
uchar cnt1 = 0;
uchar cnt2 = 0;
uchar i , k = 0;
void IOinit (void)
{
PCON = 0X00; // 电源控制全关
CMCON = 0X07; //关模拟器
TRISIO = 0X38; // 00111000 GP<5:3>输入 GP<2:0>输出
GPIO = 0X3F; // 00111111 GP<2:0>输出高电平
WPU = 0X30; // GP<5:4>内部弱上拉开启
IOC = 0X30; //GP<5:4>端口电平变化中断使能
}
void TMR1init (void)
{
OPTION_REG = 0X0F; // PSA =1, PS2:PS0 =111 开看门狗 预分频128 其余的关
INTCON = 0XC0 ; // GIE = 1 , PEIE = 1 开全局中断 开外设中断 其余的关
PIE1 = 0X01; // 外设中断使能
PIR1 = 0X00; // TMR1IF = 1 开TIMR1 外设中断标志位,需要软件清零
TMR1H = 0X3C; //TIMER1初值 溢出时间是50000(50ms)
TMR1L = 0XB0; // 65536- 50000 = 15536 (0x3CB0)
T1CON = 0X01; // 开TIMR1
}
void main ( )
{
IOinit () ;
TMR1init() ;
//主循环
while(1)
{
if(i==0 )
{
if(SET==0)
{
delay(10);
if(SET==0)
{
while(!SET);
k=!k;
cnt=0;
cnt1=0;
LED3=!LED3;
}
}
}
if(KEY == 0) //如果按键按下
{
delay(20);
if(KEY == 0)
{
time = 0; //延时标志位清零
while(!KEY); //等待按键被松开,由中断函数计数
if(time<40) //按下时间不足50ms*40=2000毫秒(2秒)
{
if (k==0)
{
cnt1++; //按键次数加1,改变工作状态
if(cnt1>3) cnt1 = 0;
}
else if( k==1)
{
cnt++;
if (cnt>10) cnt=0;
t=cnt*100;
LED1 =0;
delay(20);
LED1 =1;
}
}
if(time >= 40 && time < 100) //按住时间2秒到5秒之间
{
i = !i;
time =0;
cnt2 =0;
cnt1=0;
}
else if (time >=100)
{
break;
}
}
}
if (k==0 )
{
if (i == 1)
{ switch (cnt2)
{ case 0:
GPIO =0X3E; //00111110 开1号继电器
break;