找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4059|回复: 3
打印 上一主题 下一主题
收起左侧

STC15F104单片机红外定时手机充电器(成品制作)最终版源码

[复制链接]
跳转到指定楼层
楼主
给家人做的定时手机充电器,再也不用睡到半夜起来拨电了
网上买现成的不如自己做,既可掌握知识又能节省成本部分组件设计成可更换式,以方便更换管理员请帮忙调整下图片顺序,谢谢!

制作出来的实物图如下:


说明:


单片机源程序如下:
  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 SCL=P3^4; //接四针数码管的CLK脚
  36. sbit SDA=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.     SCL=1; //给芯片发送开始信号
  58.     SDA=1;
  59.     IIC_delay();
  60.     SDA=0;
  61.     IIC_delay();
  62.     SCL=0; //开始信号传送完
  63.     IIC_delay();
  64. }
  65. void stop_IIC(void) //停止IIC
  66. {
  67.     SCL=0;
  68.     IIC_delay();
  69.     SDA=0;
  70.     IIC_delay();
  71.     SCL=1;
  72.     IIC_delay();
  73.     SDA=1;
  74. }
  75. void ack_IIC()
  76. {
  77.     SCL=0;
  78.     _nop_();_nop_();_nop_();
  79.     while(SDA);
  80.     SCL=1;
  81.     _nop_();_nop_();_nop_();
  82.     SCL=0;
  83. }
  84. void WriteByte(unsigned char WriteData) //写一个字节数据
  85. {
  86.     unsigned char i;
  87.     for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据
  88.     {
  89.         SCL=0;
  90.         IIC_delay();
  91.         WriteData=WriteData>>1;
  92.         SDA=CY;
  93.         IIC_delay();
  94.         SCL=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.     SDA=1;
  110.     SCL=1;
  111.     start_IIC(); //调用开始信号
  112.     WriteByte(0x44);//写命令40H(数据设置)
  113.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  114.     write_LEDSROM(0xC0,xsbcdbuf[smg_qian]); //第一个数码管
  115.     write_LEDSROM(0xC1,xsbcdbuf[smg_bai]|0x80);  //第二个数码管  加|0x80 则点亮数码管中间的两个小点        
  116.     write_LEDSROM(0xC2,xsbcdbuf[smg_shi]); //第三个数码管
  117.     write_LEDSROM(0xC3,xsbcdbuf[smg_ge]);//第四个数码管
  118.     IIC_delay();
  119.     start_IIC(); //调用开始信号
  120.     WriteByte(0x8a); //送开屏命令,(8BH),亮度可以根据低三位调节。//显示亮度
  121.     stop_IIC(); //调用结束信号,一个字节命令发送完毕,可以发送下一个命令
  122. }
  123. void jisuan()  //计算
  124. {     
  125.     smg_qian=dadt/60/10; //计算小时(十位) 显示在第四位数码管
  126.         smg_bai=dadt/60%10;         //计算小时(个位) 显示在第三位数码管
  127.     smg_shi=(dadt%60)/10; //计算分钟(十位) 显示在第二位数码管
  128.     smg_ge=(dadt%60)%10;  //计算分钟(个位) 显示在第一位数码管
  129. }
  130. void Close_SMG() //关闭数码管
  131. {
  132.         dadt=0;        //清零
  133.         write_LEDSROM(0xC0,0x00); //关第一个数码管
  134.         write_LEDSROM(0xC1,0x00);  //关第二个数码管
  135.         write_LEDSROM(0xC2,0x00); //关第三个数码管
  136.         write_LEDSROM(0xC3,0x00);//关第四个数码管
  137. }
  138. /////////////////////  以上是数码管显示部分   /////////////////////

  139. //////////////////////////////////////////
  140. void delay1ms(void)        //延时
  141. {
  142.    unsigned char i,j;        
  143.          for(i=0;i<10;i++)
  144.           for(j=0;j<33;j++)
  145.            ;                 
  146. }

  147. ////////////////////////////////////////////
  148. void delay(unsigned char n) //延时
  149. {
  150.    unsigned char i;
  151.         for(i=0;i<n;i++)
  152.            delay1ms();
  153. }
  154. ////////////////////////////////////////////
  155. void beep()                //蜂鸣器响一声函数
  156. {
  157.    FMQ=0;                         //开启蜂鸣器
  158.    delay(250);       //延时
  159.    FMQ=1;           //关闭蜂鸣器     
  160. }

  161. /////////////////////////////////////////////////////////////
  162. //根据需要自行修改
  163. void Model_2(void)
  164. {
  165.          ontime=40;        //开启时间
  166.         offtime=40;        //关闭时间
  167. }
  168. /////////////////////////////////////////////////////////////
  169. void Model_3(void)
  170. {
  171.          ontime=100;        //开启时间
  172.         offtime=40;        //关闭时间
  173. }
  174. /////////////////////////////////////////////////////////////
  175. void Model_4(void)
  176. {
  177.          ontime=200;        //开启时间
  178.         offtime=80;        //关闭时间
  179. }
  180. /////////////////////////////////////////////////////////////
  181. void Model_5(void)
  182. {
  183.          ontime=700;        //开启时间
  184.         offtime=300; //关闭时间
  185. }
  186. /////////////////////////////////////////////////////////////
  187. //判断接收的编码,执行相应功能(根据需要自行修改)
  188. void _data_(void)
  189. {
  190.          switch(IR_data)        //红外接收成功
  191.         {
  192.                 case 0x45:
  193.                 k++;if(k==6) k=1;i1=0;b=1;
  194.                 beep();break;    //开机及模式调节。蜂鸣器响一声 提示解码成功,模式切换时i1必须清零
  195.                 case 0x44:
  196.                 shi=shi+30;        //每按一次加30分钟
  197.                 dadt=shi; //赋值
  198.                 jisuan(); //计算
  199.             xsled();  //写数据到LED                                                
  200.                 if(shi>2880) //最大48小时
  201.                 {
  202.                         shi=2880; //最大不能超过2天 //shi=0;Close_SMG(); //关屏
  203.                 }
  204.                 beep();break;
  205.                 case 0x47:
  206.                 k=0; //关机
  207.                 Close_SMG(); //关闭数码管
  208.                 beep();break;
  209.         }
  210.         IR_data=0x00; //必须清零
  211. }
  212. ////////////////////////////////////////////
  213. void main(void)         //主函数
  214. {

  215.         IE   = 0x82;   //开总中断和T0中断允许
  216.         IE2  = 0x04;   //T2中断允许
  217.         TMOD = 0;                //for STC15Fxxx系列        Timer0 as 16bit reload timer.
  218.         TH0  = Timer0_Reload / 256;
  219.         TL0  = Timer0_Reload % 256;
  220.         T2L  = T50MS;  //初始化计时值5ms中断一次
  221.     T2H  = T50MS >> 8;
  222.         TR0  =1;
  223.         k    =0;

  224.         while(1)  //无限循环
  225.         {
  226.                 switch(k) //判断k的值
  227.                 {
  228.                         case 0: AUXR=0x00;         //k=0时T2关闭中断
  229.                                         i1=0;                 //记得计时清零
  230.                                         shi=0;                 //关闭时,定时时长也清零
  231.                                         KG=1;                 //关闭
  232.                                         break;
  233.                         case 1: AUXR=0x10;         //k不等于0时打开中断
  234.                                         break;
  235.                         case 2: AUXR=0x10;         //k=2~5时启动相应模式
  236.                                         Model_2();         //模式2
  237.                                         break;
  238.                         case 3: AUXR=0x10;
  239.                                         Model_3();         //模式3
  240.                                         break;
  241.                         case 4: AUXR=0x10;
  242.                                         Model_4();         //模式4
  243.                                         break;
  244.                         case 5: AUXR=0x10;
  245.                                         Model_5();         //模式5
  246.                                         break;
  247.                 }
  248.                
  249.                
  250.                
  251.         }                        
  252. }
  253. /*************红外接收部分程序是引用STC官方的资料******************************/
  254. /******************** 红外采样时间宏定义, 用户不要随意修改        *******************/

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

  258. #define D_IR_SYNC_MAX                (15000/D_IR_sample)        //SYNC max time
  259. #define D_IR_SYNC_MIN                (9700 /D_IR_sample)        //SYNC min time
  260. #define D_IR_SYNC_DIVIDE        (12375/D_IR_sample)        //decide data 0 or 1
  261. #define D_IR_DATA_MAX                (3000 /D_IR_sample)        //data max time
  262. #define D_IR_DATA_MIN                (600  /D_IR_sample)        //data min time
  263. #define D_IR_DATA_DIVIDE        (1687 /D_IR_sample)        //decide data 0 or 1
  264. #define D_IR_BIT_NUMBER                32                                        //bit number

  265. //*******************************************************************************************
  266. //**************************** IR RECEIVE MODULE ********************************************

  267. void IR_RX_HT6121(void)
  268. {
  269.         uchar        SampleTime;

  270.         IR_SampleCnt++;                                                        //Sample + 1

  271.         F0 = P_IR_RX_temp;                                                //Save Last sample status
  272.         P_IR_RX_temp = P_IR_RX;                                        //Read current status
  273.         if(F0 && !P_IR_RX_temp)                                        //Last sample is high,and current sample is low, so is fall edge
  274.         {
  275.                 SampleTime = IR_SampleCnt;                        //get the sample time
  276.                 IR_SampleCnt = 0;                                        //Clear the sample counter

  277.                          if(SampleTime > D_IR_SYNC_MAX)                B_IR_Sync = 0;        //large the Maxim SYNC time, then error
  278.                 else if(SampleTime >= D_IR_SYNC_MIN)                                        //SYNC
  279.                 {
  280.                         if(SampleTime >= D_IR_SYNC_DIVIDE)
  281.                         {
  282.                                 B_IR_Sync = 1;                                        //has received SYNC
  283.                                 IR_BitCnt = D_IR_BIT_NUMBER;        //Load bit number
  284.                         }
  285.                 }
  286.                 else if(B_IR_Sync)                                                //has received SYNC
  287.                 {
  288.                         if(SampleTime > D_IR_DATA_MAX)                B_IR_Sync=0;        //data samlpe time to large
  289.                         else
  290.                         {
  291.                                 IR_DataShit >>= 1;                                        //data shift right 1 bit
  292.                                 if(SampleTime >= D_IR_DATA_DIVIDE)        IR_DataShit |= 0x80;        //devide data 0 or 1
  293.                                 if(--IR_BitCnt == 0)                                //bit number is over?
  294.                                 {
  295.                                         B_IR_Sync = 0;                                        //Clear SYNC
  296.                                         if(~IR_DataShit == IR_data)                //判断数据正反码
  297.                                         {
  298.                                                 if((IR_UserH == (User_code / 256)) &&
  299.                                                         IR_UserL == (User_code % 256))
  300.                                                                 B_IrUserErr = 0;        //User code is righe
  301.                                                 else        B_IrUserErr = 1;        //user code is wrong
  302.                                                         
  303.                                                 IR_code      = IR_data;
  304.                                                 B_IR_Press   = 1;                        //数据有效
  305.                                                 _data_();
  306.                                         }
  307.                                 }
  308.                                 else if((IR_BitCnt & 7)== 0)                //one byte receive
  309.                                 {
  310.                                         IR_UserL = IR_UserH;                        //Save the User code high byte
  311.                                         IR_UserH = IR_data;                                //Save the User code low byte
  312.                                         IR_data  = IR_DataShit;                        //Save the IR data byte
  313.                                 }
  314.                         }
  315.                 }
  316.         }
  317. }

  318. /********************** Timer0中断函数************************/
  319. void timer0 (void) interrupt 1
  320. {
  321.         IR_RX_HT6121();         //红外
  322. }

  323. ///////////////////////////////////////////
  324. void time2(void ) interrupt 12
  325. {        
  326.         TR0=0;      //T2中断期间关闭T0中断
  327.         if(k==1)        //k=1时,常开
  328.                 KG=0;        //开关
  329.         else
  330.         {
  331.                 i1++; //计次数
  332.                 if(b==1) //b=开启和关闭状态
  333.                 {
  334. ……………………

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

所有资料51hei提供下载:
STC15F104红外 定时器 TM1637数码管(终极版).zip (46.39 KB, 下载次数: 64)


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:424598 发表于 2018-11-30 09:39 | 只看该作者
用废弃的化妆品盒,给我的板子安个家

IMG_20181130_092234.jpg (76.21 KB, 下载次数: 47)

IMG_20181130_092234.jpg

IMG_20181130_092243.jpg (75.74 KB, 下载次数: 68)

IMG_20181130_092243.jpg
回复

使用道具 举报

板凳
ID:424598 发表于 2018-11-30 11:18 | 只看该作者
  1. void xsled(void) //写数据到LED
复制代码
  1. void time2(void ) interrupt 12
  2. {       
  3.         TR0=0;      //T2中断期间关闭T0中断
  4.         if(k==1)        //k=1时,常开
  5.                 KG=0;        //开关
  6.         else
  7.         {
  8.                 i1++; //计次数
  9.                 if(b==1) //b=开启和关闭状态
  10.                 {
  11.                         KG=0; //开关
  12.                         if(i1==ontime)           //开启时间
  13.                         {
  14.                                 i1=0;
  15.                                 b=0;
  16.                         }
  17.                 }
  18.                 if(b==0)
  19.                 {
  20.                         KG=1; //开关
  21.                         if(i1==offtime)           //关闭时间
  22.                         {
  23.                                 i1=0;
  24.                                 b=1;
  25.                         }
  26.                 }
  27.         }               

  28.         if(shi)        //当shi大于0分钟时,启动定时功能
  29.         {
  30.                 i2++; //计次数
  31.                 if(i2==20)
  32.                 {
  33.                         i2=0; //计数清零                                               
  34.                         miao++;         //秒
  35.                         dadt=shi; //赋值
  36.                         jisuan(); //计算
  37.                     xsled();  //写数据到LED
  38.                 }
  39.                 if(miao==60) //60秒
  40.                 {
  41.                         miao=0;         //秒清零
  42.                         shi--; //减1分钟
  43.                        
  44.                 }               
  45.                 if(shi==0)         //时
  46.                 {
  47.                         k=0; //关机
  48.                         Close_SMG(); //关闭数码管
  49.                 }
  50.         }
  51.         TR0=1;        //T2中断结束,开启T0中断
  52. }
复制代码
替换以上二段代码, 可以让数码管中间的二点以每秒的速度, 亮和灭
回复

使用道具 举报

地板
ID:438886 发表于 2018-12-6 22:54 来自手机 | 只看该作者
ssk7793 发表于 2018-11-30 11:18
替换以上二段代码, 可以让数码管中间的二点以每秒的速度, 亮和灭

快上原理图^_^
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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