PIC12F629帮我用C语言写个程序,控制三个LED亮灭!

PIC12F629帮我用C语言写个程序,控制三个LED亮灭!,第1张

/******************************************************************************

 * 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外部中断 禁止

                             * 端口电平变化中断 禁止

                             * TMR0中断标志T0IF 清零

                             * 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延时即可


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11566977.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-17
下一篇2023-05-17

发表评论

登录后才能评论

评论列表(0条)

    保存