微软公司宣布不再支持你正在使用的 IE浏览器,这会严重影响浏览网页,请使用微软最新的Edge浏览器
您好, 登录| 注册|

自制玩意4——基于PIC12F实现RGB调色+调光、FADE+调速、EEP存储

  • 2014-06-21 17:42
  • daihui713

    LV.0
  • 1.4w

    浏览

  • 56

    回复

  • 0

    获赞

  •     本人电源工程师一枚,一直从事于LED驱动开发的行当,细数也近6年了,对于单片机的学习也是近期工作所需,硬着头皮上,充其量只是入

         门,更谈不上什么高手。

        此款RGB产品早在五年前便已流行于整个市场,路人皆知,在当时此款24KEY的面板遥控器似乎成了通用遥控器,五年之后的现在,市场价值荡然无存,现也难觅它的踪影。为了留住过往,特自制此玩意,以此纪念!

          也是机缘巧合,当时是拜读了乐云兄发的《LED全彩遥控控制器(C语言程序+电路原理图+PCB版图)整套 原创.. 》这个帖子后,就冲动了想弄个出来玩玩,在此得感谢乐云兄。完成这个确实花了不少功夫,特别是在解码这部分,以及配色。光解码程序就做了几种尝试,无论你是外部中断查询,还是主函数查询都只能写大部分的功能,譬如调光、变色、颜色跳变这些都可以用定时器来实现,但是有一个FADE平滑渐变的功能,适合用循环的方式来实现,如果用外部中断或主函数查询法解码你将很难或无法实现,因为太多的PWM需要变换将会拖累定时器。所以最终尝试第三种解码方式定时器查询法便解决这所有的问题。

         品名:24KEY型RGB灯

         遥控器型号:暂且叫1616(24KEY型)

         单片机型号:Microchip PIC12F1822(带EEP),8引脚,8M内置振荡,如果使能PLL功能4倍,最大到32M

    同是电子工程师,请一定不要吝啬你的赞!

    0人已赞

    编辑 举报

    LV.1

    4099081

    1494232

    50

    312503

    说说你的看法

  • LV.

    @

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    取消
    发送
  • 现在还没有回复呢,说说你的想法

    现在还没有回复呢,说说你的想法

    全部回复(56)

  • 轩航电子_ricky

    LV.1

    2015-08-02 18:31

    @

    默默为楼主点个赞
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4113587

    1494232

    50

    634288

    取消
    发送
    42
  • hjxz001

    LV.1

    2015-09-29 06:56

    @daihui713

    以下程序为史上红外解码最精简程序示例——摘自阿莫论坛

    ——利用定时器的固定时基来查询红外脉冲的宽度,从而进行解码!

    大家可以自己去分析,至于中间的高电平是多少时间,低电平是多少时间都不用去管,只需计算两个下降沿间隔时间就可以判断0和1,同时也可以判断是否是引导码,或是结束码,或是连续码

    定时器查看时间设置为125us,执行定时器中断程序一次

    void Timer0 interrupt 1()                                                            

    {      

            irTime++;   

            if(irTime==240) // ir解码后码值存放时间, 240*125us = 30ms   

           {

                 irTime--;  

                 codeCnt=0x3f;

           }       

           if(IR_IO)   Irprot_LastState=1; // 记录IO状态   

           else if(Irprot_LastState)       // 有下降沿 

           {      

                  Irprot_LastState = 0;        // 下降沿后IO状态记录为0      

                  if(irTime<24)                // 小于24*125us=3ms的间隔才进行处理      

                 {         

                        codeCnt++;  

                        codeCnt &= 0x1f;         

                        IR_data[codeCnt>>3] <<= 1;       

                        if( irTime>15)   

                        IR_data[codeCnt>>3]++;  // 大于15*125us=1.875ms的间隔为数据1      

                 }    

                 irTime = 0;                  // 下降沿处理完成,将时间清0   

            }

    }

     

    楼主 初级试验程序讲这么详细,关键的这么经典的程序,了了几笔,为什么不能把精髓讲透彻点,让我们这些门外汉也能学习到根本
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4115333

    1494232

    50

    540986

    取消
    发送
    43
  • hjxz001

    LV.1

    2015-10-07 10:52

    @daihui713

    以下程序为史上红外解码最精简程序示例——摘自阿莫论坛

    ——利用定时器的固定时基来查询红外脉冲的宽度,从而进行解码!

    大家可以自己去分析,至于中间的高电平是多少时间,低电平是多少时间都不用去管,只需计算两个下降沿间隔时间就可以判断0和1,同时也可以判断是否是引导码,或是结束码,或是连续码

    定时器查看时间设置为125us,执行定时器中断程序一次

    void Timer0 interrupt 1()                                                            

    {      

            irTime++;   

            if(irTime==240) // ir解码后码值存放时间, 240*125us = 30ms   

           {

                 irTime--;  

                 codeCnt=0x3f;

           }       

           if(IR_IO)   Irprot_LastState=1; // 记录IO状态   

           else if(Irprot_LastState)       // 有下降沿 

           {      

                  Irprot_LastState = 0;        // 下降沿后IO状态记录为0      

                  if(irTime<24)                // 小于24*125us=3ms的间隔才进行处理      

                 {         

                        codeCnt++;  

                        codeCnt &= 0x1f;         

                        IR_data[codeCnt>>3] <<= 1;       

                        if( irTime>15)   

                        IR_data[codeCnt>>3]++;  // 大于15*125us=1.875ms的间隔为数据1      

                 }    

                 irTime = 0;                  // 下降沿处理完成,将时间清0   

            }

    }

     

    IR_data[codeCnt>>3] <<= 1

    楼主 为什么codeCnt右移3位?   当codeCnt=1的时候右移3位不是出错了吗? 

    1

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4115412

    1494232

    50

    540986

    取消
    发送
    44
  • daihui713

    LV.1

    2015-10-09 13:45

    @hjxz001

    IR_data[codeCnt>>3] <<= 1

    楼主 为什么codeCnt右移3位?   当codeCnt=1的时候右移3位不是出错了吗? 

    这位同学,你没有细看哦。codeCnt表示红外码的长度——32位码(0x00——0x1F),IR_data是定义的一个数组{用户码;用户反码;数据码;数据反码},此时codeCnt就是IR_data的指针,codeCnt>>3意思就是除法,除以8,然后IR_data[codeCnt>>3]就表示存放在IR_data数组里面的第几组数据。

     当codeCnt=1的时候右移3位后,等于0,不会出错,存放在IR_data0[0]里面,也就是用户码。只有当codeCnt加到8的时候此时就是00001000,然后右移3位,等于1,此时就开始接收第二组数据了。

     

     希望你能看的明白,我能说的就是这么多了,欢迎随时发言

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4115460

    1494232

    50

    312503

    取消
    发送
    45
  • wwpp

    LV.1

    2015-11-22 13:30

    @轩航电子_ricky

    默默为楼主点个赞
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4117074

    1494232

    50

    281962

    取消
    发送
    46
  • A_lanmao

    LV.1

    2015-11-28 18:50

    @daihui713

    一般多用于景观灯(非照明类),RGB射灯居多
    看了楼主的分析,很透彻,程序框架也很清晰,不过怎么没看到彩灯颜色渐变和闪变的子程序呢?
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4117271

    1494232

    50

    648040

    取消
    发送
    47
  • A_lanmao

    LV.1

    2015-11-28 18:55

    @daihui713

    一般多用于景观灯(非照明类),RGB射灯居多
    有一个问题要问楼主,因为没看到楼主的颜色渐变子程序,如果颜色渐变子程序中有延时,且延时较长时,红外遥控同时进行控制,会不会出现灯光变化滞后现象?
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4117272

    1494232

    50

    648040

    取消
    发送
    48
  • daihui713

    LV.1

    2015-12-23 09:32

    @A_lanmao

    有一个问题要问楼主,因为没看到楼主的颜色渐变子程序,如果颜色渐变子程序中有延时,且延时较长时,红外遥控同时进行控制,会不会出现灯光变化滞后现象?
    如果只是让延时程序这个循环空转,不做任何按键码的判断,那么肯定会灯光滞后的。  如果你在delay函数中加入按键码判断,譬如每个10ms判断一下,如有更新按键码,那么就立即break循环。  这样的话就不会有灯光滞后现象了。  总的来说,不要让你的循环空转
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4118158

    1494232

    50

    312503

    取消
    发送
    49
  • zgj920626

    LV.1

    2016-01-15 10:15

    @daihui713

    以下程序是利用定时器中断红外解码来实现24键的遥控功能(带EEP存储),所有功能都在主函数中完成。
    由于采用函数套函数的方式,相比上面第一次,程序显得精简了很多
     
    下面是主函数部分,不包含子函数和定时器中断解码函数
    #include  
    #define uchar unsigned char
    #define uint  unsigned int
    #define IRIN RA2
    #define IRIN_HIGH() RA2=1
    #define red 0x1D
    #define green 0x0F
    #define blue 0x2D
    #define RG 0x1F
    #define GB 0x2F
    #define BR 0x3D
    __CONFIG(0xF9C4);
    __CONFIG(0xDCFF);
    const uchar six_colour[6]={0x1D,0x0F,0x2D,0x1F,0x3D,0xFF};
    uchar IR_data[4]={0x00,0x00,0x00,0x00};
    bit down_mark,start,codebit_ok;
    uchar IR_code=0,num=3,num_1=5,a=1;
    uint E,fade_1,fade_2,fade_3,fade_4;
    void delay_ms(uint x,uchar w);
    void port_init();
    void timer2_init();
    void fade_pwm(uchar F,uchar G,uchar H);
    void colour_PWM(uchar BILI,uchar colourAB,uchar colourA);
    void fade();
    void strobe();
    void danse_flash(uchar six_x,uchar code_x);
    void EEPROM_write(uchar date,uchar addr);
    uchar EEPROM_read(uchar addr);
    void main()
    {  
    port_init();
    IR_code=EEPROM_read(0x01);
    if(IR_code>24)IR_code=0; 
    num=EEPROM_read(0x02);
    if(num>6)num=3; 
    num_1=EEPROM_read(0x03);
    if(num_1>12)num_1=6; 
    timer2_init();  
    IRIN_HIGH(); 
    while(1)
    {
            if(a)
            {
                    if(IR_code!=0)
                    {
                            switch(IR_code)
                            {
                                    case  0x04:
                                            while((a)&&(IR_code==0x04))colour_PWM(2,red,red);        //单色红
                                            break;
                                    case  0x05:
                                            while((a)&&(IR_code==0x05))colour_PWM(2,green,green);  //单色绿
                                            break;
                                    case  0x06:
                                            while((a)&&(IR_code==0x06))colour_PWM(2,blue,blue);  //单色蓝
                                            break;
                                    case  0x07:
                                            while((a)&&(IR_code==0x07))colour_PWM(2,0xFF,0xFF);   //单色白
                                            break;
                                    case  0x08:
                                            while((a)&&(IR_code==0x08))colour_PWM(11,RG,red);   
                                            break;
                                    case  0x09:
                                            while((a)&&(IR_code==0x09))colour_PWM(11,GB,green);
                                            break;
                                    case  0x0A:
                                            while((a)&&(IR_code==0x0A))colour_PWM(11,GB,blue);
                                            break;
                                    case  0x0C:
                                            while((a)&&(IR_code==0x0C))colour_PWM(8,RG,red);
                                            break;
                                    case  0x0D:
                                            while((a)&&(IR_code==0x0D))colour_PWM(3,GB,green);
                                            break;
                                    case  0x10:
                                            while((a)&&(IR_code==0x10))colour_PWM(5,RG,red);
                                            break;
                                            case  0x11:
                                            while((a)&&(IR_code==0x11))colour_PWM(2,GB,blue);
                                            break;
                                            case  0x14:
                                            while((a)&&(IR_code==0x14))colour_PWM(2,green,red);       //混色黄色
                                            break;
                                    case  0x15:
                                            while((a)&&(IR_code==0x15))colour_PWM(5,GB,blue);
                                            break;
                                    case  0x0B:                      //三基色跳变FLASH
                                            danse_flash(3,0x0B);
                                            break;
                            }
                            switch(IR_code)
                            {
                                    uchar w;
                                    case  0x0E:
                                            while((a)&&(IR_code==0x0E))colour_PWM(11,BR,red);
                                            break;
                                    case  0x0F:                                    //七色跳变FLASH+6色呼吸渐变FADE
                                            for(w=0;w<5;w++)           
                                            {
                                                    if((a==0)||(IR_code!=0x0F))break;
                                                    danse_flash(6,0x0F);
                                            }
                                            for(w=0;w<5;w++)strobe();
                                            break;
                                    case  0x12:
                                            while((a)&&(IR_code==0x12))colour_PWM(5,BR,red);
                                            break;
                                    case  0x13: 
                                            while((a)&&(IR_code==0x13))fade();    //七色平湖过渡型渐变FADE
                                            break;
                                    case  0x16:
                                            while((a)&&(IR_code==0x16))colour_PWM(2,blue,red);    //混色紫色
                                            break;
                                    case  0x17:                                // //七色跳变FLASH
                                            danse_flash(6,0x17);
                                            break;
                                }
                    }
                    else colour_PWM(2,0xFF,0xFF);             //第一次开机 ON时 发白光
              }
             else PORTA=0x0D;
         }
    }
    colour_PWM()还有flash函数可以绣出来吗,正需要这个了,万分感谢
    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4118787

    1494232

    50

    650204

    取消
    发送
    50
  • 我系河边草

    LV.1

    2016-02-11 15:45

    @

    0

    设为最佳答案

    置顶

    编辑

    删除

    举报

    #该内容仅管理员可见#

    #回复内容已被删除#

    #该内容正在审核#

    回复:

    4119321

    1494232

    50

    552621

    取消
    发送
    51
  • 现在还没有回复呢,说说你的想法

     1 2 3 4 5 6  
  • 回复

  • 收藏

  • 点赞

  • 举报有害信息

  • 已超出发布时间24小时,无法编辑与删除
    关于我们 联系方法 广告服务 会议服务 电子星球APP 网站地图 不良信息举报 热线:400-003-2006
    © 2002-2023 Netbroad(网博互动)公司版权所有 津ICP备 11006234号-2 联网备案号:12010402000747 增值电信业务经营许可证:津B2-20120058