⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 实验5.lst

📁 电机控制板程序修改.机电一体化的实际应用。可操作性强
💻 LST
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V7.20   实验5                                                                 05/27/2008 11:09:34 PAGE 1   


C51 COMPILER V7.20, COMPILATION OF MODULE 实验5
OBJECT MODULE PLACED IN 实验5.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE 实验5.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          
   2          //---------------------------------------------------------------------------------------
   3          //    步进电机、直流电机控制板程Version1.1。
   4          //    编写开始日期:2008年1月27日
   5          //    2008.1.30 改进版本1.1,改变测速方法:测霍尔元件若干次触发的时间
   6          //    程序中测速、步进电机精确调速、直流电机PWM精确控制等都合用一个T1计时器
   7          //    ,100us自动重装。
   8          //
   9          //    测速方法:用T0作计数器,每计4个脉冲(霍尔),就读一下T1中断次数计时器
  10          //    count_pulse_time,这个值就是转盘旋转一周所花的时间。由于采用100us为最小时间
  11          //    单位。速度测量具有一定的误差。
  12          //
  13          //    步进电机精确控制速度方法:主要是精确控制每步走的时间。同样利用T1的100us
  14          //    定时器。根据设定的转速,可求得每步所需要的时间间隔stepping_interval,
  15          //    100us计数器采用count_stepping_interval,当count_stepping_interval计到
  16          //    stepping_interval值时,步进电机走一步。
  17          //
  18          //    2008.4.5修改:四个磁钢改为一个磁钢,计数只记一次。
  19          //    2008.4.7修改:PWM用一个字节,从0-99,周期改为10ms
  20          //    2008.4.12修改:测速用INT1中断,计两次中断的时间,不用T0引脚
  21          //---------------------------------------------------------------------------------------
  22          
  23          //-------------------------------------变量定义------------------------------------------
  24          #include "string.h"
  25          #include "stdio.h"
  26          #include "reg52.h"
  27          sbit _A=0x90;             //步进电机4相控制引脚
  28          sbit _B=0x91;
  29          sbit _C=0x92;
  30          sbit _D=0x93;
  31          sbit DC_MOTOR=0x96;       //直流电机控制引脚
  32          sbit clk0=0x97;           //硬件环形分配器时钟控制引脚
  33          sbit DIR=0xb2;            //硬件环形分配器方向控制引脚
  34          
  35          unsigned char cmd;
  36                // cmd为PC机通过串口发给控制板的命令值,后续PC可能再发1-2字节数据或控制板返回2字节数据:n1,n2
  37                // cmd=0;    PC机无命令
  38                // cmd=0xc0; PC机要求软件环形分配步进电机,以转速(n1n2)运行,3字节命令。
  39                // cmd=0xc1; PC机要求硬件环形分配步进电机,以转速(n1n2)运行,3字节命令。
  40                // cmd=0xc2; PC机要求直流电机以PWM=n1运行,n1为占空比百分数1-100.
  41                // cmd=0xc3; PC机要求测电机转速,控制板返回转速(n1n2).
  42                // cmd=0xc4;
  43                // cmd=0xc5; PC机要求步进电机停止。
  44          
  45          
  46          unsigned char step_index=0; //步进电机软件分配表的索引值:0-7
  47          unsigned int speed=0;       //一秒内霍尔触发计数次数,除4乘60即为转速
  48          unsigned int count_4pulse_time=0;   //定时器T1中断次数计时器,计4个T0脉冲(转一圈)花了多少个100us.
  49          
  50          //----步进电机精确调速所需变量-----------
  51          unsigned int stepping_interval;      //步进电机在用T0中断精确定速时,每步时间间隔(即合计每步有多少个100us)
  52          unsigned int count_stepping_time;//定时器T1中断次数计数器,为计到stepping_interval值所设的计数器
  53          bit stepping_by_T0=0;                //用定时器T1调速步进电机标记:=1确认,=0取消
  54          
  55          //----直流电机PWM精确调速----------------
