找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4499|回复: 10
打印 上一主题 下一主题
收起左侧

单片机LED调光程序问题

  [复制链接]
跳转到指定楼层
楼主
ID:140489 发表于 2017-4-19 14:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在用一个按键可以实现开灯、关灯,长按可以调光,但是调光要在关灯后,按一次按键开灯,在1秒内接着长按就可以调光,如果大于1秒再按按键就成关灯了;请大神帮忙看一下,怎么写才能做到,短按开关灯,在开灯的时候,随时长按都能进入调光状态。
/*led1用高色温, led2用低色温,key_S2按键短按开关灯,长按调光调色温 ,led1和led2的状态相反
无级调光 ,亮到暗,暗到亮      

*/
#include <reg52.h>
unsigned char pwm_led_val = 0;//LED占空比值  0最亮
unsigned char pwm_t;// 周期
sbit led1 = P1^0;        //定义LED端口
sbit led2 = P1^7;
sbit key_s2 = P3^0;         //定义按键端口
void delay(unsigned int z)//毫秒级延时
{
        unsigned int x,y;
        for(x = z; x > 0; x--)
                for(y = 114; y > 0 ; y--);
}        

//定时器0中断
void timer0() interrupt 1
{
        pwm_t++;
        if(pwm_t == 40)
        {
                pwm_t = 0; led1 = 1;        led2 = !led1;
        }
        if(pwm_led_val == pwm_t)
                led1 = 0; led2 = !led1;                                         
}
void main()
{   
        bit flag;          //亮度标志位

        TMOD |= 0x02;//8位自动重装模块
        TH0 = 240;
        TL0 = 240;//
        TR0 = 1;//启动定时器0
        ET0 = 1;//允许定时器0中断
        EA        = 1;//总中断允许
        while(1)
        {
                  if(key_s2 == 0)
                   {
                    delay(10);
                    if(key_s2 == 0)         //确认按下

                     {
                           TR0 = !TR0;
                           P1 = 0xff;         //开关灯
                           delay(100);          //延时长一点
                             while(!key_s2) //如果按键还处于按下状态,就进入调光
                           {
                              delay(10);

                                
                                        if(flag==0)
                                        {
                                                   if(pwm_led_val < 40)
                                                {
                                                        pwm_led_val++;                        //变暗
                                                        if(pwm_led_val >= 40)
                                                                flag=1;
                                                }
                                          }
                                 
                                  if(flag==1)
                                  {
                                           if(pwm_led_val > 0)
                                          pwm_led_val--;          //变亮
                                          if(pwm_led_val <=0)
                                            flag=0;
                                  }         
                                 }
                                 
                                 
                                }
                          }
                    
                 }
                 
  }         


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:191208 发表于 2017-4-19 16:06 | 只看该作者
写的还是挺好的
回复

使用道具 举报

板凳
ID:191208 发表于 2017-4-19 16:07 | 只看该作者
还有别的代码源程序吗
回复

使用道具 举报

地板
ID:190228 发表于 2017-4-19 18:03 | 只看该作者
写的挺好的
回复

使用道具 举报

5#
ID:165962 发表于 2017-4-19 18:23 | 只看该作者
应该没有问题的
回复

使用道具 举报

6#
ID:140489 发表于 2017-4-20 08:50 | 只看该作者
怎么没有高手来看一下呢?这个问题困扰我好长时间了
回复

使用道具 举报

7#
ID:140489 发表于 2017-4-21 13:29 | 只看该作者
用状态机的编程思路,终于把这个功能实现了
/* ********************************************************************************************* */
// 处理器   : STC89C52RC
// 编译环境 : Keil4 C51
// 系统时钟 : 11.0592MHZ
// 简单描述 : 1个独立按键,短按开关灯,长按调光
/* ********************************************************************************************* */
#include<reg52.h>
typedef unsigned char uChar8;
typedef unsigned int  uInt16;
                                         /*初始状态  确认状态   单击状态    连发状态 */
typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};//键值状态值
uChar8 pwm_led_val = 0;         //LED占空比值 0-20 0最亮
uChar8 pwm_t;                                 //周期
sbit KEY1 = P3^0;                        //定义按键端口
sbit LED = P1^0;                        //定义LED灯端口

void Timer0Init(void)
{
        TMOD |= 0x02;                        //设置定时器0工作模式2,8位自动重装
        TH0 = 240;                                //定时器装初值
        TL0 = 240;                                //11.0592M晶振下占空比最大比值是20,输出2880HZ
        EA = 1;                                        //开总中断
        ET0 = 1;                                //开定时器0中断
        TR0 = 1;                                //启动定时器0
}
void Timer1Init(void)
{
        TMOD |= 0x10;                        // 设置定时器1工作模式1,16位计数器
        TH1 = 0xDC;                                // 赋初始值
        TL1 = 0x00;                                // 11.0592M晶振下,定时10ms
        TR1 = 1;                                // 启动定时器1
}

