数码之家

 找回密码
 立即注册
搜索
查看: 1972|回复: 30

[C51] 自制电热毯控制器

[复制链接]
发表于 2022-7-2 15:52:37 | 显示全部楼层 |阅读模式
本帖最后由 cyj988 于 2022-7-2 16:11 编辑

老寒腿毛病导致夏天也得睡电热毯。在网上买的韩国电褥子没有其他的毛病就是有点太热。调到最低档也不行  还热。
利用手里现有的技术改造了一下,做个能控制通断的开关。说白了就是我要50%功率吧,就输出2秒关闭2秒。通过单片机控制想要的输出百分比。
单片机控制可控硅输出。
做的过程也没有拍照,做完了总结一下。
嘉立创免费做的线路板5块,成功的用掉2块了,下面的是其中一个。

以前社区买的门铃,门铃内部线路板另做它用了,外壳没舍得扔,利用上了。



手工开孔做的插座孔,里面的铜片是拆报废插座里面的。因为韩国电褥子插头都是圆柱型的,所以孔开的大,
现在是圆的扁的通用。

上电效果。

解说一下,上部是用led组合的数码管,由于第一次没有经验导致数码管得字体有点失真。不过看多了就能看懂显示的是几了。
现在显示的是21,晚上还会清晰点,这样也好,不至于在晚上刺眼。
调节按钮是用ec11 这个键帽使用以前做耳机配件用的铝制的帽,感觉还不难看,用胶水粘上的。
功能就是通过调节ec11数码显示00-99。00就是关闭没有输出,99就是一直输出,可以定时0-8小时开启时间,0.5小时一个档,
按键切换时间或功率比,每次调节完5秒按键没有动作把调节后的值保存在eeprom里,显示剩余时间5秒自动切换到显示功率比界面。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

打赏

参与人数 2家元 +20 收起 理由
jf201006 + 10 謝謝分享
玛德陛下 + 10 謝謝分享

查看全部打赏

 楼主| 发表于 2022-7-2 15:59:25 | 显示全部楼层
#include        <reg51.h>        // 定义8x51暂存器之标头档,P2-17~19
#include <intrins.h>
#define        SEG        P1                        // 定义七节显示器接至Port 2
//#define        SCANP        P3                // 定义扫瞄线接至Port 1
sbit  LED=P5^5;                        // 声明LED接至P0.7

#define uint unsigned int  
#define uchar unsigned char

/*声明T0计时相关声明*/  // THx TLx 计算参考
#define  count_M1   500        // T0(MODE 1)之计量值,0.05s
#define  TH_M1  (65536-count_M1)/256// T0(MODE 1)计量高8位元
#define  TL_M1  (65536-count_M1)%256// T0(MODE 1)计量低8位元
int count_T0=0;                                         // 计算 T0中断次数
/*声明T1扫瞄相关声明*/
//#define  count_M2   500                        // T1(MODE 2)之计量值,0.25ms
//#define  TH_M2  (65536-count_M2)/256        // T1(MODE 2)自动载入计量  
//#define  TL_M2  (65536-count_M2)%256        // T1(MODE 2)计数量
//uchar count_T1=0;                                // 计算 T1中断次数        
/* 声明七节显示器驱动信号阵列(共阳) */
                                //         0          1                2          3                4         5                6         7           8         9
char code TAB[]={        0x8a, 0xef, 0x96, 0xa6, 0xe3,0x22, 0x82, 0xee, 0x82, 0xa2,         //数字0-4
                                        0xdf, 0xdf, 0xdf, 0xdf, 0xdf,0xff, 0xff, 0xdf, 0xdf, 0xdf,
                                        0xa8,
                                         };        //数字5-9
uchar disp[4];        // 声明显示区阵列初始显示00
sbit P00=P3^2;//正转
sbit P01=P3^4;//反转
sbit P02=P3^5;//按下
sbit LS138A=P2^7;            //
sbit LS138B=P2^6;
sbit led1=P2^5;
/* 声明基本变量 */
char seconds;                        // 秒数
char bianma,shijian,gonglv;                        // 编码器数值
char i,b;
bit a=1,panduan=1;
  uint fen,aa,bb;
