您的位置:首页技术文栏单片机C51
内容搜索:
阅读内容
背景:#EDF0F5 #FAFBE6 #FFF2E2 #FDE6E0 #F3FFE1 #DAFAF3 #EAEAEF 默认  

单片机控制的遥控步进电机

[日期:2008-08-19 ] [来源:东哥单片机学习网 www.picavr.com 作者:佚名] [字体: (投递新闻)

单片机控制的遥控步进电机

#include <AT89X51.h> 

#include<stdio.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int 
static unsigned int count;  //计数
unsigned int hour,minute,second,count;

sbit RS = P2^3;//Pin4
sbit RW = P2^2; //Pin5
sbit E  = P2^4;//Pin6

#define Data  P0    //数据端口
static int step_index;  //步进索引数,值为0-7
bit   k=0;                                      //红外解码判断标志位,为0则为有效信号,为1则为无效
  uchar n=0;                                      //用来控制外部中断
static bit turn;  //步进电机转动方向
static bit stop_flag;  //步进电机停止标志
static int speedlevel; //步进电机转速参数,数值越大速度越慢,最小值为1,速度最快
static int spcount;    //步进电机转速参数计数
void delay(unsigned int endcount);  //延时函数,延时为endcount*0.5毫秒
void gorun();          //步进电机控制步进函数
  uchar  data date[4];                        //date数组为存放地址原码,反码,数据原码,反码 
char data Test1[]="                  ";
#define   IR_RE P3_2
void DelayUs(unsigned char us)//delay us
{
 unsigned char uscnt;
 uscnt=us>>1;/* Crystal frequency in 12MHz*/
 while(--uscnt);
}
/******************************************************************/
void DelayMs(unsigned char ms)//delay Ms
{
 while(--ms)
   {
     DelayUs(250);
     DelayUs(250);
     DelayUs(250);
     DelayUs(250);
   }
}
void WriteCommand(unsigned char c)
{
 DelayMs(5);//short delay before operation
 E=0;
 RS=0;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
}
/****************************************************************/
void WriteData(unsigned char c)
{
 DelayMs(5);   //short delay before operation
 E=0;
 RS=1;
 RW=0;
 _nop_();
 E=1;
 Data=c;
 E=0;
 RS=0;
}
/*********************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
 unsigned char p;
 if (pos>=0x10)
    p=pos+0xb0; //是第二行则命令代码高4位为0xc
 else 
    p=pos+0x80; //是第二行则命令代码高4位为0x8
 WriteCommand (p);//write command
 WriteData (c);   //write data
}
/*************************************************************************/
void ShowString (unsigned char line,char *ptr)
{
 unsigned char l,i;
 l=line<<4;
 for (i=0;i<16;i++)
  ShowChar (l++,*(ptr+i));//循环显示16个字符
}
/*********************************************************************/
void InitLcd()
{
 DelayMs(15);
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x38); //display mode
 WriteCommand(0x06); //显示光标移动位置
 WriteCommand(0x0c); //显示开及光标设置
 WriteCommand(0x01); //显示清屏

}

/*--------------------------延时1ms程子程序-----------------------*/
delay1000()             
{
   uint i,j;
   for(i=0;i<1;i++)
     for(j=0;j<124;j++)
     ;
}

/*---------------------------延时882us子程序-----------------------*/

delay882()
{
   uint i,j;
   for(i=0;i<1;i++)                  
     for(j=0;j<109;j++)
     ;
}

/*--------------------------延时2400ms程子程序-----------------------*/