/* ***************************************************** */
// 函数名称:        Init()
// 函数功能:   初始化
// 入口参数:        无
// 出口参数:         无
/* ***************************************************** */
void Init()                                        //初始化
{
        Timer0Init();
        Timer1Init();
               
}

//定时器0中断
void timer0() interrupt 1
{
        pwm_t++;
        if(pwm_t == 20)
        {
                pwm_t = 0; LED = 1;
        }
        if(pwm_led_val == pwm_t)
                LED = 0;                                         
}


/* ***************************************************** */
// 函数名称:KeyScan(void)
// 函数功能:扫描按键
// 入口参数:无
// 出口参数:键值(num)
/* ***************************************************** */
void KeyScan(void)
{
        static uChar8 KeyStateTemp1 = 0;                        //按键状态临时存储值1
        static uChar8 KeyTime = 0;                                        //按键延时时间
        bit KeyPressTemp1;                                                        //按键是否按下存储值1
        bit falg;                                                                        //亮度标志

        KeyPressTemp1 = KEY1;                                                //读取I/O口的键值
        switch(KeyStateTemp1)
        {       
                case StateInit:                                                        //按键初始状态
                        if(!KeyPressTemp1)                                        //当按键按下,状态切换到确认态
                                KeyStateTemp1 = StateAffirm;
                        break;
               
                case StateAffirm:                                                //按键确认态
                        if(!KeyPressTemp1)
                        {
                                KeyTime = 0;
                                KeyStateTemp1 = StateSingle;        //切换到单次触发态       
                        }
                        else KeyStateTemp1 = StateInit;         //按键已抬起,切换到初始态
                        break;
       
                case StateSingle:                                                //按键单发态
                        if(KeyPressTemp1)                                        //按下时间小于1s
                        {
                                KeyStateTemp1 = StateInit;          //按键释放,则回到初始态
                                                TR0 = !TR0;
                                                LED = 1;                                //关闭LED
               
                        }
                        else if(++KeyTime > 100)                        //按下时间大于1s(100*10ms)
                        {
                                KeyStateTemp1 = StateRepeat;        //状态切换到连发态
                                KeyTime = 0;       
                        }
                        break;
               
                case StateRepeat:                                                //按键连发态               
                        if(KeyPressTemp1)
                                KeyStateTemp1 = StateInit;                //按键释放,则进初始态
                        else                                                                //按键未释放
                        {
                                if(++KeyTime > 10)                                //按键计时值大于100ms(10*10ms)
                                {
                                        KeyTime = 0;       
                                                if(falg == 0)
                                                {
                                                        if(pwm_led_val < 20)
                                                        {
                                                                pwm_led_val++;        //亮度变暗
                                                                if(pwm_led_val==20)
                                                                        falg = 1;
                                                        }
                                                }

                                                if( falg ==1 )
                                                {
                                                        if(pwm_led_val > 0)
                                                        {
                                                                pwm_led_val--;        //亮度变亮
                                                                if(pwm_led_val==0)
                                                                        falg = 0;
                                                        }
                                                }
                                }
                                break;
                        }
                        break;
               
                default: KeyStateTemp1 = KeyStateTemp1 = StateInit; break;
        }
}


/* ***************************************************** */
// 函数名称:ExecuteKeyNum(void)
// 函数功能:按键值来执行相应的动作
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void ExecuteKeyNum(void)
{
        if(TF1)                                        //定时器1溢出
        {
                TF1 = 0;
                TH1 = 0xDC;
                TL1 = 0x00;
                KeyScan();
        }
}


void main()
{
        Init();                                        //首先初始化各数据
        while(1)                                //进入主程序大循环
        {
                ExecuteKeyNum();        //不停的检测按键是否被按下
        }

}
回复

使用道具 举报

8#
ID:47933 发表于 2017-4-23 10:19 | 只看该作者
真厉害,一个键这么多功能
回复

使用道具 举报

9#
ID:192838 发表于 2017-4-23 21:22 | 只看该作者
好强啊
回复

使用道具 举报

10#
ID:417131 发表于 2019-7-31 15:29 | 只看该作者
LED调光效果很重要,一般用指数调光方式。
回复

使用道具 举报

11#
ID:511461 发表于 2019-8-1 09:10 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表