void delay(unsigned int cnt)//10为1ms
{
unsigned char i;
for(;cnt>0;cnt--)
for(i=0;i<111;i++);
}
  /****************特殊功能寄存器声明****************/
sfr ISP_DATA = 0xc2;   
sfr ISP_ADDRH = 0xc3;   
   sfr ISP_ADDRL = 0xc4;  
  sfr ISP_CMD = 0xc5;   
sfr ISP_TRIG = 0xc6;   
    sfr ISP_CONTR = 0xc7;
  void  cc(uint addr);
void  xcx(uint addr,uchar dat);
uchar dcx(uint addr);
void  Q0();
  void bianmaqi(void);

//==主程序================================
main()                                        // 主程序开始
{
//char panduan;

        IE=0x8a;                        // 1000 1010,启用TF0、TF1中断(6-4页)
        TMOD=0x20;                        // 0010 0000,T1采mode 2、T0采mode 0        16位自动重装
        TH0=TH_M1; TL0=TL_M1;// 设置T0计数量高8位元、低8位元
        TR0=1;                                // 启动T0(7-7页)
        T2H=0x9e; T2L=0x58;// 设置T2自动载入值、计数量
        AUXR=0X10;                          //  允许定时器2运行,12分频
        IE2=0X04;                                // 启动T2 ET2=1

         P2M0=0xc0;
         P2M1=0x00;
                               
        shijian=        dcx(0x0001);
        gonglv=        dcx(0x0005);

        while(1)
       
        {         
if(b==5&a==0)
   {  EA=0;
         SEG=0XFF;
         cc(0x0000);
         xcx(0x0001,shijian) ;
         xcx(0x0005,gonglv)          ;
         panduan=1;
         EA=1;


   a=1;}
         if(P02==0)
        { delay(30);
        while(P02==0);

         panduan=~panduan;       
         if(panduan==0)
         b=0;
                 }
         if(panduan==0)
         {         bianmaqi();
         shijian=bianma;
           seconds=shijian*5;
       
           if(shijian>16)
           shijian=0;
           if(shijian<0)
           shijian=16;               
           if(b==5)
           panduan=1;
          
          
          
            }
        else
        { bianmaqi();
        seconds=bianma;
         gonglv=bianma;
        if(gonglv>99)
        gonglv=0;
        if(gonglv<0)
        gonglv=99;//                                       
                        }                  
                         
}        }                                        // 主程序结束  
//== T0中断子程序- 计算并显示秒数 ==================

void T0_1s(void) interrupt 1        // T0中断子程序开始
{//        TH0=TH_M1; TL0=TL_M1;                // 设置T0计数量高8位元、低8位元
  
        if (++count_T0==2000)                        // 若中断20次,即0.05x20=1秒
        {        count_T0=0;                                // 重新计次
                b++;                                 // 秒数加1
                   fen++;
                if (b>5)                 // 若超过5秒
                        b=5;                        // 秒数归0,重新开始
                 if(fen==1800)
        {         fen=0;
                 shijian=shijian-1;                         //
                }                                                // i
        }                                                        // i
        disp[1]=(seconds/10);         // 填入十位数显示区
        disp[0]=(seconds%10);         // 填入个位数显示区
       
         

SEG=0xff;
    switch(i)                                          
             {            
       
                case 0:LS138A=0; LS138B=1;  break;         
             case 1:LS138B=0; LS138A=1;  break;                    
          
                       
             }

          SEG=TAB[disp[i]];

        i++;
        if(i==2)
          {
           i=0;
          
                 }


                  }

       
                                                                // T0中断子程序结束                
//===T1中断子程序 - 扫瞄 =========================                       

