http://power.baidu.com/question/240873584599025684.html?entry=browse_difficult

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

2014-12-31 16:05DINZEYU  分类:C/C++ | 浏览 87 次
 C语言VC++

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

按键按一次LED1低亮,按两次高亮,按三次2HZ闪,按三次关,按键长按3秒松开LED2亮,长按3秒松开LED2灭,按键长按5秒松开LED3亮,长按5秒松开LED3灭,每个功能独立操作,互不影响!

分享到:

 
2015-01-01 22:52

 

提问者采纳

热心网友
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/******************************************************************************
 * 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;
    }
}
追问:
非常感谢,请问这个程序直接烧录进单片机就能正常工作吗?
追答:
编译后烧录就可以
提问者评价
太给力了,你的回答完美的解决了我的问题!
05-06 19:33