找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11786|回复: 15
收起左侧

STC15F104W单片机红外排插详细制作步骤 附源程序

  [复制链接]
ID:424598 发表于 2018-12-7 22:18 | 显示全部楼层 |阅读模式
首先上原理图
红外单片机控制插座设计图.png
红外单片机的制作方法,我这里就不细说了,请看我之前发的几个贴子,有原理图(你只要制做红外部分,继电器直接用一个低电平的即可)

以下是制作好的图
IMG_20181207_212529.jpg


接上220V降5V模块
IMG_20181207_212545.jpg


制作完毕,准备测试
IMG_20181207_212502.jpg


插入排座,接上手机
IMG_20181207_212102.jpg


红外遥控器开启电源
IMG_20181207_212109.jpg


手机开始充电
IMG_20181207_212116_1.jpg


由于是旧手机,所以这里显示充电的电流较低
IMG_20181207_212152.jpg


数码管有倒计时,倒计时结束自动断电
IMG_20181207_212207.jpg


给模块安个漂亮的外壳
IMG_20181207_214017.jpg


附件较上一个版本进行了优化
1.有源蜂鸣器改成无源蜂鸣器
2.数码管倒计时功能增加
  a、在原每次增加30分钟的基础上,增加了+10分钟,-10分钟,+1分钟,-1分钟,共四个新按键
  b、原倒计时只显示时钟和分钟,现改成如果时间大于1小时则显示时钟+分钟,如果时间小于60分钟,则显示分钟+秒钟
遥控器按键说明1.jpg    20键迷你遥控器码图1.jpg

