找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16413|回复: 10
收起左侧

基于51单片机的红外遥控电风扇设计源码与资料分享

  [复制链接]
ID:425054 发表于 2018-11-12 15:36 | 显示全部楼层 |阅读模式
原理图都在资料里,资料在附件l,曾经的课程设计

制作出来的红外遥控电风扇实物图如下:
0.jpg 1.jpg

电路原理图如下:
0.png

红外遥控器配置图:
0.png

元件清单:
STC89C52/C51单片机        1
10uF电解电容            2
10K色环电阻        4
1K色环电阻        1
22pF瓷片电容        2
11.0592Mhz晶振        1
DIP40单片机插座        1
7cm*9cm万孔板        1
2.5mm排针        3+2
自复位按键        1   
DC5V的电源座        2
DC5V的USB电源线        2
小的LED电源指示灯        1
焊接跳线        不计
4.7K排阻            1
VS1838B红外接收头        1
通用红外遥控器        1
DC5V 马达        1
L9110H 电机驱动芯片    1
VS1838B红外接收头        1
红外遥控器        1

红外遥控电风扇单片机源程序如下:

  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=P2^0;
  9. sbit dianji2=P2^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=9;
  171.                                
  172.                                                 break;  
  173.                 case 0x46:       
  174.         //P2=0xff;
  175. //        timer1_init();//定时器1初始化
  176.                                                   PWM_val_buf=PWM_val;
  177.                                         PWM_val=0;

  178.                                        
  179.                                 //        }
  180.                                         break;
  181.                 case 0x0C:                                        //亮度
  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=6;
  191.                                
  192.                                         break;
  193.             case 0x5E:                        //亮度
  194.                           //  timer1_init();//定时器1初始化
  195.                                                 PWM_val=9;
  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. /************************************************************/
复制代码
QQ截图20181112153303.png
所有资料51hei提供下载:
王一哲——散件红外遥控器控制直流电机PWM转速设计资料.zip (594.09 KB, 下载次数: 353)

评分

参与人数 2黑币 +55 收起 理由
都市郎 + 5 共享资料的黑币奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:92513 发表于 2019-5-1 11:05 | 显示全部楼层
感谢分享,程序编译成功 慢慢研究
回复

使用道具 举报

ID:539074 发表于 2019-5-15 17:08 | 显示全部楼层
请问这个的子程序框图怎么画呢
回复

使用道具 举报

ID:484435 发表于 2019-5-15 18:49 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:562262 发表于 2019-6-13 23:48 | 显示全部楼层
新手前来围观,好
回复

使用道具 举报

ID:571461 发表于 2019-6-27 08:54 | 显示全部楼层
我的开发板还有遥控都不一样,这个程序好像没用,我的电机风扇也不是焊的,不知道要往哪里接,求大神解惑
回复

使用道具 举报

ID:573668 发表于 2019-6-27 19:38 | 显示全部楼层
很帮很好支持加油
回复

使用道具 举报

ID:451441 发表于 2019-11-13 13:57 | 显示全部楼层
很全面的资料,谢谢LZ分享
回复

使用道具 举报

ID:694235 发表于 2020-2-17 13:09 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:808455 发表于 2020-7-27 14:41 | 显示全部楼层
感谢分享 先下来看看 不知道懂不懂
回复

使用道具 举报

ID:808455 发表于 2020-7-27 14:42 | 显示全部楼层
考虑的很周到啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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