找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的红外遥控和按键调速风扇程序

  [复制链接]
跳转到指定楼层
楼主
ID:974010 发表于 2022-3-28 20:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. /*************************************************************************/
  2. #include <reg52.h>      
  3. #include <intrins.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. /***********端口定义*****************/
  7. sbit IR_R=P3^3;      //红外线数据接收口



  8. sbit dianji1=P1^0;
  9. sbit dianji2=P1^1;



  10. /************************************/
  11. /***********寄存器定义***************/
  12. //以下为红外接收解码用到的寄存器
  13. uchar IR_receive_time;      //红外接收脉冲时间计数
  14. bit IR_receive_flag;      //红外接收检测启动标志位

  15. uchar IR_receive_data[33];  //红外数据接收缓存接收计数脉冲个数 引导码+8位地址码+8位地址码+8位数据码+8位数据反码

  16. uchar IR_receive_bit;       //红外接收数据位标志
  17. bit IR_receive_OK;        //红外数据接收完毕标志

  18. uchar IR_receive_code[4];   //红外解码数据缓存

  19. bit IR_receive_end;       //红外解码结束标志位      
  20. //键值相关定义
  21. bit ON_flag;  //开标志

  22. //PWM相关寄存器定义
  23. #define                PWM_DUTY_MAX        10        // 0~255        PWM周期, 最大255
  24. #define                PWM_ON                        0        // 定义占空比的电平, 1 或 0

  25. #define                PWM_OFF                        (!PWM_ON)
  26. uchar pwm_cnt;                //周期计数值
  27. uchar PWM_val;
  28. uchar PWM_val_buf;
  29. /*******1ms基准延时程序*******************/
  30. void Delay1ms(uint t)    //1ms延时程序
  31. {
  32.         uchar j;
  33.         while(t--)
  34.         {
  35.                 for(j=0;j<125;j++)
  36.                 { ; }
  37.         }
  38. }
  39. /****************************************/
  40. /************************************************************************
  41. //定时器1中断服务子函数产生PWM信号
  42. void timer1() interrupt 3                 //定时器1设置为8位自动重装
  43. {      
  44.         if(++pwm_cnt==PWM_DUTY_MAX)        //PWM周期结束,重新开始新的周期
  45.         {
  46.                 pwm_cnt=0;
  47.                 P1=PWM_ON;   
  48.         }
  49.         if(pwm_cnt==PWM_val)         P1=PWM_OFF;  //判断PWM占空比是否结束  高电平结束
  50. }
  51. /***************************************************/
  52. /********************红外解码初始化设置程序***********************/
  53. void IR_receive_init(void)   //定时器0设置函数
  54. {
  55.         IR_receive_time=0;
  56.         IR_receive_flag=0;
  57.         IR_receive_bit=0;
  58.         IR_receive_OK=0;
  59.         IR_receive_end=0;
  60.         TMOD=0x22;         //设置定时器0为8位自动重装计数
  61.         TH0=0x00;
  62.         TL0=0x00;          //设置定时时间为256us
  63.         ET0=1;             //定时器0中断打开
  64.         EA=1;              //总中断打开         
  65.         TR0=1;             //启动定时器0
  66. }
  67. /*************************************************************/
  68. /*******************红外接收口外部中断0设置函数*********************/
  69. void int0init(void)
  70. {
  71.         IT0=1;            //外部中断0触发方式设置为下降沿触发
  72.         EX0=1;            //外部中断0中断打开
  73.         EA=1;             //总中断打开
  74. }
  75. /*******************************************************************/
  76. /***********************红外接收产生256us定时计数程序***************/
  77. void time0(void) interrupt 1      //定时器0中断处理函数
  78. {
  79.         IR_receive_time++;            //红外接收定时脉冲计数器
  80. }
  81. /*******************************************************************/
  82. /***********************红外33位数据(含一位引导码)接收程序************************/
  83. void int0() interrupt 0         //外部中断0处理程序
  84. {
  85.         if(IR_receive_flag)    //红外数据接收检测标志位
  86.         {
  87.                 if(IR_receive_time>32&&IR_receive_time<63)   //检测接收时间是否在8-16ms范围,若在,说明接收到红外引导码
  88.                 {
  89.                         IR_receive_bit=0;    //红外接收数据位标志 清0
  90.                 }
  91.                 IR_receive_data[IR_receive_bit]=IR_receive_time;    //接收数据(每位数据的脉冲时间)
  92.                 IR_receive_time=0;        //红外接收定时脉冲计数器  清0 准备等待接收下一位数的脉冲时间
  93.                 IR_receive_bit++;         //红外接收数据位标志 接收下一位数据
  94.                 if(IR_receive_bit==33)    //判断包括一位引导码和32位数据是否接收完成
  95.                 {
  96.                         IR_receive_bit=0;     //接收完毕,则接收数据位标志清0
  97.                         IR_receive_OK=1;      //红外接收完毕标志位置1,表示数据已接收完
  98.                 }
  99.         }
  100.         else
  101.         {
  102.                 IR_receive_flag=1;     //红外接收启动标志
  103.                 IR_receive_time=0;     //红外接收脉冲计数器清0 准备计数
  104.         }
  105. }
  106. /*********************************************************************/
  107. /*****************************红外数据解码程序************************/
  108. void IR_code(void)
  109. {
  110.         uchar k,i,j,value;
  111.         k=1;                 //k=1意思是跳过引导码数据,不处理接收引导码
  112.         for(j=0;j<4;j++)     //有4组数据,即8位地址码+8位地址码+8位数据码+8位数据码反码
  113.         {
  114.                 for(i=0;i<8;i++)     //每组数据有8位二进制数
  115.                 {
  116.                         value=value>>1;      //寄存器数据位右移一位   接收数据是从每组数据的低位到高位接收的
  117.                         if(IR_receive_data[k]>6)     //通过判断计数脉冲时长确定个位数是0还是1  通过计算我们得知数据0的时长为4.4ms,数据1的时长为8.8ms,我们取中间值6,则大于6说明为数量1
  118.                         {
  119.                                 value=value|0x80;    //确定一组8位数据的一位(bit)数值
  120.                         }
  121.                    k++;
  122.                 }
  123.                 IR_receive_code[j]=value;    //确定一组8位数据的值
  124.         }
  125.         IR_receive_end=1;      //红外数据解码完成标志
  126. }
  127. /*********************************************************************/

  128. /*********定时器1初始化程序*********************/
  129. void timer1_init(void)
  130. {

  131.         TMOD = 0x22;  //设置定时器为模式2(8位自动重装载)
  132.         TL1=0x9C;  //初始化计时值 100us 9C  50us CE
  133.         TH1=0x9C;
  134.         TR1=1;  //启动定时器1
  135.         ET1=1;  //开启定时器1中断
  136.         EA=1;   //开总中断
  137. }
  138. /***********************************************/
  139. void timer1(void) interrupt 3
  140. {
  141.         pwm_cnt++;
  142.         if(pwm_cnt>=PWM_DUTY_MAX)        //PWM周期结束,重新开始新的周期
  143.         {
  144.                 pwm_cnt=0;
  145.         //        P1=PWM_ON;  
  146.                         dianji1=0;
  147. //                                zhishi=0;
  148.         }
  149.         if(pwm_cnt>=PWM_val) //        P1=PWM_OFF;  //判断PWM占空比是否结束  高电平结束      
  150.         {
  151.                                 dianji1=1;
  152. //zhishi=1;
  153.         }                                 
  154. }
  155. /***********************************************/
  156. /*****************红外键值处理程序***************************/
  157. void IR_check(uchar tmp)
  158. {
  159.         switch(tmp){
  160.                 case 0x45:  
  161.                            //按键1         开 LED灯   
  162.                                   //        if(ON_flag==0)  
  163.                                 //        {
  164.                                          //   ON_flag=1;
  165.                                           PWM_val=PWM_val_buf;
  166.                                        
  167.                                           //P2=0x00;
  168.                                 //        }
  169.                                         timer1_init();//定时器1初始化
  170.                         PWM_val=1;
  171.                               
  172.                                                 break;  
  173.                 case 0x0C:      
  174.         //P2=0xff;
  175. //        timer1_init();//定时器1初始化
  176.                                                   PWM_val_buf=PWM_val;
  177.                                         PWM_val=0;

  178.                                        
  179.                                 //        }
  180.                                         break;
  181.                 case 0x08:                                        //亮度
  182.                           //  if(ON_flag==1)
  183.                                 //        {
  184.                                         //        timer1_init();//定时器1初始化
  185.                                                 PWM_val=4;

  186.                                 //        }
  187.                                         break;
  188.             case 0x18:                        //亮度
  189.                                   //        timer1_init();//定时器1初始化
  190.                                                 PWM_val=1;
  191.                               
  192.                                         break;
  193.             case 0x5E:                        //亮度
  194.                           //  timer1_init();//定时器1初始化
  195.                                                 PWM_val=3;
  196.                               
  197.                                         break;
  198.          
  199.         }
  200. }

  201. /************************************************************/
  202. /**************主程序****************************************/
  203. void main()
  204. {
  205.     //PWM_val=5;  //占空比
  206.         //PWM_val_buf=5;
  207.         IR_receive_init();   //红外初始化设置程序
  208.         int0init();          //外部中断0设置
  209.         //P2=0x00;

  210.         dianji2=1;

  211.         while(1)                                                     
  212.         {
  213.          
  214.                 if(IR_receive_OK)
  215.                 {
  216.                 //        IR_receive_OK=0;
  217.                         IR_code();    //红外数据解码
  218.                 }
  219.                 if(IR_receive_end)
  220.                 {
  221.                         IR_receive_end=0;

  222.                         EX0=0;
  223.                         if(IR_receive_code[0]==0x00&&IR_receive_code[1]==0xFF)  //判断用户码是否正确
  224.                         {
  225.                                 if(IR_receive_code[2]==~IR_receive_code[3])  //判断反码是否正确
  226.                                 {
  227.                                         IR_check(IR_receive_code[2]);  //红外按键值处理程序
  228.                                 }
  229.                         }
  230.          //   IR_receive_init();   //再次启动红外解码设置程序,等待下一次解码
  231.                         int0init();          //外部中断0设置
  232.                 }
  233.         }
  234. }
  235. /************************************************************/
复制代码
可以通过红外遥控控制电机挡位。

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:1032802 发表于 2022-6-7 09:26 | 只看该作者
请问有没有仿真电路图
回复

使用道具 举报

板凳
ID:974010 发表于 2022-7-15 21:03 | 只看该作者
@无名 发表于 2022-6-7 09:26
请问有没有仿真电路图

不好意思,没有啊。就是跟普中开发板一样的电路图
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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