delay2400()                                          
{
   uint i,j;
   for(i=0;i<3;i++)          
     for(j=0;j<99;j++)
      ;
}
void IR_decode()
{
  uchar  i,j;
  while(IR_RE==0);
  delay2400();
  if(IR_RE==1)                               //延时2.4ms后如果是高电平则是新码
  {
     delay2400();                            //延时4.8ms避开4.5ms的高电平
     for(i=0;i<4;i++)
     {
       for(j=0;j<8;j++)
       {
           while(IR_RE==0);                       //等待地址码第1位高电平到来
           delay882();                         //延时882ms判断此时引脚电平
           ///CY=IR_RE;
           if(IR_RE==0)
           {       
              date[i]>>=1;
              date[i]=date[i]&0x7f;              
           }
           else if(IR_RE==1)
           {
              delay1000();
              date[i]>>=1;
              date[i]=date[i]|0x80;
           }
        }                                    //1位数据接收结束
     }                                       //32位二进制码接收结束
  
 } 
if (date[2]==0x16)
TR0 = 0;
else if(date[2]==0x14)
{TR0 = 1;
}
else if(date[2]==0x10)
{if (speedlevel>1)
    speedlevel--;
     else
    speedlevel=1;
}
else if(date[2]==0x1A)
 {if(speedlevel<5)
    speedlevel++;
     else
   speedlevel=5;
 }
 else if(date[2]==0x11)
 turn=~turn;

 

}
void int0() interrupt 0 using 1

   uint i;
   for(i=0;i<4;i++)
   { 
     delay1000();
     if(IR_RE==1){k=~k;}                   //刚开始为4.5ms的引导码,如果4ms内出现高电平则退出解码程序
   }

   if(k==0)
   { 
   EX0=0;                                //检测到有效信号关中断,防止干扰
   IR_decode();                          //如果接收到的是有效信号,则调用解码程序
                                //解码成功,调用显示程序,显示该键值
   }
  EX0=1;                                 //开外部中断,允许新的遥控按键
}
void main(void) 
{
  InitLcd();//
DelayMs(15);

sprintf(Test1,"STEP MOTOR SPEED");//the first line
ShowString(0,Test1);
ShowChar(0x19,’r’);
ShowChar(0x1a,’p’);
ShowChar(0x1b,’m’);
count = 0;
  step_index = 0;
  spcount = 0;
  stop_flag = 0;

  P1_0 = 0;
  P1_1 = 0;
  P1_2 = 0;
  P1_3 = 0;
  SP=0x60; 
  EA = 1;             //允许CPU中断 
  TMOD = 0x11; //设定时器0和1为16位模式1 
  ET0 = 1;           //定时器0中断允许 
  EX0=1;
  TH0 = 0xFE;
  TL0 = 0x0C;   //设定时每隔0.5ms中断一次
  TR0 = 1;         //开始计数
turn=0;

speedlevel=1;
 
while(1)
{
if(turn==0)
ShowChar(0x14,’+’);
else
ShowChar(0x14,’-’);
if(TR0 ==0)
{
 ShowChar(0x15,’0’);
ShowChar(0x16,’0’);
ShowChar(0x17,’0’);
ShowChar(0x18,’0’);

else
{
if(speedlevel==1)
 {
ShowChar(0x15,’3’);
ShowChar(0x16,’0’);
ShowChar(0x17,’0’);
ShowChar(0x18,’0’);
}
else if(speedlevel==2)
 {
ShowChar(0x15,’1’);
ShowChar(0x16,’5’);
ShowChar(0x17,’0’);
ShowChar(0x18,’0’);
 }
 else if(speedlevel==3)
 {
ShowChar(0x15,’1’);
ShowChar(0x16,’0’);
ShowChar(0x17,’0’);
ShowChar(0x18,’0’);
 }
 else if(speedlevel==4)
 {
ShowChar(0x15,’0’);
ShowChar(0x16,’7’);
ShowChar(0x17,’5’);
ShowChar(0x18,’0’);
 }
else if(speedlevel==5)
 {
 ShowChar(0x15,’0’);
ShowChar(0x16,’6’);
ShowChar(0x17,’0’);
ShowChar(0x18,’0’);
 }
}
}
}
//定时器0中断处理 
void timeint(void) interrupt 1 using 0

  TH0=0xFE;
  TL0=0x0C; //设定时每隔0.5ms中断一次

  count++;

  spcount--;
  if(spcount<=0)
  {
    spcount = speedlevel;
    gorun();
  }

}

void delay(unsigned int endcount)
{
  count=0;
  do{}while(count<endcount);
}

void gorun()
{
  if (stop_flag==1)
  {
    P1_0 = 0;
    P1_1 = 0;
    P1_2 = 0;
    P1_3 = 0;
    return;
  }

  switch(step_index)
  {
  case 0: //0
    P1_0 = 1;
    P1_1 = 0;
    P1_2 = 0;
    P1_3 = 0;
    break;
  case 1: //0、1
    P1_0 = 1;
    P1_1 = 1;
    P1_2 = 0;
    P1_3 = 0;
    break;
  case 2: //1
    P1_0 = 0;
    P1_1 = 1;
    P1_2 = 0;
    P1_3 = 0;
    break;
  case 3: //1、2
    P1_0 = 0;
    P1_1 = 1;
    P1_2 = 1;
    P1_3 = 0;
    break;
  case 4:  //2
    P1_0 = 0;
    P1_1 = 0;
    P1_2 = 1;
    P1_3 = 0;
    break;
  case 5: //2、3
    P1_0 = 0;
    P1_1 = 0;
    P1_2 = 1;
    P1_3 = 1;
    break;
  case 6: //3
    P1_0 = 0;
    P1_1 = 0;
    P1_2 = 0;
    P1_3 = 1;
    break;
  case 7: //3、0
    P1_0 = 1;
    P1_1 = 0;
    P1_2 = 0;
    P1_3 = 1;
  }

  if (turn==0)
  {
    step_index++;
    if (step_index>7)
      step_index=0;
  }
  else
  {
    step_index--;
    if (step_index<0)
      step_index=7;
  }
    
}


阅读:
录入:petta

推荐 】 【 打印
本文评论
      全部评论
发表评论


点评: 字数
姓名:
站长推荐