void T1_8ms(void) interrupt 12        // T1中断子程序开始
       
         {
                bb++;       
                if(bb==100)
                bb=0;
//        LED=~LED;;
//        }                               
if(shijian>0)

{        if(gonglv>bb)
       
        {        LED=0;
        led1=0;
                  }   
   
{        if(gonglv<bb)
        {                                                // if叙述结束(超过60秒)
        LED=1;
        led1=1;        }                                                // if叙述结束(中断20次)
        }           }
                           
   else
{
LED=1;
led1=1;          
fen=0;
        }
          }



//if (++aa==10)                        // 若中断20次,即0.05x20=1秒
//        {        aa=0;                                // 重新计次
                         
void cc(uint addr)

{  
// 打开 IAP 功能(ISP_CONTR.7)=1:允许编程改变Flash, 设置Flash操作等待时间
// 0x83(晶振<5M)   0x82(晶振<10M)   0x81(晶振<20M)   0x80(晶振<40M)   
ISP_CONTR = 0x81;   
    ISP_CMD   = 0x03;
        ISP_ADDRL = addr;   // 用户可以对"Data Flash/EEPROM区"进行扇区擦除     ISP_ADDRL = addr;         // ISP/IAP操作时的地址寄存器低八位,  
   ISP_ADDRH = addr>>8;      // ISP/IAP操作时的地址寄存器高八位。
  //EA =0;     
   ISP_TRIG = 0x5a;
   ISP_TRIG = 0xa5;         // 在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入5a,     ISP_TRIG = 0xB9;          // 再写入B9h,ISP/IAP命令才会生效。  
   _nop_();   
    Q0();           // 关闭ISP/IAP

}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:写一字节
入口:addr = 扇区单元地址 , dat = 待写入数据
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void xcx(uint addr,uchar dat)
{     
ISP_CONTR = 0x81;   
    ISP_CMD   = 0x02;       // 用户可以对"Data Flash/EEPROM区"进行字节编程     ISP_ADDRL = addr;        
     ISP_ADDRL = addr;
         ISP_ADDRH = addr>>8;   
     ISP_DATA  = dat;          // 数据进ISP_DATA   
// EA = 0;     
ISP_TRIG = 0x5a;   
   ISP_TRIG = 0xa5;      
  _nop_();   
Q0();       // 关闭ISP/IAP
}

/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:读一字节
入口:addr = 扇区单元地址
出口:dat  = 读出的数据  
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