C51 COMPILER V7.20   实验5                                                                 05/27/2008 11:09:34 PAGE 2   

  56          unsigned int PWM=0;   //直流电机脉宽调制系数(1到99)10^-1,精确到1%
  57                                //例如PWM=21表示21%
  58          unsigned int count_DC_MOTOR_time;
  59                                //定时器T1中断次数计数器,为计到PWM值所设的计数器
  60          
  61          //----三种步进电机工作方式软件分配表-----
  62          unsigned char code step_tab0[8]={0x8,0x4,0x2,0x1,0x8,0x4,0x2,0x1};//4相单4拍
  63          unsigned char code step_tab1[8]={0xc,0x6,0x3,0x9,0xc,0x6,0x3,0x9};//4相双4拍
  64          unsigned char code step_tab2[8]={0x8,0xc,0x4,0x6,0x2,0x3,0x1,0x9};//4相8拍
  65          
  66          //-----LCD16液晶显示控制引脚定义---------
  67          sbit E=0xb4;
  68          sbit RS=0xb7;
  69          sbit RW=0xb6;
  70          sfr lcd_dat_port=0x80; //lcd数据口
  71          unsigned char lcd_buf[17];
  72          unsigned int  count_display; //液晶显示刷新计时
  73          //------按键端口定义---------------------
  74          sfr key_port=0xa0;     //P2口接键盘
  75          unsigned char code key_index[16]={0xdb,0xee,0xde,0xbe, //0,1,2,3
  76                                            0x7e,0xed,0xdd,0xbd, //4,5,6,7
  77                                            0x7d,0xeb,0xbb,0x7b, //8,9,上,下
  78                                            0xe7,0xd7,0xb7,0x77};//左,右,功能,确认
  79          //------菜单变量定义--------------------
  80          unsigned char menu_level=0; //菜单级别,0为没选择
  81          unsigned char choice=0;     //选择项,0为没选择;
  82                                      //       1为测速;
  83                                      //       2为设定步进电机转速;
  84                                      //       3为设定PWM值
  85          
  86          //-----------------------------变量定义结束------------------------------------------------
  87          
  88          /*-----------------   约延时100us  --------------------*/
  89          delay(unsigned char dy)
  90          {
  91   1       unsigned char ii;
  92   1       while(--dy)
  93   1         for(ii=0;ii<24;ii++) ;
  94   1       }
  95          /*----------------步进电机环形分配驱动程序---------------*/
  96          void step(bit direction)
  97          {unsigned char state;
  98   1       if (direction==1)
  99   1          {if (++step_index>7) step_index=0;}  //正转
 100   1       else
 101   1          {if (--step_index<0) step_index=7;}  //反转
 102   1      
 103   1       state=step_tab0[step_index];
 104   1      
 105   1      
 106   1       //根据开关状态决定使用硬件环形分配还是软件环形分配
 107   1       clk0=~clk0;         //使用硬件环形分配器情况
 108   1       _A=state & 0x8;     //实用软件环形分配器情况
 109   1       _B=state & 0x4;
 110   1       _C=state & 0x2;
 111   1       _D=state & 0x1;
 112   1      
 113   1      }
 114          /*----------------------步进电机软件延时的升速------------------------
 115          void accelerating()
 116           {
 117            unsigned char i;
C51 COMPILER V7.20   实验5                                                                 05/27/2008 11:09:34 PAGE 3   

 118            for(i=0;i<200;i++)
 119              {step(1);
 120               delay(240-i);
 121              }
 122            while(1)
 123              {step(1);
 124               delay(30);   //最高速约可到20
 125              }
 126           }*/
 127          /*------------------- 步进电机软件延时调速------------------
 128          void stepping(bit direction,unsigned char dy)
 129              //direction为方向=0或=1;  dy为每步延时时间从0-255
 130          {
 131           while(1)
 132              {step(direction);
 133               delay(dy);   //最高速约可到20
 134              }
 135          }*/
 136          //----------- T0、T1初始化设置,--------------------------
 137          //2008.4.12日,将T0中断改为INT1中断
 138          //功能:  设置T1定时100us,T0作计数(计霍尔脉冲数)测转速
 139          void set_T0T1()           //测步进电机转速时, T1作为定时器计100us时间
 140          {                         //T0计4个霍尔脉冲,察看需要的时间
 141   1       TMOD=0x22;       //T1:定时方式2,8位自动重装定时器;T0:计数方式1,8自动重装计数器.
 142   1       TH1=256-184;             //22.1184MHz晶振,184个机器周期约为100微秒(99.83us)
 143   1       TL1=256-184;
 144   1       TH0=256-56;                //T0用来计20us,
 145   1       TL0=256-56;
 146   1       IT1=1;                     //INT1为边沿触发上升沿方式
 147   1       EA=1;ET1=1;EX1=1;ET0=1;    //开定时器T0中断,改为INT1中断
 148   1      
 149   1       TR0=1;
 150   1      
 151   1       TR1=1;             //T0开始计数,T1开始计时
 152   1       count_4pulse_time=0;     //定时器T0累计数清零
 153   1      }
 154          //--------------步进电机定时器精确调速--------------------
 155          //功能:  根据指定速度计算每步以100us为单位的时间间隔
 156          void stepping_int(unsigned int stepping_speed_int) //speed_int是转速:r/min
 157          {
 158   1       float stepping_speed;        //为了减少计算带来的误差,先用浮点数进行计算
 159   1       stepping_speed=stepping_speed_int;
 160   1       stepping_speed=60/(stepping_speed*48);//得到每步秒数
 161   1       stepping_speed=stepping_speed*10000;  //得到每步百微秒数
 162   1       stepping_interval=stepping_speed;
 163   1       //set_T0T1();  //设置T1,T0: T1定时器作定时100us并控制步进电机,
 164   1                    //           T0作计数以测定直流电机或步进电机转速
 165   1       stepping_by_T0=1;
 166   1      }
 167          /*--------------------直流电机PWM调速程序1-------------------
 168          void pwm(unsigned char percent)//percent为占空比百分比从1到100
 169          { unsigned int i,j;
 170            j=10*percent;
 171            while(1)
 172             {
 173              DC_MOTOR=1;
 174              for(i=0;i<j;i++);
 175              DC_MOTOR=0;
 176              for(i=0;i<1000-j;i++);
 177             }
 178          }*/
 179          //------定时器T0计20us,用于产生PWM波---------------