单片机源程序如下:
  1. /*
  2. 1  IRC_CLKO/INT2/CLKOUT1/T0/RST/P3^4                   8  RSTOUT_LOW/INT1/P3^3
  3. 2  VCC(5V)                                                                           7  INT0/P3^2
  4. 3  INT3/CLKOUT0/T1/P3^5                                                   6  P3^1/TXD
  5. 4  GND                                                                                   5  INT4/P3^0/RXD
  6. 烧录时,烧录器的VCC接2脚,TXD接5脚,RXD接6脚,GND接4脚
  7. */
  8. //////STC15F104////////////
  9. #include <STC15F2K60S2.H>
  10. #include <intrins.h>
  11. #define uchar unsigned char
  12. #define uint unsigned int
  13. #define T50MS (65536-50000) //12T模式

  14. /*************        用户系统配置        **************/
  15. //烧录频率请选12.000MHz
  16. #define MAIN_Fosc                12000000L        //定义主时钟, 模拟串口和红外接收会自动适应。5~36MHZ

  17. #define D_TIMER0                125                        //选择定时器时间, us, 红外接收要求在60us~250us之间

  18. #define        User_code                0x00FF                //定义红外接收用户码(38K的迷你遥控器通用)


  19. /*************        以下宏定义用户请勿修改        **************/
  20. #define freq_base                        (MAIN_Fosc / 1200)
  21. #define Timer0_Reload                (65536 - (D_TIMER0 * freq_base / 10000))

  22. /*************        本地变量声明        **************/
  23. bit                P_IR_RX_temp;                //Last sample
  24. bit                B_IR_Sync;                        //已收到同步标志
  25. uchar        IR_SampleCnt;                //采样计数
  26. uchar        IR_BitCnt;                        //编码位数
  27. uchar        IR_UserH;                        //用户码(地址)高字节
  28. uchar        IR_UserL;                        //用户码(地址)低字节
  29. uchar        IR_data;                        //数据原码
  30. uchar        IR_DataShit;                //数据反码

  31. bit                B_IrUserErr;                //User code error flag
  32. bit                B_IR_Press;                        //Key press flag,include repeat key.
  33. uchar        IR_code;                        //IR code        红外键码

  34. /*注:此处数码管只支持四针的TM1637数码管*/
  35. sbit CLK=P3^4; //接四针数码管的CLK脚
  36. sbit DIO=P3^3; //接四针数码管的DIO脚
  37. sbit KG    =P3^1;                        //开关(接LED负极,LED正极接VCC 或 接继电器IN口)
  38. sbit FMQ   =P3^0;                        //蜂鸣器(接蜂鸣器负极,蜂鸣器正极接VCC)
  39. sbit P_IR_RX    =P3^2;           //定义红外接收输入端口
  40. uint i2,shi,fen,miao; //shi=时,fen=分,miao=秒
  41. uint i1,ontime,offtime; //ontime=开启时间,offtime=关闭时间
  42. uchar k,data1=0x01; //k=模式值
  43. bit b;
  44. //uchar a[4];    //储存用户码、用户反码与键数据码、键数据反码

  45. //数码管
  46. uint smg_ge,smg_shi,smg_bai,smg_qian,dadt;
  47. unsigned char code xsbcdbuf[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77}; //0-9及二个点

  48. /*************        本地函数声明        **************/
  49. /////////////////////  以下是数码管显示部分   /////////////////////
  50. void IIC_delay(void) //IIC延时
  51. {
  52.     unsigned char i;
  53.     for(i=0;i<20;i++) _nop_();
  54. }
  55. void start_IIC(void) //启动IIC

  56. {
  57.     CLK=1; //给芯片发送开始信号
  58.     DIO=1;
  59.     IIC_delay();
  60.     DIO=0;
  61.     IIC_delay();
  62.     CLK=0; //开始信号传送完
  63.     IIC_delay();
  64. }
  65. void stop_IIC(void) //停止IIC
  66. {
  67.     CLK=0;
  68.     IIC_delay();
  69.     DIO=0;
  70.     IIC_delay();
  71.     CLK=1;
  72.     IIC_delay();
  73.     DIO=1;
  74. }
  75. void ack_IIC()
  76. {
  77.     CLK=0;
  78.     _nop_();_nop_();_nop_();
  79.     while(DIO);
  80.     CLK=1;
  81.     _nop_();_nop_();_nop_();
  82.     CLK=0;
  83. }
  84. void WriteByte(unsigned char WriteData) //写一个字节数据
  85. {
  86.     unsigned char i;
  87.     for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据
  88.     {
  89.         CLK=0;
  90.         IIC_delay();
  91.         WriteData=WriteData>>1;
  92.         DIO=CY;
  93.         IIC_delay();
  94.         CLK=1;
  95.         IIC_delay();
  96.     }
  97. //8位数据传送完
  98.     ack_IIC(); //判断芯片发过来的ACK应答信号
  99. }
  100. void write_LEDSROM(unsigned char addr,unsigned char WData) //写一字节数据到LEDSROM
  101. {
  102.     start_IIC(); //调用开始信号
  103.     WriteByte(addr); //写起始地址命令(0C0H),地址00H单元。
  104.     WriteByte(WData);//给显示寄存器写显示数据,值可根据实参改变
  105.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  106. }
  107. void xsled(void) //写数据到LED
  108. {
  109.     DIO=1;
  110.     CLK=1;
  111.     start_IIC(); //调用开始信号
  112.     WriteByte(0x44);//写命令40H(数据设置)
  113.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  114.     write_LEDSROM(0xC0,xsbcdbuf[smg_qian]); //第一个数码管
  115.         if(miao%2==0) { //此处实现数码管中间的两个小数每秒钟闪烁一次
  116.                 write_LEDSROM(0xC1,xsbcdbuf[smg_bai]);  //第二个数码管
  117.         } else {
  118.                 write_LEDSROM(0xC1,xsbcdbuf[smg_bai]|0x80);  //第二个数码管  加|0x80 则点亮数码管中间的两个小点       
  119.         }                                                                                                                                                                                                            
  120.     write_LEDSROM(0xC2,xsbcdbuf[smg_shi]); //第三个数码管
  121.     write_LEDSROM(0xC3,xsbcdbuf[smg_ge]);//第四个数码管
  122.     IIC_delay();
  123.     start_IIC(); //调用开始信号
  124.     WriteByte(0x8a); //送开屏命令,(8BH),亮度可以根据低三位调节。//显示亮度
  125.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  126. }
  127. void jisuan()  //计算
  128. {     
  129.     if(dadt>=60) { //如果时间>=60分钟,则显示小时+分钟
  130.                 smg_qian=dadt/60/10; //计算小时(十位) 显示在第四位数码管
  131.                 smg_bai=dadt/60%10;         //计算小时(个位) 显示在第三位数码管
  132.             smg_shi=(dadt%60)/10; //计算分钟(十位) 显示在第二位数码管
  133.             smg_ge=(dadt%60)%10;  //计算分钟(个位) 显示在第一位数码管
  134.         }
  135.         else if(dadt<60){
  136.                 smg_qian=0; //计算分钟(十位) 显示在第四位数码管
  137.                 smg_bai=0;         //计算分钟(个位) 显示在第三位数码管
  138.             smg_shi=(dadt%60)/10; //计算秒钟(十位) 显示在第二位数码管
  139.             smg_ge=(dadt%60)%10;  //计算秒钟(个位) 显示在第一位数码管
  140.         }
  141. }
  142. void Close_SMG() //关闭数码管
  143. {
  144.         dadt=0;        //清零
  145.         write_LEDSROM(0xC0,0x00); //关第一个数码管
  146.         write_LEDSROM(0xC1,0x00);  //关第二个数码管
  147.         write_LEDSROM(0xC2,0x00); //关第三个数码管
  148.         write_LEDSROM(0xC3,0x00);//关第四个数码管
  149. }
  150. /////////////////////  以上是数码管显示部分   /////////////////////

  151. /////////////////////  以下是无源蜂鸣器部分   /////////////////////
  152. void DelayMS(uint time)//延时函数,有参函数
  153. {  
  154.     uint i4,j4;   
  155.     for(i4=time; i4>0; i4--)   
  156.                 for(j4=110; j4>0; j4--);  
  157. }



  158. void Buzzer(uint Number,uint Time)     //可以选择鸣响次数和音频
  159. {
  160.     uint i3=0,j3=0,k3=0;
  161.     for(i3 = 0; i3 < Number; i3 ++)
  162.     {
  163.         for(j3=0; j3<Time; j3++)
  164.         {
  165.             FMQ = !FMQ;              //beep取反
  166.             for (k3=0; k3<100; k3++);     //需要产生方波,调节音频
  167.         }
  168.         DelayMS(100);                    //间隔时间
  169.     }
  170.     FMQ = 1;  //注意PNP=0;NPN=1关闭蜂鸣器,否则三极管电流会很大。(不接三极管也行,直接接负极,正极接VCC即可)
  171. }
  172. /////////////////////  以下是无源蜂鸣器部分   /////////////////////


  173. //////////////////////////////////////////
  174. void delay1ms(void)        //延时
  175. {
  176.    unsigned char i,j;       
  177.          for(i=0;i<10;i++)
  178.           for(j=0;j<33;j++)
  179.            ;                 
  180. }

  181. ////////////////////////////////////////////
  182. void delay(unsigned char n) //延时
  183. {
  184.    unsigned char i;
  185.         for(i=0;i<n;i++)
  186.            delay1ms();
  187. }
  188. ////////////////////////////////////////////

  189. void beep()                //蜂鸣器响一声函数
  190. {       
  191.         Buzzer(1,1000); //无源蜂鸣器(任意调节参数,选择自己喜欢的鸣叫次数和音频(1代表只响一声))
  192.    /*
  193.    FMQ=0;                         //开启有源蜂鸣器
  194.    delay(250);       //延时
  195.    FMQ=1;           //关闭有源蜂鸣器
  196.    */
  197. }

  198. /////////////////////////////////////////////////////////////
  199. //根据需要自行修改
  200. void Model_2(void)
  201. {
  202.         ontime=40;        //开启时间
  203.         offtime=40;        //关闭时间
  204. }
  205. /////////////////////////////////////////////////////////////
  206. void Model_3(void)
  207. {
  208.         ontime=100;        //开启时间
  209.         offtime=40;        //关闭时间
  210. }
  211. /////////////////////////////////////////////////////////////
  212. void Model_4(void)
  213. {
  214.         ontime=200;        //开启时间
  215.         offtime=80;        //关闭时间
  216. }
  217. /////////////////////////////////////////////////////////////
  218. void Model_5(void)
  219. {
  220.         ontime=700;        //开启时间
  221.         offtime=300; //关闭时间
  222. }
  223. /////////////////////////////////////////////////////////////
  224. //判断接收的编码,执行相应功能(根据需要自行修改)
  225. void _data_(void)
  226. {
  227.         switch(IR_data)        //红外接收成功
  228.         {
  229.                 case 0x45: //20键的迷你遥控器的左上电源键
  230.                 k=1;i1=0;b=1; //取消原来的5种模式,如需还原,请改成k++;if(k==1) k=1;i1=0;b=1;
  231.                 beep();break;    //开机及模式调节。蜂鸣器响一声 提示解码成功,模式切换时i1必须清零
  232.                
  233.                 case 0x44: //20键的迷你遥控器的左2的TEST键
  234.                 shi=shi+30;        //每按一次加30分钟
  235.                 beep();break;
  236.                
  237.                 case 0x07: //20键的迷你遥控器的左3的快倒键
  238.                 if(shi<10) {
  239.                 k=0; //关机
  240.                 Close_SMG(); //关闭数码管
  241.                 } else {               
  242.                         shi=shi-10;        //每按一次减10分钟               
  243.                 }
  244.                 beep();break;
  245.                
  246.                 case 0x09: //20键的迷你遥控器的右3的快进键               
  247.                 shi=shi+10;        //每按一次加10分钟
  248.                 beep();break;
  249.                
  250.                 case 0x40: //20键的迷你遥控器的+键               
  251.                 shi=shi+1;        //每按一次加1分钟
  252.                 beep();break;
  253.                
  254.                 case 0x19: //20键的迷你遥控器的-键               
  255.                 if(shi<1) {
  256.                 shi=0;
  257.                 k=0; //关机
  258.                 Close_SMG(); //关闭数码管
  259.                 } else {               
  260.                         shi=shi-1;        //每按一次减1分钟               
  261.                 }
  262.                 beep();break;
  263.                
  264.                 case 0x47: //20键的迷你遥控器的右上MENU键
  265.                 k=0; //关机
  266.                 Close_SMG(); //关闭数码管
  267.                 beep();break;
  268.         }               
  269.         if(shi>2880) //最大48小时
  270.         {
  271.                 shi=2880; //最大不能超过2天 //shi=0;Close_SMG(); //关屏
  272.         }
  273.         IR_data=0x00; //必须清零
  274. }
  275. ////////////////////////////////////////////
  276. void main(void)         //主函数
  277. {

  278.         IE   = 0x82;   //开总中断和T0中断允许
  279.         IE2  = 0x04;   //T2中断允许
  280.         TMOD = 0;                //for STC15Fxxx系列        Timer0 as 16bit reload timer.
  281.         TH0  = Timer0_Reload / 256;
  282.         TL0  = Timer0_Reload % 256;
  283.         T2L  = T50MS;  //初始化计时值5ms中断一次
  284.     T2H  = T50MS >> 8;
  285.         TR0  =1;
  286.         k    =0;

  287.         while(1)  //无限循环
  288.         {
  289.                 switch(k) //判断k的值
  290.                 {
  291.                         case 0: AUXR=0x00;         //k=0时T2关闭中断
  292.                                         i1=0;                 //记得计时清零
  293.                                         shi=0;                 //关闭时,定时时长也清零
  294.                                         KG=1;                 //关闭
  295.                                         break;
  296.                         case 1: AUXR=0x10;         //k不等于0时打开中断
  297.                                         break;
  298.                         case 2: AUXR=0x10;         //k=2~5时启动相应模式
  299.                                         Model_2();         //模式2
  300.                                         break;
  301.                         case 3: AUXR=0x10;
  302.                                         Model_3();         //模式3
  303.                                         break;
  304.                         case 4: AUXR=0x10;
  305.                                         Model_4();         //模式4
  306.                                         break;
  307.                         case 5: AUXR=0x10;
  308.                                         Model_5();         //模式5
  309.                                         break;
  310.                 }
  311.                
  312.                
  313.                
  314.         }                        
  315. }
  316. /*************红外接收部分程序是引用STC官方的资料******************************/
  317. /******************** 红外采样时间宏定义, 用户不要随意修改        *******************/

  318. #if ((D_TIMER0 <= 250) && (D_TIMER0 >= 60))
  319.         #define        D_IR_sample                        D_TIMER0                //定义采样时间,在60us~250us之间
  320. #endif

  321. #define D_IR_SYNC_MAX                (15000/D_IR_sample)        //SYNC max time
  322. #define D_IR_SYNC_MIN                (9700 /D_IR_sample)        //SYNC min time
  323. #define D_IR_SYNC_DIVIDE        (12375/D_IR_sample)        //decide data 0 or 1
  324. #define D_IR_DATA_MAX                (3000 /D_IR_sample)        //data max time
  325. #define D_IR_DATA_MIN                (600  /D_IR_sample)        //data min time
  326. #define D_IR_DATA_DIVIDE        (1687 /D_IR_sample)        //decide data 0 or 1
  327. #define D_IR_BIT_NUMBER                32                                        //bit number

  328. //*******************************************************************************************
  329. //**************************** IR RECEIVE MODULE ********************************************

  330. void IR_RX_HT6121(void)
  331. {
  332.         uchar        SampleTime;

  333.         IR_SampleCnt++;                                                        //Sample + 1

  334.         F0 = P_IR_RX_temp;                                                //Save Last sample status
  335.         P_IR_RX_temp = P_IR_RX;                                        //Read current status
  336.         if(F0 && !P_IR_RX_temp)                                        //Last sample is high,and current sample is low, so is fall edge
  337.         {
  338.                 SampleTime = IR_SampleCnt;                        //get the sample time
  339.                 IR_SampleCnt = 0;                                        //Clear the sample counter

  340.                          if(SampleTime > D_IR_SYNC_MAX)                B_IR_Sync = 0;        //large the Maxim SYNC time, then error
  341.                 else if(SampleTime >= D_IR_SYNC_MIN)                                        //SYNC
  342.                 {
  343.                         if(SampleTime >= D_IR_SYNC_DIVIDE)
  344.                         {
  345.                                 B_IR_Sync = 1;                                        //has received SYNC
  346.                                 IR_BitCnt = D_IR_BIT_NUMBER;        //Load bit number
  347.                         }
  348.                 }
  349.                 else if(B_IR_Sync)                                                //has received SYNC
  350.                 {
  351.                         if(SampleTime > D_IR_DATA_MAX)                B_IR_Sync=0;        //data samlpe time to large
  352.                         else
  353.                         {
  354.                                 IR_DataShit >>= 1;                                        //data shift right 1 bit
  355.                                 if(SampleTime >= D_IR_DATA_DIVIDE)        IR_DataShit |= 0x80;        //devide data 0 or 1
  356.                                 if(--IR_BitCnt == 0)                                //bit number is over?
  357.                                 {
  358.                                         B_IR_Sync = 0;                                        //Clear SYNC
  359.                                         if(~IR_DataShit == IR_data)                //判断数据正反码
  360.                                         {
  361.                                                 if((IR_UserH == (User_code / 256)) &&
  362.                                                         IR_UserL == (User_code % 256))
  363.                                                                 B_IrUserErr = 0;        //User code is righe
  364.                                                 else        B_IrUserErr = 1;        //user code is wrong
  365.                                                        
  366.                                                 IR_code      = IR_data;
  367.                                                 B_IR_Press   = 1;                        //数据有效
  368.                                                 _data_();
  369.                                         }
  370.                                 }
  371.                                 else if((IR_BitCnt & 7)== 0)                //one byte receive
  372.                                 {
  373.                                         IR_UserL = IR_UserH;                        //Save the User code high byte
  374.                                         IR_UserH = IR_data;                                //Save the User code low byte
  375.                                         IR_data  = IR_DataShit;                        //Save the IR data byte
  376.                                 }
  377.                         }
  378.                 }
  379.         }
  380. }

  381. /********************** Timer0中断函数************************/
  382. void timer0 (void) interrupt 1
  383. {
  384.         IR_RX_HT6121();         //红外
  385. }

  386. ///////////////////////////////////////////
  387. void time2(void ) interrupt 12
  388. {       
  389.         TR0=0;      //T2中断期间关闭T0中断
  390.         if(k==1)        //k=1时,常开
  391.                 KG=0;        //开关
  392.         else
  393.         {
  394.                 i1++; //计次数
  395.                 if(b==1) //b=开启和关闭状态
  396. ……………………

  397. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
STC15F104红外 定时器 TM1637数码管 无源蜂鸣器.zip (51.8 KB, 下载次数: 163)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:424598 发表于 2018-12-7 22:22 | 显示全部楼层
这张图传小了,看不清,重传
20键迷你遥控器码图.jpg
回复

使用道具 举报

ID:445163 发表于 2018-12-14 00:00 来自手机 | 显示全部楼层
怎么看你历史的帖子呀
回复

使用道具 举报

ID:1 发表于 2018-12-14 00:08 | 显示全部楼层
2321481869 发表于 2018-12-14 00:00
怎么看你历史的帖子呀


1.png
回复

使用道具 举报

ID:85796 发表于 2019-8-15 15:21 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:78569 发表于 2019-12-27 16:42 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:206067 发表于 2020-1-28 23:27 | 显示全部楼层
可以改成15F102W用吗 编译当前有47个错误
回复

使用道具 举报

ID:162957 发表于 2020-1-29 16:06 | 显示全部楼层
正好需要这方面的资料,下了参考一下
回复

使用道具 举报

ID:410680 发表于 2020-3-1 01:09 | 显示全部楼层
学习一下,谢谢分享
回复

使用道具 举报

ID:704585 发表于 2020-6-12 14:02 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:55085 发表于 2020-6-12 16:05 | 显示全部楼层
实用技术,赞扬楼主!!!!!
回复

使用道具 举报

ID:848824 发表于 2020-12-12 11:27 来自手机 | 显示全部楼层
挺好还带定时
回复

使用道具 举报

ID:848824 发表于 2020-12-12 11:35 来自手机 | 显示全部楼层
等数码屏到了做一个,谢谢分享
回复

使用道具 举报

ID:848824 发表于 2020-12-19 05:11 来自手机 | 显示全部楼层
怎么容易死机是怎么回事啊!
回复

使用道具 举报

ID:848824 发表于 2020-12-21 12:28 来自手机 | 显示全部楼层
编译不能通过
回复

使用道具 举报

ID:848824 发表于 2020-12-21 12:29 来自手机 | 显示全部楼层
编译不能通过程序有问题啊!
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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