uchar dcx(uint addr)
{      
   uchar dat;   
ISP_CONTR = 0x81;   
     ISP_CMD   = 0x01;         // 用户可以对"Data Flash/EEPROM区"进行字节读     ISP_ADDRL = addr;      
       ISP_ADDRL = addr;
           ISP_ADDRH = addr>>8;
//EA = 0;   
  ISP_TRIG = 0x5a;   
           ISP_TRIG = 0xa5;     
          _nop_();   
  dat = ISP_DATA;     // 取出数据
Q0();         // 关闭ISP/IAP
   return dat;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:关闭ISP/IAP操作
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Q0()
{   
  ISP_CONTR = 0;            // 关闭IAP功能
     ISP_CMD   = 0;            // 待机模式,无ISP操作   
   ISP_TRIG  = 0;            // 关闭IAP功能, 清与ISP有关的特殊功能寄存器
  ISP_ADDRH=0x80;
ISP_ADDRL =0;

}
void bianmaqi(void)
{ if(panduan==0)
   bianma=shijian;
   else
   bianma=gonglv;


  if(!P00) //如果p0.0口变为低电平
{
delay(20); //延时
if(!P00) //如果p0.0还是低电平
{
while(!P00); //等待p0.0变成高电平
while(P01); //等待p0.1变成低电平
delay(20); //延时
while(P01); //如果p0.1还是低电平
while(!P01); //等待p0.1变成高电平
bianma+=1; //计数加1
a=0;
b=0;
  }}
   if(!P01)
{
delay(20);
if(!P01)
{
while(!P01);
while(P00);
delay(20);
while(P00);
while(!P00);
bianma-=1;
a=0;
b=0;
  }
        }        }

打赏

参与人数 1家元 +16 收起 理由
数码家园 + 16

查看全部打赏

回复 支持 反对

使用道具 举报

发表于 2022-7-2 16:26:18 | 显示全部楼层
这几天不开空调室内得三十七八度了吧还开电热毯,这恐怕不是老寒腿范畴了吧!
回复 支持 反对

使用道具 举报

发表于 2022-7-2 16:31:49 | 显示全部楼层
LED显示的数字太佛系了,你说这是21?哈哈哈哈……
回复 支持 反对

使用道具 举报

发表于 2022-7-2 16:34:16 | 显示全部楼层
通过温度控制不好吗?
回复 支持 反对

使用道具 举报

发表于 2022-7-2 16:42:54 | 显示全部楼层
思路没毛病。
就是旋钮要用塑料的。
然后电热毯70W左右调整到35W。很多电扇调速器就可以实现了。
当然用单片机加可控硅光藕能实现更多功能。
回复 支持 反对

使用道具 举报

发表于 2022-7-2 17:01:12 | 显示全部楼层
真是个狠人,控制电热毯都用上单片机了。
回复 支持 反对

使用道具 举报

发表于 2022-7-2 17:01:31 | 显示全部楼层
老寒腿却实需要保暖,不过夏天晚上用护膝要方便舒服点吧
回复 支持 反对

使用道具 举报

发表于 2022-7-2 17:13:28 | 显示全部楼层
本帖最后由 davidjia 于 2022-7-2 17:16 编辑

实在看不出显示的是21  用单个的LED模拟数码管按数码管的笔画排列就可以了。可以去看看我的数码管。程序能顺利跑通,为电热毯用心了。支持折腾。
回复 支持 反对

使用道具 举报

发表于 2022-7-2 17:33:54 | 显示全部楼层
买个两位的数码管也就是块把钱的事,有些还包邮呢。
回复 支持 反对

使用道具 举报

发表于 2022-7-2 18:25:37 | 显示全部楼层
控制电热毯都用上单片机了
回复 支持 反对

使用道具 举报

发表于 2022-7-2 18:44:33 | 显示全部楼层
我一直也想做一个,但是太懒了,后来使用了一个盐袋热敷包那种调温控制器进行改造,效果也不错!
回复 支持 反对

使用道具 举报

发表于 2022-7-2 19:53:20 | 显示全部楼层
哈哈,搞的不错
回复 支持 反对

使用道具 举报

发表于 2022-7-2 19:55:27 | 显示全部楼层
哈哈,这数字真的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:07:12 来自手机浏览器 | 显示全部楼层
hujj 发表于 2022-7-2 17:33
买个两位的数码管也就是块把钱的事,有些还包邮呢。

考虑成本还要考虑空间,想着贴片的led能节省空间才做的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:09:01 来自手机浏览器 | 显示全部楼层
feetprint 发表于 2022-7-2 18:25
控制电热毯都用上单片机了

stc15f408自己用成本不高
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:11:20 来自手机浏览器 | 显示全部楼层
danqrs 发表于 2022-7-2 16:42
思路没毛病。
就是旋钮要用塑料的。
然后电热毯70W左右调整到35W。很多电扇调速器就可以实现了。

电源用的是手机充电器改的,高低压隔离,输出用的是光耦控制,应该不会漏电吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:16:48 来自手机浏览器 | 显示全部楼层
铃兰花匠 发表于 2022-7-2 16:26
这几天不开空调室内得三十七八度了吧还开电热毯,这恐怕不是老寒腿范畴了吧! ...

腿不热乎点就会有点不舒服
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:19:16 来自手机浏览器 | 显示全部楼层
jpdd521 发表于 2022-7-2 16:34
通过温度控制不好吗?

控制温度还要增加温度检测部件,关键是要增加两根电线,感觉有点麻烦。这个简单
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-2 20:21:06 来自手机浏览器 | 显示全部楼层
人艰不拆了 发表于 2022-7-2 19:55
哈哈,这数字真的

再有机会做线路板肯定会有所改善的。
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-28 04:14 , Processed in 0.327601 second(s), 15 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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