zoukankan      html  css  js  c++  java
  • 51单片机控制步进电机

             将自己大学做的为数不多的编程学习进行记录,选修嵌入式之前,师兄提醒我这作业量大,还是选了,因为对编程有一种向往。差点挂掉这门课,每周要交作业,学习一到两个硬件知识,真的比想象中吃力,到最后还是顺利交完作业,通过了课程。这个课程正逢《流浪地球》热播,老师第一节课说了其中电影中有一点很真实:“没有硬件支撑和配合,程序不管用。”通过这个课程,确实了解到了硬件的重要性,以前看到的黑客电影一下子分为严谨和糊弄观众两种了。

    1. 使用Keil 4编写C语言程序,编译生成.hex文件,使用Proteus7.8进行仿真
    2. 使用了51单片机,按键,电机等一系列硬件
    3. #include <reg52.h>
      #include <intrins.h>
      #include <string.h>
      #define uint unsigned int
      #define uchar unsigned char
      
      sbit IN1 = P1^0;
      sbit IN2 = P1^1;
      sbit ENA = P1^2;
      sbit RS = P2^5;
      sbit RW = P2^6;
      sbit EN = P2^7;    
      sbit k1 = P2^0;       //正转
      sbit k2 = P2^1;       //反转
      sbit k3 = P2^2;       //加速
      sbit k4 = P2^3;       //减速
      sbit k5 = P2^4;       //暂停
      sbit inter0    =P3^2;
      
      
      int g,s,b,q,t,e;                    //定义转速各位
      int m,n,num,PWM=100,PWMH=50;      
      int ZS=0,PWMH_1,PWMH_2,PWMH_3;        //转速
      
      uchar LCD_DSY_BUFFER1[]={"ZS 040 PWM 050%"};    //  buffer缓冲器 
      
      
      /*******************************************************************************
      * 函 数 名         : Timer0Init
      * 函数功能           : 定时器0初始化
      *******************************************************************************/
      void Timer0Init()
      {
          TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
          TH0=0XFC;    //给定时器赋初值,定时1ms
          TL0=0X18;    
          TR0=1;//打开定时器
          ET0=1;//打开定时器1中断允许
          EA=1;  //打开总中断            
      }
      
      /*******************************************************************************
      * 函 数 名         : Int1Init()
      * 函数功能           : 设置外部中断1
      *******************************************************************************/
      void Int0Init()       //设置INT0
      {
          
          IT0=1;//1-跳变沿出发方式(下降沿)0-低电平触发
          EX0=1;//打开INT0的中断允许。    
          EA=1;//打开总中断    
      }
      
      /*================测量转速,利用外部中断INT0和定时器T0,每1s计算一次============*/
       /*============定时器0 PWM输出,调节转速    ============*/
      
       void X0_time() interrupt 0      //外部中断0部分
       {
           inter0=0;
          m++;      //计算脉冲
          inter0=1;
       }
      
      //定时器T0中断部分
       void T0_time() interrupt 1     // interrupt 1 为定时器中断0; 0-外部中断0;  2-外部中断1;3-定时器1;4-串口 
       {
          TH0 = 0XFC;                   //      TH0=(65536-1000)/256;      定时1ms
          TL0 = 0x18;    
              
          num++;                       //这是计算溢出次数(脉冲宽度)
          t++;
      
          if(num>=100)                      //周期100ms,num=1 表示1ms
          num=0;
      
      
          if(num<=PWMH)
              ENA=1;                          //置高电平
          else    
              ENA=0;
      
      
              
          if(t==970)                           //1s时间到,计算转速      1000ms
          {
      
              ZS=m*60/24;               //一转2脉冲
              b=ZS%1000/100;
              s=ZS%100/10;
              g=ZS%10;                   
              ZS=m*60/2;                 
              m=0;        
              t=0;                 
          }
      
       }
      
      
      void delay(uchar z)        //延时0.5MS
      {    uchar y;
          for(z;z>0;z--)
               for(y=243;y>0;y--);
      }
      
      void keyscan()
      {
      
          if(k1==0)     //正转
          {
              e=1;
              while(!k1);
          }
          if(k2==0)    //反转
          {
              e=2;
              while(!k2);        
          }
      
           if(k3==0)     //加速
          {
              PWMH=PWMH+10;
              if(PWMH>=110)
              { PWMH=30; }
              while(!k3);
          }
          if(k4==0)    //减速
          {
              PWMH=PWMH-10;
              if(PWMH<=-10)
              { PWMH=30; }
              while(!k4);                    
          }
          if(k5==0)     //暂停、启动
          {
              e=0;
              while(!k5);
          }
          PWMH_1=PWMH/100;
          PWMH_2 =   PWMH    %100/10;
          PWMH_3    =PWMH%10;
      
      }                   
      
      /****************LCD显示部分********************/
      uchar Read_LCD_State()                    //    6  1602
      {
           uchar state;
          RS=0;RW=1;EN=1;delay(1);
          state=P0;
          EN = 0;delay(1);
          return state;
      }
      
      void LCD_Busy_Wait()                        // 7
      {
           while((Read_LCD_State()&0x80)==0x80);       //当最高位为1时,延时5秒
          delay(5);
      }
      
      void Write_LCD_Data(uchar dat)                 // 8
      {
           LCD_Busy_Wait();
          RS=1;RW=0;EN=0;P0=dat;EN=1;delay(1);EN=0;          //dat为
      }
      
      void Write_LCD_Command(uchar cmd)    // 9  command命令 控制
      {
           LCD_Busy_Wait();
          RS=0;RW=0;EN=0;P0=cmd;EN=1;delay(1);EN=0;         //cmd为地址
      }
      
      
      void Init_LCD()                                 //  10     初始化
      {
           Write_LCD_Command(0x38);           //显示16*2显示,5*7点阵,8位数据接口
          delay(1);                           
          Write_LCD_Command(0x01);           //显示清零,数据指针清零
          delay(1);    
          Write_LCD_Command(0x06);           //写一个字符后地址指针加一
          delay(1);    
          Write_LCD_Command(0x0c);            //设置开显示,不显示光标
          delay(1);    
      }
      
      void Set_LCD_POS(uchar p)                     // 11
      {
           Write_LCD_Command(p|0x80);      //
      }
      
      void Display_LCD_String(uchar p,uchar *s)        //12 在LCD显示    Display_LCD_String(0x00,LCD_DSY_BUFFER1);
      {
           uchar i;
          Set_LCD_POS(p);            //p为液晶屏地址0x00
          for(i=0;i<25;i++)
          {
              Write_LCD_Data(s[i]);
              delay(1);     
          }
      }
      
      void Display_LCD_String2(uchar p,uchar *s)        //12 在LCD显示
      {
           uchar i;
          Set_LCD_POS(p);            //p为液晶屏地址0x00
          for(i=0;i<16;i++)
          {
              Write_LCD_Data(s[i]);
              delay(1);     
          }     
      }
      
      void Format_Date(uchar d,uchar *a)            // 13  
      {     
          a[1]=d+'0';     //0’的ASCII值为48      
      }
      
      void main()
      {
          Timer0Init(); //初始化T0
          Int0Init();      //初始化外部中断
          Init_LCD();      
           while(1)
           {
               keyscan();
                    
              Format_Date(b,LCD_DSY_BUFFER1+2);    // 
              Format_Date(s,LCD_DSY_BUFFER1+3);   // 
              Format_Date(g,LCD_DSY_BUFFER1+4);    //
                  
              Format_Date(PWMH_1,LCD_DSY_BUFFER1+10);
              Format_Date(PWMH_2,LCD_DSY_BUFFER1+11);
              Format_Date(PWMH_3,LCD_DSY_BUFFER1+12);
              Display_LCD_String(0x00,LCD_DSY_BUFFER1);
      
               if(e==0)
               {IN1=1;IN2=1;ENA=1;}
               if(e==1)
               {IN1=0;IN2=1;ENA=1;}
               if(e==2)
               {IN1=1;IN2=0;ENA=1;}         
           }
      }
    4. 难点是按键控制电机转速时使用PWM,将电机转速传递到液晶显示屏并显示
    5. 每一次接触新的硬件,就要查它的相关信息,才能顺利编程,真是很宝贵的自己学习经历
  • 相关阅读:
    用原生js实现ajax、jsonp
    $.ajax()方法详解
    用原生js实现ajax
    escape()、encodeURI()、encodeURIComponent()区别详解
    stylus项目知识点
    vue之给a标签赋值
    iOS—网络实用技术OC篇&网络爬虫-使用java语言抓取网络数据
    iOS开发——高级语法篇&继承、实现、依赖、关联、聚合、组合的联系与区别
    iOS-性能优化4
    iOS-性能优化3
  • 原文地址:https://www.cnblogs.com/youcansayIdontKnow/p/13365447.html
Copyright © 2011-2022 走看看