英锐恩单片机论坛,Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流

 找回密码
 立即注册
搜索
电子烟方案单片机单片机开发深圳单片机开发
单片机方案国产单片机8位单片机电子烟方案开发
查看: 5618|回复: 4
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
1#
发表于 2012-8-22 14:10:39 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
小小按键 大有学问!软件产生PWM与按键实时处理!---------PICC初学例子!
假设现在有个产品,要实现一个按键调节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);                                        //脉冲输出
      }   
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|公司首页|Microchip单片机,模拟器件,接口电路,麦肯单片机,单片机应用交流 ( 粤ICP备09008620号 )

GMT+8, 2024-11-24 01:54 , Processed in 0.051746 second(s), 26 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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