找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机按键控制风扇程序源代码(9G舵机摇头+直流电机出风)

[复制链接]
跳转到指定楼层
楼主
红外遥控风扇实验手册
一、元件清单
1、9G舵机                            1个
2、直流电机                     1个
3、电机支架                          1组
4、51主板                     1个
5、杜邦线                            若干
6、螺丝、螺帽            若干
二、软件
              1、Keil4软件
              2、程序烧录软件
三、硬件安装
1、舵机
2、直流电机
四、硬件接线
1.舵机接线说明
舵机
51开发板
红色
VCC
棕色
GND
橙色
P35

2.直流电机接线说明
一个脚接步进电机模块的+,另一个脚接步进电机模块的A 。



3.实物接线图
3.1602直插即可。

五、实验操作说明
用红外遥控器对准红外接收头,操作即可。

使用说明:

舵机信号线连接 P3.5
电机连接 uln2003 A脚
ch-     停止舵机转动
ch    开始舵机转动
prev     停止风扇转动
next     开始风扇转动
-        风扇减速
+        风扇加速


单片机按键控制风扇程序源代码如下:
  1. /*******************************************************************************
  2. * 实验名                           : 1602显示红外线值实验
  3. * 使用的IO             : 电机用P1口,键盘使用P3.0、P3.1、P3.2、P3.3
  4. * 实验效果       : LCD1602显示出读取到的红外线的值
  5. *        注意                                         :
  6. *******************************************************************************/
  7. #include<reg51.h>
  8. #include"lcd.h"
  9. #include <stdio.h>
  10. //#include "delay.h"


  11. sfr T2CON  = 0xC8;          //timer2 control register
  12. sfr RCAP2L = 0xCA;
  13. sfr RCAP2H = 0xCB;
  14. sfr TL2    = 0xCC;
  15. sfr TH2    = 0xCD;

  16. typedef unsigned char BYTE;
  17. typedef unsigned int WORD;

  18. #define FOSC 12000000L      //System frequency
  19. #define BAUD 9600       //UART baudrate

  20. /*Define UART parity mode*/
  21. #define NONE_PARITY     0   //None parity
  22. #define ODD_PARITY      1   //Odd parity
  23. #define EVEN_PARITY     2   //Even parity
  24. #define MARK_PARITY     3   //Mark parity
  25. #define SPACE_PARITY    4   //Space parity

  26. #define PARITYBIT NONE_PARITY   //Testing even parity

  27. sbit bit9 = P2^2;           //P2.2 show UART data bit9
  28. bit busy;

  29. sbit Sevro_moto_pwm = P3^5;           //接舵机信号端输入PWM信号调节速度

  30. sbit FanPin=P1^0;

  31. unsigned int pwm_val_left  = 0;//变量定义
  32. unsigned char push_val_left =14;//舵机归中,产生约,1.5MS 信号
  33. unsigned int  timer=0;                        //延时基准变量
  34. unsigned int  Servo_Ctr=0;

  35. unsigned int pwm_val_Fan=0;
  36. unsigned char Fan_speed=199;

  37. int flag=0;
  38. sbit IRIN=P3^2;

  39. unsigned char code CDIS1[13]={" Red Control "};
  40. unsigned char code CDIS2[13]={" IR-CODE:--H "};
  41. unsigned char code Test_OK[2]={"OK"};
  42. unsigned char IrValue[6];
  43. unsigned char Time;
  44. unsigned char IrOK=0;
  45. /*--------------------------------------------------------------
  46.                            函数声明
  47. --------------------------------------------------------------*/
  48. void InitUART(void);
  49. char putchar(char c);
  50. void IrInit();
  51. void DelayMs(unsigned int );
  52. void SendString(char *s);
  53. void SendData(BYTE dat);
  54. void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time);
  55. void pwm_Servomoto(void);
  56. void test_servo(void);
  57. void Motor_Ctr(void);

  58. void Pwm_Motor(void);
  59. /*******************************************************************************
  60. * 函数名         : main
  61. * 函数功能                   : 主函数
  62. * 输入           : 无
  63. * 输出                  : 无
  64. *******************************************************************************/

  65. void main()
  66. {
  67.         unsigned char i;
  68.             //串口初始化
  69.    

  70. //     printf("\r\n\n\r\n");
  71.    
  72.                 TMOD=0X11;
  73.         TH1=(65536-100)/256;          //100US定时
  74.         TL1=(65536-100)%256;
  75.         TH0=0;
  76.         TL0=0;  
  77.         TR1= 1;
  78.         ET1= 1;
  79.         ET0= 1;
  80.         EA = 1;

  81.         IrInit();       
  82.         LcdInit();
  83.         InitUART();

  84.         LcdWriteCom(0x80);
  85.        
  86.         for(i=0;i<13;i++)
  87.         {
  88.                 LcdWriteData(CDIS1[i]);       
  89.         }
  90.         LcdWriteCom(0x80+0x40);
  91.         for(i=0;i<13;i++)
  92.         {
  93.                 LcdWriteData(CDIS2[i]);       
  94.         }
  95.         while(1)
  96.         {
  97.             test_servo();
  98.                 IrValue[4]=IrValue[2]>>4;                          //高位
  99.                 IrValue[5]=IrValue[2]&0x0f;                //低位       
  100.                 if(IrValue[4]>9)
  101.                 {
  102.                         LcdWriteCom(0xc0+0x09);                        //设置显示位置
  103.                         LcdWriteData(0x37+IrValue[4]);        //将数值转换为该显示的ASCII码
  104.                 }
  105.                 else
  106.                 {
  107.                         LcdWriteCom(0xc0+0x09);
  108.                         LcdWriteData(IrValue[4]+0x30);        //将数值转换为该显示的ASCII码
  109.                 }       
  110.                 if(IrValue[5]>9)
  111.                 {
  112.                         LcdWriteCom(0xc0+0x0a);
  113.                         LcdWriteData(IrValue[5]+0x37);                //将数值转换为该显示的ASCII码
  114.                 }
  115.                 else
  116.                 {
  117.                         LcdWriteCom(0xc0+0x0a);
  118.                         LcdWriteData(IrValue[5]+0x30);                //将数值转换为该显示的ASCII码
  119.                 }       
  120.                 DelayMs(50);
  121.         //        printf("\r\n SZ-51 UART printftest OK if you see these words! c%c%",        IrValue[2],        IrValue[3]);
  122.                  if(IrOK==1)                           //如果处理好后进行红外处理
  123.         {
  124. //                printf("\r\n SZ-51 UART printftest OK if you see these words!");
  125.                 SendString(Test_OK);
  126.                         if(IrValue[4]>9)
  127.                 {
  128.                         LcdWriteCom(0x80+0x0d);                        //设置显示位置
  129.                         LcdWriteData(0x37+IrValue[4]);        //将数值转换为该显示的ASCII码
  130.                 }
  131.                 else
  132.                 {
  133.                         LcdWriteCom(0x80+0x0d);
  134.                         LcdWriteData(IrValue[4]+0x30);        //将数值转换为该显示的ASCII码
  135.                 }       
  136.                 if(IrValue[5]>9)
  137.                 {
  138.                         LcdWriteCom(0x80+0x0e);
  139.                         LcdWriteData(IrValue[5]+0x37);                //将数值转换为该显示的ASCII码
  140.                 }
  141.                 else
  142.                 {
  143.                         LcdWriteCom(0x80+0x0e);
  144.                         LcdWriteData(IrValue[5]+0x30);                //将数值转换为该显示的ASCII码
  145.                 }
  146.                    switch(IrValue[2])
  147.                       {
  148.                                     case 0x18:  
  149.                                                 LcdWriteCom(0x80+0x0f);
  150.                                                 LcdWriteData(CDIS1[3]);                //将数值转换为该显示的ASCII码
  151.                         break;
  152.                                                 case 0x52:  
  153.                                                 LcdWriteCom(0x80+0x0f);
  154.                                                 LcdWriteData(CDIS1[2]);                //将数值转换为该显示的ASCII码
  155.                         break;
  156.                                  default:break;
  157.                        }

  158.                    IrOK=0;
  159.         }
  160.                 else
  161.                 {
  162.                 //        printf("\r\n SZ-51 UART printftest OK if you see these words!");
  163.                 }
  164.                 DelayMs(50);
  165.         }
  166. }                                                                         
  167. /*******************************************************************************
  168. * 函数名         : DelayMs()
  169. * 函数功能                   : 延时
  170. * 输入           : x
  171. * 输出                  : 无
  172. *******************************************************************************/

  173. void DelayMs(unsigned int x)   //0.14ms误差 0us
  174. {
  175. unsigned char i;
  176.   while(x--)
  177. {
  178.   for (i = 0; i<13; i++)
  179. {}
  180. }
  181. }
  182. /*******************************************************************************
  183. * 函数名         : IrInit()
  184. * 函数功能                   : 初始化红外线接收
  185. * 输入           : 无
  186. * 输出                  : 无
  187. *******************************************************************************/

  188. void IrInit()
  189. {
  190.         IT0=1;//下降沿触发
  191.         EX0=1;//打开中断0允许
  192.         EA=1;        //打开总中断

  193.         IRIN=1;//初始化端口
  194. }
  195. /*******************************************************************************
  196. * 函数名         : ReadIr()
  197. * 函数功能                   : 读取红外数值的中断函数
  198. * 输入           : 无
  199. * 输出                  : 无
  200. *******************************************************************************/

  201. void ReadIr() interrupt 0
  202. {
  203.         unsigned char j,k;
  204.         unsigned int err;
  205.         Time=0;                                         
  206.         DelayMs(70);

  207.         if(IRIN==0)                //确认是否真的接收到正确的信号
  208.         {         
  209.                
  210.                 err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
  211.                 /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
  212.                 侯,程序死在这里*/       
  213.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                 
  214.                 {                       
  215.                         DelayMs(1);
  216.                         err--;
  217.                 }
  218.                 if(IRIN==1)                        //如果正确等到9ms低电平
  219.                 {
  220.                         err=500;
  221.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
  222.                         {
  223.                                 DelayMs(1);
  224.                                 err--;
  225.                         }
  226.                         for(k=0;k<4;k++)                //共有4组数据
  227.                         {                               
  228.                                 for(j=0;j<8;j++)        //接收一组数据
  229.                                 {

  230.                                         err=60;               
  231.                                         while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
  232. //                                        while (!IRIN)
  233.                                         {
  234.                                                 DelayMs(1);
  235.                                                 err--;
  236.                                         }
  237.                                         err=500;
  238.                                         while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
  239.                                         {
  240.                                                 DelayMs(1);//0.14ms
  241.                                                 Time++;
  242.                                                 err--;
  243.                                                 if(Time>30)
  244.                                                 {
  245.                                                         EX0=1;
  246.                                                         return;
  247.                                                 }
  248.                                         }
  249.                                         IrValue[k]>>=1;         //k表示第几组数据
  250.                                         if(Time>=8)                        //如果高电平出现大于565us,那么是1
  251.                                         {
  252.                                                 IrValue[k]|=0x80;
  253.                                         }
  254.                                         Time=0;                //用完时间要重新赋值                                                       
  255.                                 }
  256.                         }
  257.                 }
  258.                 if(IrValue[2]==~IrValue[3])
  259.                 {
  260.                        
  261.                         IrOK=1;

  262.                         DelayMs(5);
  263.                         return;
  264.                 }
  265.                 else
  266.                 {
  267.                         IrOK=0;
  268.                 }

  269.         }
  270.                
  271. }
  272. /*--------------------------------------------------------------
  273.                             串口初始化
  274. --------------------------------------------------------------*/
  275. void InitUART(void)
  276. {
  277. #if (PARITYBIT == NONE_PARITY)
  278.     SCON = 0x50;            //8-bit variable UART
  279. #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY)
  280.     SCON = 0xda;            //9-bit variable UART, parity bit initial to 1
  281. #elif (PARITYBIT == SPACE_PARITY)
  282.     SCON = 0xd2;            //9-bit variable UART, parity bit initial to 0
  283. #endif

  284.     TL2 = RCAP2L = (65536-(FOSC/32/BAUD)); //Set auto-reload vaule
  285.     TH2 = RCAP2H = (65536-(FOSC/32/BAUD)) >> 8;
  286.     T2CON = 0x34;           //Timer2 start run
  287.     ES = 1;                 //Enable UART interrupt
  288.     EA = 1;
  289. }     

  290. /*--------------------------------------------------------------
  291.              printf调用的底层发送一个字节函数
  292. --------------------------------------------------------------*/
  293. char putchar(char c)
  294. {
  295.     SBUF = c;
  296.     while(!TI);
  297.     TI = 0;

  298.     return c;
  299. }


  300. /*----------------------------
  301. UART interrupt service routine
  302. ----------------------------*/
  303. void Uart_Isr() interrupt 4 using 1
  304. {
  305.     if (RI)
  306.     {
  307.         RI = 0;             //Clear receive interrupt flag
  308.         P0 = SBUF;          //P0 show UART data
  309.         bit9 = RB8;         //P2.2 show parity bit
  310.     }
  311.     if (TI)
  312.     {
  313.         TI = 0;             //Clear transmit interrupt flag
  314.         busy = 0;           //Clear transmit busy flag
  315.     }
  316. }

  317. /*----------------------------
  318. Send a byte data to UART
  319. Input: dat (data to be sent)
  320. Output:None
  321. ----------------------------*/
  322. void SendData(BYTE dat)
  323. {
  324.     while (busy);           //Wait for the completion of the previous data is sent
  325.     ACC = dat;              //Calculate the even parity bit P (PSW.0)
  326.     if (P)                  //Set the parity bit according to P
  327.     {
  328. #if (PARITYBIT == ODD_PARITY)
  329.         TB8 = 0;            //Set parity bit to 0
  330. #elif (PARITYBIT == EVEN_PARITY)
  331.         TB8 = 1;            //Set parity bit to 1
  332. #endif
  333.     }
  334.     else
  335.     {
  336. #if (PARITYBIT == ODD_PARITY)
  337.         TB8 = 1;            //Set parity bit to 1
  338. #elif (PARITYBIT == EVEN_PARITY)
  339.         TB8 = 0;            //Set parity bit to 0
  340. #endif
  341.     }
  342.     busy = 1;
  343.     SBUF = ACC;             //Send data to UART buffer
  344. }

  345. /*----------------------------
  346. Send a string to UART
  347. Input: s (address of string)
  348. Output:None
  349. ----------------------------*/
  350. void SendString(char *s)
  351. {
  352.     while (*s)              //Check the end of the string
  353.     {
  354.         SendData(*s++);     //Send current char and increment string ptr
  355.     }
  356. }


  357. /************************************************************************/
  358. /*                    PWM调制舵机电机转速                                   */
  359. /************************************************************************/
  360. /*                    舵机电机调速                                        */
  361. /*调节push_val_left的值改变舵机电机转速,占空比            */
  362.                 void pwm_Servomoto(void)
  363. {  

  364.     if(pwm_val_left<=push_val_left)
  365.                Sevro_moto_pwm=1;
  366.         else
  367.                Sevro_moto_pwm=0;
  368.         if(pwm_val_left>=200)
  369.         pwm_val_left=0;

  370. }

  371. void Pwm_Motor(void)
  372. {
  373.         if(flag==1)
  374.         {
  375.          FanPin=0;
  376.         }
  377.         else
  378.         {
  379.          if(pwm_val_Fan<=Fan_speed)
  380.                FanPin=1;
  381.         else
  382.                FanPin=0;
  383.         if(pwm_val_Fan>=200)
  384.         pwm_val_Fan=0;
  385.         }
  386. }
  387. /***************************************************/
  388. ///*TIMER1中断服务子函数产生PWM信号*/
  389.         void time1()interrupt 3   using 2
  390. {       
  391.      TH1=(65536-100)/256;          //100US定时
  392.          TL1=(65536-100)%256;
  393.          timer++;                                  //定时器100US为准。在这个基础上延时
  394.          pwm_val_left++;
  395.          pwm_val_Fan++;
  396.          pwm_Servomoto();
  397.          Pwm_Motor();
  398.          
  399. }

  400. void pwm_Servomoto_angle(unsigned int angle,unsigned int Servo_time)
  401. {
  402.                   push_val_left=5+angle*20/180;          //舵机向左转90度
  403.                   timer=0;
  404.                   while(timer<=Servo_time); //延时400MS让舵机转到其位置                 4000
  405. }


  406. void test_servo(void)
  407. {
  408. int pos;
  409.         for(pos=0;pos<180;pos+=3)
  410.         {
  411.                 Motor_Ctr();
  412. //                pwm_Fan_speed();
  413.                 while(Servo_Ctr==0)
  414.                 {
  415.                 Motor_Ctr();
  416.                
  417.                 }
  418.        
  419.                 pwm_Servomoto_angle(pos,100) ;
  420.                 DelayMs(10);
  421.         }
  422.         for(pos = 180; pos>=0; pos-=3)     // goes from 180 degrees to 0 degrees
  423.         {
  424.                 Motor_Ctr();

  425.                 while(Servo_Ctr==0)
  426.                 {
  427.                         Motor_Ctr();
  428.                        

  429.                 }
  430.                
  431.           pwm_Servomoto_angle(pos,100) ;
  432.           DelayMs(10);
  433.         }
  434. }

  435. void Motor_Ctr(void)
  436. {
  437.                           switch(IrValue[2])
  438.                       {
  439.                     case 0x44:  
  440.                                 FanPin=0;
  441.                                  flag=1;
  442.                 break;
  443.                                 case 0x40:  
  444.                                 FanPin=1;
  445.                                 flag=0;
  446.                 break;
  447.                                 case 0x45:  
  448.                                 Servo_Ctr=0;
  449.                 break;
  450.                                 case 0x46:  
  451.                                 Servo_Ctr=1;
  452.                 break;

  453.                                 case 0x07:
  454.                                 if(Fan_speed>200)
  455.                                 {
  456.                                         Fan_speed=200;
  457.                                 }
  458.                                 if(Fan_speed<0)
  459.                                 {
  460.                                         Fan_speed=0;
  461.                                 }
  462.                                 Fan_speed=Fan_speed-20;
  463.                 break;
  464.                                 case 0x15:  
  465.                                 if(Fan_speed>200)
  466.                                 {
  467.                                         Fan_speed=200;
  468.                                 }
  469.                                 if(Fan_speed<0)
  470.                                 {
  471.                                         Fan_speed=0;
  472.                                 }
  473.                                 Fan_speed=Fan_speed+20;
  474.                 break;
  475.                                 default:break;
  476.                        }
  477. }
复制代码


所有资料51hei提供下载:
红外遥控风扇-lcd1602显示键值.zip (2.51 MB, 下载次数: 29)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:396611 发表于 2018-12-8 22:55 | 只看该作者
我想问一些问题可以帮我解答一下吗?那个程序里面的FanPins是什么意思呀
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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