C51 COMPILER V7.20   实验5                                                                 05/27/2008 11:09:34 PAGE 4   

 180          void Timer0() interrupt 1 using 2          //每个脉冲进入1次中断
 181          { 
 182   1       count_DC_MOTOR_time++;     //直流电机的PWM控制计时
 183   1       if (count_DC_MOTOR_time>PWM)
 184   1         {
 185   2          DC_MOTOR=0;
 186   2          if (count_DC_MOTOR_time>500) count_DC_MOTOR_time=0;
 187   2         }
 188   1        else  DC_MOTOR=1;
 189   1      }
 190          //---------用INT1中断计4个脉冲的中断程序,测量步进电机及测直流电机转速-------
 191          void INT1_measurement() interrupt 2           //每个脉冲进入1次中断
 192          { unsigned long long_speed;              //为减少计算误差,先用浮点数运算
 193   1        long_speed=count_4pulse_time;
 194   1        count_4pulse_time=0;                   //重新开始计数
 195   1        long_speed=600000L/long_speed;   //将计100us数的值转换为每分转的圈数
 196   1        speed=long_speed;
 197   1      }
 198          //-------定时器T1的100us中断程序,控制步进电机转速并为步进/直流电机测速计时----
 199          void Timer1() interrupt 3
 200          {
 201   1       count_4pulse_time++;       //为步进电机或直流电机测速计时,4个脉冲一个周期=n个100us
 202   1       count_stepping_time++;     //为控制步进电机转速计时,计每步是否达到预定速度要求的间隔时
 203   1       count_display++;
 204   1       if (count_4pulse_time>5000)
 205   1         {
 206   2          count_4pulse_time=0;
 207   2          speed=0;
 208   2         }
 209   1       if ((stepping_by_T0==1)&&(count_stepping_time>=stepping_interval))
 210   1         {                     //控制步进电机速度
 211   2          count_stepping_time=0;
 212   2          step(1);
 213   2         }
 214   1      }
 215          //---------------- 初始化串口 ---------------------------
 216          void ini_com()
 217          {
 218   1       SM0=0;SM1=1;REN=1;     //串口设定:方式1,即8位可变波特率,接收使能
 219   1       T2CON=0x34;            //用T2作为波特率发生器
 220   1       RCAP2H=0xff;TH2=0xff;
 221   1       RCAP2L=0xdc;TL2=0xdc;  //0xdc=波特率19200 0xfa=115200
 222   1      }
 223          //----------------- 串口接收一字节 ----------------------
 224          unsigned char receipt_byte()
 225          {
 226   1       unsigned int i=0;
 227   1       while(RI==0 && i<1000) i++;
 228   1       RI=0;
 229   1       return(SBUF);
 230   1      }
 231          //----------------- 串口发送一字节 ----------------------
 232          void transmit_byte(unsigned char send_byte)
 233          {
 234   1       ES=0;
 235   1       SBUF=send_byte;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -