查看: 1329|回复: 0
打印 上一主题 下一主题

小小按键 大有学问!软件产生PWM与按键实时处理!

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-9 20:50:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
假设现在有个产品,要实现一个按键调节LED的亮度(PWM六档调光)。要以最低成平,体积要小,抗干扰最好。用PIC12C508A,最适合不过了。

方案实现如下:

按键功能:
    一个普通的IO口接上拉电阻输入,通过按键拉地。按键低电平有效,高电平无效。
每按一下占空比增加一档。长按无效,第次增加一档。要防止干扰。

调光功能:
    一个普通的IO口外接三极管驱动LED,由于单片机没有PWM模块,没有中断功能。只能用软件产生PWM信号。


   我们都知道用软件产生PMW 是占用单片机太多的时间,系统很难做其它工作。要如何实时处理按键功能,要多下
功夫才行。

编译软件为HI-PICC。

为了方面调试,先使用可擦写的PIC16F84A调试源程序,成功后再移值到PIC12C508A单片机系统。

《按键实时处理流程》

声明申请两个标志  1,有效标志   2,完成标志  为静态私有,初始化只清零一次。

一,判断有效标志是否等于 1。是,向下执行。否,跳到二处。

    判断按键是否等于     0。是,向下执行。否,跳到三处。

    判断完成标志是否等于 0。是,向下执行。否,按键长按,无效退出。

    按键有效,增加占空比。完成标志置为 1。退出。

二,判断按键是否等于 0。是,置有效标志为 1。否,没有按键退出。

三,按键受干扰,或按键弹开。清所有标志,退出。

《软件产生PWM流程》

一,根据占空比计算高电平延时,低电平延时。
    输出高电平,软件产生高电平延时。
    输出低电平,软件产生低电平延时。
二,循环执行约20毫秒,后退出。

《主程序主作流程》

一,调用初始化子程序.
二,调用按键处理子程序。
三,调用软件产生PWM子程序。
四,循环执行 二,三。


C源程序

/引入头文件*********************************************************
#include      <pic1684.h>

//脚位定义***********************************************************
#define       key       RA3                                //按键输入
#define       led       RB0                                //输出指示

//*******************************************************************
//函数名称:port_init();
//输入参数:无
//输出参数:无
//功能描述:端口设置
//建造日期:2008.06.03
//*****************************************************************
void PortInit(void)
{
     PORTA = 0xfd;                                         //  
     TRISA = 0xfd;                                         //A 口设置   
     
     PORTB = 0x00;                                         //
     TRISB = 0x00;                                         //B 口设置
}

//*******************************************************************
//函数名称:KeyInt(*p);
//输入参数:占空比地址
//输出参数:无
//功能描述:按键处理函数
//建造日期:2008.06.03
//*******************************************************************
void KeyInt(unsigned char *p)
{   
     static bit valid = 0;                                 //有效标志
     static bit finish = 0;                                //完成标志
     
     if (valid == 1)
      {
       if (key == 0)
        {
         if (finish == 0)
          {
           finish = 1;                                     //完成置位
           
           if (*p == 251)
            {
             *p = 0x01;                                    //按键有效
            }
  
           else
            {
             *p += 50;                                     //按键有效
            }
          }
        }
     
       else
        {
         valid = 0;                                        //有效清零
         finish = 0;                                       //完成清零
        }  
      }
      
     else
      {
       if (key == 0) valid = 1;                            //有效置位
      }
}

//*******************************************************************
//函数名称:LedPwm(Pwm);
//输入参数:占空比
//输出参数:无
//功能描述:led 脉冲调宽输出
//建造日期:2008.06.03
//*******************************************************************
void LedPwm(unsigned char Pwm)
{
     unsigned char PwmH;
     unsigned char PwmL;
     unsigned char i;
   
     
     for (i = 0; i < 20; i++)
      {
       PwmH = Pwm;                                         //脉冲高位
       PwmL = 255 - PwmH;                                  //脉冲低位

       led = 1;                                            //
       while (PwmH--);                                     //高位输出
     
       led = 0;                                            //
       while (PwmL--);                                     //低位输出
      }        
}

//*******************************************************************
//函数名称:main();
//输入参数:无
//输出参数:无
//功能描述:主要程序
//建造日期:2008.06.03
//*******************************************************************
void main(void)                                            //
{   
     unsigned char Pwm = 0x01;                             //占空初值      

     PortInit();                                           //脚位设置
   
     while (1)
      {
       KeyInt(&Pwm);                                       //按键处理
       LedPwm(Pwm);                                        //脉冲输出
      }  
}


(原文件名:KeyInt1.jpg)


(原文件名:KeyInt2.jpg)

经过产品实测PWM频率约为1KHZ.在按键按下,弹起,长按.灯光不出现闪烁.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

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