找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机红外遥控计算器源码(个位数相加)

[复制链接]
跳转到指定楼层
楼主
通过红外遥控,实现简单地计算器,并通过数码管显示出来


单片机源程序如下:
  1. #include "stc15.h"
  2. #include "intrins.h"
  3. #include "gpio.h"
  4. #include "uart.h"
  5. #include "595hc.h"

  6. #define MAIN_Fosc       11059200L   //定义主时钟
  7. #define SysTick     10000       // 次/秒, 系统滴答频率, 在4000~16000之间
  8. #define Timer0_Reload   (65536UL - ((MAIN_Fosc + SysTick/2) / SysTick))     //Timer 0 中断频率, 在config.h中指定系统滴答频率, 在4000~16000之间.

  9. u8 i=0,j,k;
  10. u8 number;
  11. u8 cnt_1ms;  //1ms基本计时
  12. bit B_1ms;   //1ms标志

  13.         
  14. /*************  红外接收程序变量声明    **************/
  15. sbit    P_IR_RX = P3^6;         //定义红外接收输入IO口

  16. u8  IR_SampleCnt;       //采样计数
  17. u8  IR_BitCnt;          //编码位数
  18. u8  IR_UserH;           //用户码(地址)高字节
  19. u8  IR_UserL;           //用户码(地址)低字节
  20. u8  IR_data;            //数据原码
  21. u8  IR_DataShit;        //数据移位

  22. bit P_IR_RX_temp;       //Last sample
  23. bit B_IR_Sync;          //已收到同步标志
  24. bit B_IR_Press;         //安键动作发生
  25. u8  IR_code;            //红外键码
  26. u16 UserCode;           //用户码
  27. /*********************************/

  28. #define IR_SAMPLE_TIME      (1000000UL/SysTick)         //查询时间间隔, us, 红外接收要求在60us~250us之间

  29. #if ((IR_SAMPLE_TIME <= 250) && (IR_SAMPLE_TIME >= 60))
  30.         #define D_IR_sample         IR_SAMPLE_TIME      //定义采样时间,在60us~250us之间
  31. #endif

  32. #define D_IR_SYNC_MAX       (15000/D_IR_sample) //SYNC max time
  33. #define D_IR_SYNC_MIN       (9700 /D_IR_sample) //SYNC min time
  34. #define D_IR_SYNC_DIVIDE    (12375/D_IR_sample) //decide data 0 or 1
  35. #define D_IR_DATA_MAX       (3000 /D_IR_sample) //data max time
  36. #define D_IR_DATA_MIN       (600  /D_IR_sample) //data min time
  37. #define D_IR_DATA_DIVIDE    (1687 /D_IR_sample) //decide data 0 or 1
  38. #define D_IR_BIT_NUMBER     32                  //bit number
  39. #define SysTick     10000       // 次/秒, 系统滴答频率, 在4000~16000之间

  40. //*******************************************************************************************
  41. //**************************** IR RECEIVE MODULE ********************************************
  42. void IR_RX_NEC(void)
  43. {
  44.     u8  SampleTime;

  45.     IR_SampleCnt++;                         //Sample + 1

  46.     F0 = P_IR_RX_temp;                      //Save Last sample status
  47.     P_IR_RX_temp = P_IR_RX;                 //Read current status
  48.     if(F0 && !P_IR_RX_temp)                 //Pre-sample is high,and current sample is low, so is fall edge
  49.     {
  50.         SampleTime = IR_SampleCnt;          //get the sample time
  51.         IR_SampleCnt = 0;                   //Clear the sample counter

  52.              if(SampleTime > D_IR_SYNC_MAX)     B_IR_Sync = 0;  //large the Maxim SYNC time, then error
  53.         else if(SampleTime >= D_IR_SYNC_MIN)                    //SYNC
  54.         {
  55.             if(SampleTime >= D_IR_SYNC_DIVIDE)
  56.             {
  57.                 B_IR_Sync = 1;                  //has received SYNC
  58.                 IR_BitCnt = D_IR_BIT_NUMBER;    //Load bit number
  59.             }
  60.         }
  61.         else if(B_IR_Sync)                      //has received SYNC
  62.         {
  63.             if(SampleTime > D_IR_DATA_MAX)      B_IR_Sync=0;    //data samlpe time too large
  64.             else
  65.             {
  66.                 IR_DataShit >>= 1;                  //data shift right 1 bit
  67.                 if(SampleTime >= D_IR_DATA_DIVIDE)  IR_DataShit |= 0x80;    //devide data 0 or 1
  68.                 if(--IR_BitCnt == 0)                //bit number is over?
  69.                 {
  70.                     B_IR_Sync = 0;                  //Clear SYNC
  71.                     if(~IR_DataShit == IR_data)     //判断数据正反码
  72.                     {
  73.                         UserCode = ((u16)IR_UserH << 8) + IR_UserL;
  74.                         IR_code      = IR_data;
  75.                         B_IR_Press   = 1;           //数据有效
  76.                     }
  77.                 }
  78.                 else if((IR_BitCnt & 7)== 0)        //one byte receive
  79.                 {
  80.                     IR_UserL = IR_UserH;            //Save the User code high byte
  81.                     IR_UserH = IR_data;             //Save the User code low byte
  82.                     IR_data  = IR_DataShit;         //Save the IR data byte
  83.                 }
  84.             }
  85.         }
  86.     }
  87. }
  88. //*********************************** MODULE END ********************************************
  89. //*******************************************************************************************


  90. ///********************** Timer0初始化 ************************/
  91. void Timer0Init(void)                //1毫秒 @11.0592MHz
  92. {
  93.         AUXR = 0x80;                //定时器时钟1T模式
  94.         TMOD = 0x00;                //设置定时器模式
  95.         TL0 = (u8)(Timer0_Reload % 256);                //设置定时初值
  96.         TH0 = (u8)(Timer0_Reload / 256);                //设置定时初值
  97.         EA = 1;                    //开启总中断
  98.         ET0 = 1;                //允许定时器0中断
  99.         TF0 = 0;                //清除TF0标志
  100.         TR0 = 1;                //定时器0开始计时
  101. }
  102. ///********************** Timer0中断函数 ************************/
  103. void timer0 (void) interrupt 1
  104. {
  105.         IR_RX_NEC();
  106.         if(--cnt_1ms == 0)
  107.         {
  108.                         cnt_1ms = SysTick / 1000;
  109.                         B_1ms = 1;      //1ms标志
  110.                         DisplayScan();  //1ms扫描显示一位
  111.         }
  112. }


  113. int Addend;  //数
  114. int Augend;  //被数
  115. int Sum_Sub;  //和_差
  116. int Middle_Number;  //中间数
  117. int Buffer;  //缓冲暂存
  118. bit Catch_Flag = 0;
  119. u8 Addition_Flag = 0;
  120. void main(void)
  121. {
  122.         GPIO();
  123.         Timer0Init();
  124.         
  125.         cnt_1ms = SysTick / 1000;
  126.         for(i=0; i<8; i++)  LED8[i] = 16;
  127.         LED8[0] = 12;  //C
  128.         LED8[1] = 10;  //A
  129.         LED8[2] = 21;  //L
  130.         LED8[3] = 12;  //C
  131.         LED8[4] = 25;  //U
  132.         LED8[5] = 21;  //L
  133.         LED8[6] = 10;  //A
  134.         LED8[7] = 17;  //-
  135.         

  136.         
  137.         
  138. while (1)
  139. {
  140.         
  141.                 if(B_1ms)   //1ms到
  142.                 {                        
  143.                         B_1ms = 0;
  144.                         if(B_IR_Press)      //检测到收到红外键码
  145.                         {
  146.                                 B_IR_Press = 0;
  147.                                        
  148.         //                                        LED8[0] = (u8)((UserCode >> 12) & 0x0f);    //用户码高字节的高半字节
  149.         //                                        LED8[1] = (u8)((UserCode >> 8)  & 0x0f);    //用户码高字节的低半字节
  150.         //                                        LED8[2] = (u8)((UserCode >> 4)  & 0x0f);    //用户码低字节的高半字节
  151.         //                                        LED8[3] = (u8)(UserCode & 0x0f);            //用户码低字节的低半字节
  152.         //                                        LED8[6] = IR_code >> 4;
  153.         //                                        LED8[7] = IR_code & 0x0f;
  154.                                 
  155.                                 switch(IR_code)
  156.                                 {
  157.                                         case 0x16: Middle_Number = 0;Catch_Flag = 1;
  158.                                                 break;
  159.                                         case 0x0C: Middle_Number = 1;Catch_Flag = 1;
  160.                                                 break;
  161.                                         case 0x18: Middle_Number = 2;Catch_Flag = 1;
  162.                                                 break;
  163.                                         case 0x5E: Middle_Number = 3;Catch_Flag = 1;
  164.                                                 break;
  165.                                         case 0x08: Middle_Number = 4;Catch_Flag = 1;
  166.                                                 break;
  167.                                         case 0x1C: Middle_Number = 5;Catch_Flag = 1;
  168.                                                 break;
  169.                                         case 0x5A: Middle_Number = 6;Catch_Flag = 1;
  170.                                                 break;
  171.                                         case 0x42: Middle_Number = 7;Catch_Flag = 1;
  172.                                                 break;
  173.                                         case 0x52: Middle_Number = 8;Catch_Flag = 1;
  174.                                                 break;
  175.                                         case 0x4A: Middle_Number = 9;Catch_Flag = 1;
  176.                                                 break;
  177.                                         case 0x07: Middle_Number = 10;Catch_Flag = 1;  // -
  178.                                                 break;
  179.                                         case 0x15: Middle_Number = 11;Catch_Flag = 1;  // +
  180.                                                 break;
  181.                                         case 0x09: Middle_Number = 12;Catch_Flag = 1;  // =
  182.                                                 break;
  183.                                 }
  184.                                 
  185.                         if(Catch_Flag == 1)
  186.                         {
  187.                                         Catch_Flag = 0;
  188.                                 
  189.                                         if(Addition_Flag == 0)
  190.                                         {
  191. First:
  192.                                                 for(i=0;i<8;i++) LED8[i] = 16;  //清屏
  193.                                                 Augend = Middle_Number;
  194.                                                 LED8[0] = Augend;
  195.                                                 Addition_Flag = 1;
  196.                                         }
  197.                                         else if(Addition_Flag == 1)
  198.                                         {
  199.                                                 Buffer = Middle_Number;
  200.                                                 if((Buffer - 10) < 0) goto First;  //如果不是符号,则跳转
  201.                                                 if(Buffer == 10) LED8[1] = 17;
  202.                                                 if(Buffer == 11) LED8[1] = 24;
  203.                                                 Addition_Flag = 2;
  204.                                         }
  205.                                         else if(Addition_Flag == 2)
  206.                                         {
  207.                                                 Addend = Middle_Number;
  208.                                                 LED8[2] = Addend;
  209.                                                 Addition_Flag = 3;
  210.                                         }
  211.                                        
  212.                                         if(Middle_Number == 12)
  213.                                         {
  214.                                                 if(Buffer == 10)
  215.                                                 {
  216.                                                         Sum_Sub = Augend - Addend;
  217.                                                         if(Sum_Sub < 0)
  218. ……………………

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

所有资料51hei提供下载:
红外遥控 - 计算器(个位数相加).rar (43.2 KB, 下载次数: 34)


评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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