找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机红外遥控直流电机调速系统的程序设计

[复制链接]
跳转到指定楼层
楼主
ID:346510 发表于 2019-1-13 14:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
红外遥控直流电机调速系统的设计 杜鹏 2015214213 实验八.zip (116.71 KB, 下载次数: 49)

单片机程序源码:
  1. #include <reg51.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sbit RS=P2^6;   //LCD引脚
  5. sbit RW=P2^5;
  6. sbit EN=P2^7;
  7. sbit IRIN=P3^2;  //红外接口
  8. sbit PWM_Out=P1^0;  //PWM输出引脚

  9. uchar tab[]={"IR-CODE:00H"};                                                                                          
  10. unsigned char IrValue[6];
  11. unsigned char Time;
  12. unsigned char PWM_Cnt,PWM_Duty; //PWM_cnt : PWM周期变量 0~10; PWM_Duty: 占空比变量0~10
  13. void System_Init();   
  14. void Delay_Ms(unsigned int x);
  15. void delayms(uint ms)
  16. {
  17.   uint i,j;
  18.   for (i=ms;i>0;i--)
  19.   for(j=0;j<124;j++);
  20. }
  21. void lcdwc(uchar com)//写入命令
  22. {
  23.         RS=0;  //选择写入命令
  24.         RW=0;  //选择写入
  25.         EN=0;  //使能清零
  26.         P0=com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  27.         delayms(5);
  28.         EN=1;  //写入时序
  29.         delayms(5);
  30.         EN=0;  
  31.         P0=com<<4;//发送低四位
  32.         delayms(5);
  33.         EN= 1;         //写入时序
  34.         delayms(5);
  35.         EN= 0;

  36. }

  37. void lcdwd(uchar dat)//写入数据
  38. {
  39.         RS=1; //选择写入数据
  40.         RW=0; //选择写入
  41.         EN=0; //使能清零
  42.         P0=dat;//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  43.         delayms(5);
  44.         EN=1; //写入时序
  45.         delayms(5);
  46.         EN=0;
  47.         P0=dat<< 4; //写入低四位
  48.         delayms(5);
  49.         EN=1; //写入时序
  50.         delayms(5);
  51.         EN=0;

  52. }

  53. void initlcd()
  54. {
  55.         lcdwc(0x32); //将8位总线转为4位总线
  56.         lcdwc(0x28);//在四位线下的初始化
  57.         delayms(5);
  58.         lcdwc(0x0c);//00001100 显示开及光标设置
  59.         lcdwc(0x06);//00000110 显示光标移动设置
  60.         lcdwc(0x01);//00000001 清屏
  61.                
  62. }

  63. void main()
  64. {
  65.         uchar i;
  66.         initlcd();
  67.         lcdwc(0x80);//设置数据指针起点

  68.         for(i=0;i<11;i++)
  69.         {
  70.      lcdwd(tab[i]);               
  71.         }
  72.         
  73.         System_Init();
  74.         while(1)
  75.         {
  76.                
  77.         }
  78. }
  79. void System_Init()
  80. {
  81.         TMOD |= 0X10;   //定时器1 16位计时模式   
  82.         
  83.         TH1=(65536-1000)/256;   //定时1ms中断一次   生成100HZ 的PWM信号
  84.         TL1=(65536-1000)%256;
  85.         TR1=1;
  86.         ET1=1;
  87.         
  88.         IT0=1;//下降沿触发
  89.         EX0=1;//打开中断0允许
  90.         EA=1;        //打开总中断

  91.         IRIN=1;//初始化端口        
  92. }
  93. /*******************************************************************************
  94. * 函数名         : DelayMs()
  95. * 函数功能                   : 延时
  96. * 输入           : x
  97. * 输出                  : 无
  98. *******************************************************************************/

  99. void Delay_Ms(unsigned int x)   //0.14ms误差 0us
  100. {
  101. unsigned char i;
  102.   while(x--)
  103. {
  104.   for (i = 0; i<13; i++)
  105. {}
  106. }
  107. }

  108. void ReadIr() interrupt 0
  109. {
  110.         unsigned char j,k;
  111.         unsigned int err;
  112.         Time=0;                                         
  113.         Delay_Ms(70);

  114.         if(IRIN==0)                //确认是否真的接收到正确的信号
  115.         {         
  116.                
  117.                 err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
  118.                 /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
  119.                 侯,程序死在这里*/        
  120.                 while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                  
  121.                 {                        
  122.                         Delay_Ms(1);
  123.                         err--;
  124.                 }
  125.                 if(IRIN==1)                        //如果正确等到9ms低电平
  126.                 {
  127.                         err=500;
  128.                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
  129.                         {
  130.                                 Delay_Ms(1);
  131.                                 err--;
  132.                         }
  133.                         for(k=0;k<4;k++)                //共有4组数据
  134.                         {                                
  135.                                 for(j=0;j<8;j++)        //接收一组数据
  136.                                 {

  137.                                         err=60;               
  138.                                         while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
  139. //                                        while (!IRIN)
  140.                                         {
  141.                                                 Delay_Ms(1);
  142.                                                 err--;
  143.                                         }
  144.                                         err=500;
  145.                                         while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
  146.                                         {
  147.                                                 Delay_Ms(1);//0.14ms
  148.                                                 Time++;
  149.                                                 err--;
  150.                                                 if(Time>30)
  151.                                                 {
  152.                                                         EX0=1;
  153.                                                         return;
  154.                                                 }
  155.                                         }
  156.                                         IrValue[k]>>=1;         //k表示第几组数据
  157.                                         if(Time>=8)                        //如果高电平出现大于565us,那么是1
  158.                                         {
  159.                                                 IrValue[k]|=0x80;
  160.                                         }
  161.                                         Time=0;                //用完时间要重新赋值                                                        
  162.                                 }
  163.                         }
  164.                 }
  165.                 IrValue[4]=IrValue[2]>>4;                          //高位
  166.                 IrValue[5]=IrValue[2]&0x0f;                //低位        
  167.                 if(IrValue[4]>9)
  168.                 {                                       
  169.                         lcdwc(0x80+8);//设置数据指针起点
  170.                         lcdwd(0x37+IrValue[4]);        
  171.                 }
  172.                 else
  173.                 {
  174.                         lcdwc(0x80+8);//设置数据指针起点
  175.                         lcdwd(0x30+IrValue[4]);        
  176.                 }        
  177.                 if(IrValue[5]>9)
  178.                 {
  179.                         lcdwc(0x80+9);//设置数据指针起点
  180.                         lcdwd(0x37+IrValue[5]);        
  181.                 }
  182.                 else
  183.                 {
  184.                         lcdwc(0x80+9);//设置数据指针起点
  185.                         lcdwd(0x30+IrValue[5]);        
  186.                 }        
  187.                 if(IrValue[2]==0x0C)
  188.                 {
  189.                         if(PWM_Duty<10)
  190.                                 PWM_Duty+=1;
  191.                 }
  192.                 if(IrValue[2]==0x18)
  193.                 {
  194.                         if(PWM_Duty>0)
  195.                                 PWM_Duty-=1;
  196.                 }
  197.            if(IrValue[2]==0x5E)
  198.                 {
  199.           PWM_Duty=5;                           
  200.                 }
  201.                   
  202.                 if(IrValue[2]!=~IrValue[3])
  203.                 {
  204.                         return;
  205.                 }
  206.         }                        
  207. }
  208. void T1_service() interrupt 3   //定时器1中断函数
  209. {
  210.         TH1=(65536-1000)/256;  
  211.         TL1=(65536-1000)%256;
  212.         /*----------------------------------------------
  213.                 PWM控制脉宽:   cnt变量会在  0~~~~~~~~~~10 之间循环
  214.                                                                                                                                                         ^
  215.                                                                                                                                                         |
  216.                                                                                                                                                 PWM_Duty
  217.         
  218.                 PWM_Duty取0~10中的值会得到不同占空比的PWM波;
  219.                 当cnt<PWM_Duty时 IO口输出高定平,否则为低电平。
  220.        ----------------------------------------------*/
  221.         PWM_Cnt++;    //PWM 变量计数
  222.         if(PWM_Cnt>=10) //计数变量限制范围在0~10
  223.                 PWM_Cnt=0;
  224.         
  225.         if(PWM_Cnt<PWM_Duty)   //控制PWM引脚电平变化
  226.                 PWM_Out=1;
  227.         else
  228.         PWM_Out=0;
  229.         }
复制代码

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:566605 发表于 2019-6-27 15:32 | 只看该作者
那个按键控制呀 连接好无法控制
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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