找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机代码实现按键-PC串口通讯-红外遥控控制电机

[复制链接]
跳转到指定楼层
楼主
51单片机代码实现按键-PC串口通讯-红外遥控控制电机


完整代码下载:
红外无线-PC机串口-按键控制PWM变化.rar (39.91 KB, 下载次数: 67)






部分源码预览:
  1. #include<reg51.h>  //51头文件,
  2. #include<intrins.h>
  3. //---------常用的两个宏定义--------------
  4. typedef unsigned char u8;
  5. typedef unsigned int  u16;

  6. //------------函数的声明-----------------
  7. void DelayMS(u16 dly);

  8. //--定义使用的IO口--//
  9. sbit LED=P1^3;
  10. sbit KEY1=P1^1;
  11. sbit KEY2=P1^2;
  12. sbit PWM=P2^1;

  13. sbit LSA=P2^2;
  14. sbit LSB=P2^3;
  15. sbit LSC=P2^4;
  16. sbit IRIN=P3^2;

  17. //--定义一个全局变量--//
  18. u16 num,j,k,pwm,i;        //定时器返回值
  19. u8  myKEY;        //存放电脑发送过来的按键

  20. u8 IrValue[6];
  21. u8 Time;
  22. u8 DisplayData[8];
  23. u8 code smgduan[17]={
  24. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  25. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
  26. //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码

  27.         //void Timer0Interrupt();
  28.         //void InitTimer1();
  29.         //void Keyscan();
  30. /*******************************************************************************
  31. * 函 数 名         : delay
  32. * 函数功能                   : 延时函数,i=1时,大约延时10us
  33. *******************************************************************************/
  34. void delay(u16 i)
  35. {
  36.         while(i--);       
  37. }

  38. void Delay10ms(u8 c)   //误差 0us
  39. {
  40.         u8 a, b;
  41.         for (;c>0;c--)                //--c已经在传递过来的时候已经赋值了,所以在for语句第一句就不用赋值了--//
  42.         {
  43.                 for (b=38;b>0;b--)
  44.                 {
  45.                         for (a=130;a>0;a--);
  46.                 }
  47.         }      
  48. }
  49. /*******************************************************************************
  50. * 函数名         :DigDisplay()
  51. * 函数功能                 :数码管显示函数
  52. * 输入           : 无
  53. * 输出                  : 无
  54. *******************************************************************************/
  55. void DigDisplay()
  56. {
  57.         u8 i;
  58.         for(i=0;i<3;i++)
  59.         {
  60.                 switch(i)         //位选,选择点亮的数码管,
  61.                 {
  62.                         case(0):
  63.                                 LSA=0;LSB=0;LSC=0; break;//显示第0位
  64.                         case(1):
  65.                                 LSA=1;LSB=0;LSC=0; break;//显示第1位
  66.                         case(2):
  67.                                 LSA=0;LSB=1;LSC=0; break;//显示第2位       
  68.                 }
  69.                 P0=DisplayData[i];//发送数据
  70.                 delay(10); //间隔一段时间扫描       
  71.                 P0=0x00;//消隐
  72.         }               
  73. }
  74. /*******************************************************************************
  75. * 函数名         : IrInit()
  76. * 函数功能                   : 初始化红外线接收
  77. * 输入           : 无
  78. * 输出                  : 无
  79. *******************************************************************************/

  80. void IrInit()
  81. {
  82.         IT0=1;//下降沿触发
  83.         EX0=1;//打开中断0允许
  84.         EA=1;        //打开总中断

  85.         IRIN=1;//初始化端口
  86. }
  87. /*******************************************************************************
  88. * 函 数 名         : Timer0Init
  89. * 函数功能                   : 定时器0初始化
  90. * 输    入         : 无
  91. * 输    出         : 无
  92. *******************************************************************************/
  93. void Timer0Init()
  94. {
  95.         TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

  96.         TH0 = 0xFF;
  97.         TL0 = 0xff;   //60ms
  98.                
  99.         ET0=1;//打开定时器0中断允许
  100.         EA=1;//打开总中断
  101.         TR0=1;//打开定时器                       
  102. }
  103. /*******************************************************************************
  104. * 函 数 名         : UsartInit()
  105. * 函数功能                   : 串口初始化
  106. * 输    入         : 无
  107. * 输    出         : 无
  108. *******************************************************************************/

  109. void UsartInit()
  110. {
  111.         SCON=0x50;        //设置串口工作模式1,允许接收

  112.         TMOD=0x20;  //设置定时器1工作方式2
  113.         PCON=0x80;  //波特率加倍
  114.         TH1=0xF3;        //设置定时器1初始值,波特率是4800bps
  115.         TL1=0xF3;                                          
  116.         TR1=1;                //启动定时器1

  117.         EA=1;                //打开总中断
  118.         ES=1;                //打开接收中断       
  119. }

  120. void main(void)
  121. {   
  122.         IrInit();

  123.         k=2;
  124.         Timer0Init();   //定时器0初始化
  125.         UsartInit();    // 串口初始化
  126.         IP=0x10;                //设置串口中断为高优先级

  127.         i=100;
  128.         while(1)
  129.         {
  130.                 DisplayData[0] = smgduan[IrValue[2]/16];
  131.                 DisplayData[1] = smgduan[IrValue[2]%16];
  132.                 DisplayData[2] = smgduan[16];
  133.             DigDisplay();
  134.                   
  135.                
  136.                 if (KEY1==0)  //检测按键K1是否按下
  137.                 {
  138.                         Delay10ms(1);        //消除抖动
  139.                         num=0;
  140.                         while (KEY1==0)        //再次检测按键是否按下
  141.                         {
  142.                                 Delay10ms(1);
  143.                                 num++;                //记录按键按下的时间
  144.                         }
  145.                         if(5<num&&num<50)        //此处一定不能定成0<num<50否则程序会认为是0<num而不会判定num<50;
  146.                         LED=~LED;
  147.                         i=i+5;
  148.                         if(num>50)
  149.                         k++;
  150.                         while(!KEY1)
  151.                         {
  152.                         }
  153.                 }

  154.                 if (myKEY=='x' || myKEY=='X')  //检测键盘按键是否按下
  155.                 {
  156.                        
  157.                         Delay10ms(1);        //消除抖动
  158.                         if (myKEY=='x' || myKEY=='X')        //再次检测键盘按键是否按下
  159.                         {
  160.                                 LED=~LED;
  161.                                 i=i+5;
  162.                                 myKEY=0;
  163.                         }
  164.                 }
  165.                 if (IrValue[2]/16==0&&IrValue[2]%16==9)  //检测遥控按键是否按下
  166.                 {
  167.                         LED=~LED;
  168.                         i=i+10;
  169.                         IrValue[2]=0x11;
  170.                 }


  171.                 else if (KEY2==0)
  172.                 {
  173.                         Delay10ms(1);
  174.                         if (KEY2==0)
  175.                         {
  176.                                 LED=~LED;
  177.                                 i=i-5;
  178.                                 j=0;
  179.                                 while ((j<30) && (KEY2==0))  //检测按键是否松开
  180.                                 {
  181.                                         Delay10ms(1);
  182.                                         j++;
  183.                                 }
  184.                         }      
  185.                 }
  186.                 P2=~k;

  187.                 if(myKEY=='y' || myKEY=='Y')          //按下键盘的Y键就亮,按其它键则灭
  188.                 {
  189.                         LED=~LED;
  190.                         i=i-5;
  191.                         myKEY=0;
  192.                 }
  193.                 if (IrValue[2]/16==1&&IrValue[2]%16==5)  //检测按键K1是否按下
  194.                 {
  195.                         LED=~LED;
  196.                         i=i-10;
  197.                         IrValue[2]=0x00;
  198.                 }

  199.         }
  200. }

  201. /*******************************************************************************
  202. * 函数名         : ReadIr()
  203. * 函数功能                   : 读取红外数值的中断函数
  204. * 输入           : 无
  205. * 输出                  : 无
  206. *******************************************************************************/

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

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

  268. void Timer0Interrupt(void) interrupt 1
  269. {
  270.         TH0 = 0xff;
  271.         TL0 = 0xff;
  272.         pwm++;
  273.         if(i>=200)         //改变i这个值可以改变直流电机的速度
  274.         {
  275.                 i=200;
  276.         }
  277.         if(pwm>200)  //PWM周期为100*0.5ms
  278.         {
  279.                 pwm=0;
  280.         }
  281.        

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


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

使用道具 举报

沙发
ID:466759 发表于 2019-1-31 23:47 | 只看该作者
唔,小白一个,不会用。。。。
回复

使用道具 举报

板凳
ID:253618 发表于 2019-2-6 13:15 | 只看该作者
楼主程序注释得很详细,感谢
回复

使用道具 举报

地板
ID:9727 发表于 2019-4-9 10:22 | 只看该作者
非常感谢,学习了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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