找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC15F104单片机红外+定时器+TM1637数码管程序

  [复制链接]
跳转到指定楼层
楼主
由于手头只有TM1637数码管,所以只能用它了.

关键计算24小时代码
  1. smg_qian=dadt/60/10; //计算小时(十位) 显示在第四位数码管
  2.         smg_bai=dadt/60%10;         //计算小时(个位) 显示在第三位数码管
  3.     smg_shi=(dadt%60)/10; //计算分钟(十位) 显示在第二位数码管
  4.     smg_ge=(dadt%60)%10;  //计算分钟(个位) 显示在第一位数码管
复制代码
关闭数码管代码
  1. dadt=0;        //清零
  2.         write_LEDSROM(0xC0,0x00); //关第一个数码管
  3.         write_LEDSROM(0xC1,0x00);  //关第二个数码管
  4.         write_LEDSROM(0xC2,0x00); //关第三个数码管
  5.         write_LEDSROM(0xC3,0x00);//关第四个数码管
复制代码





单片机源程序:
  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; //接四针数码管的GIO脚
  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 t,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.         //stop_IIC();
  138. }
  139. /////////////////////  以上是数码管显示部分   /////////////////////

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

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

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

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

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

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

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

  266. //*******************************************************************************************
  267. //**************************** IR RECEIVE MODULE ********************************************

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

  271.         IR_SampleCnt++;                                                        //Sample + 1

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

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

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

  324. ///////////////////////////////////////////
  325. void time2(void ) interrupt 12
  326. {       
  327.         TR0=0;      //T2中断期间关闭T0中断
  328.         if(k==1)        //k=1时,风扇常开
  329.                 KG=0;        //开关
  330.         else
  331.         {
  332.                 i1++; //计次数
  333.                 if(b==1) //b=开启和关闭状态
  334.                 {
  335.                         KG=0; //开关
  336.                         if(i1==ontime)           //开启时间
  337.                         {
  338.                                 i1=0;
  339.                                 b=0;
  340.                         }
  341.                 }
  342.                 if(b==0)
  343.                 {
  344.                         KG=1; //开关
  345.                         if(i1==offtime)           //关闭时间
  346.                         {
  347.                                 i1=0;
  348.                                 b=1;
  349.                         }
  350.                 }
  351.         }               

  352.         if(shi)        //当shi大于0分钟时,启动定时功能
  353.         {
  354.                 i2++; //计次数
  355.                 if(i2==20)
  356.                 {
  357.                         i2=0; //计数清零                                               
  358.                         miao++;         //秒

  359.                 }
  360.                 if(miao==60) //60秒
  361.                 {
  362.                         miao=0;         //秒清零
  363.                         shi--; //减1分钟
  364.                         dadt=shi; //赋值
  365.                         jisuan(); //计算
  366.                     xsled();  //写数据到LED                       
  367.                 }               
  368.                 if(shi==0)         //时
  369.                 {
  370.                         k=0; //关机
  371.                         Close_SMG(); //关闭数码管
  372.                 }
  373.         }
  374.         TR0=1;        //T2中断结束,开启T0中断
  375.         t++; //数码管       
  376. }
复制代码

下载:
STC15F104红外 定时器 TM1637数码管.zip (46.63 KB, 下载次数: 107)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1 发表于 2018-11-27 16:52 | 只看该作者
能分享下原理图吗?
回复

使用道具 举报

板凳
ID:433756 发表于 2018-11-27 17:58 来自手机 | 只看该作者
好不错啊
回复

使用道具 举报

地板
ID:424598 发表于 2018-11-27 18:31 来自手机 | 只看该作者
admin 发表于 2018-11-27 16:52
能分享下原理图吗?

原理图:http://www.51hei.com/bbs/dpj-142926-1.html
看我另一个贴,此贴只是在原来贴的基础上,补加了倒计时显示数码管,最大支持48小时,可以根据需要在改更大
回复

使用道具 举报

5#
ID:484750 发表于 2019-3-6 16:02 | 只看该作者
请问下这个tm1637能改电容按键识别吗
回复

使用道具 举报

6#
ID:848824 发表于 2020-12-16 13:45 | 只看该作者
小白下载学习一下,谢谢分享
回复

使用道具 举报

7#
ID:230374 发表于 2021-3-29 10:19 | 只看该作者
下载学习,谢谢分享,无私贡献
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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