单片机
返回首页

单片机LED调光程序,状态机按键处理,效果比较好

2020-11-21 来源:51hei

用状态机处理按键,终于把这个功能实现了;实验板上测试通过。
/* ********************************************************************************************* */
// 处理器   : STC89C52RC
// 编译环境 : Keil4 C51
// 系统时钟 : 11.0592MHZ
// 简单描述 : 1个独立按键,短按开关LED灯,长按调光,如果按住按键不放,LED亮度从 亮-->暗,暗-->亮,循环。
/* ********************************************************************************************* */
#include
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;

                                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();        //不停的检测按键是否被按下
        }

}

进入单片机查看更多内容>>
相关视频
  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • 串联电容降压变换器的设计

  • 医疗监护和可穿戴设备

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 新唐 8051单片机教程

    相关电子头条文章