微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 关于单片机中步进电机的程序控制问题求解

关于单片机中步进电机的程序控制问题求解

时间:10-02 整理:3721RD 点击:

if(pt==2)  
{     
pt=0;         
if(flag==0&&moto==1)         
P2=(P2&0x0f)|CONTROL[counts];   
if(flag==0&&moto==0)   
P2=(P2&0x0f)|codes2[counts];   
counts++;   
if(counts==8)counts=0;                                 
}  
}
这一段不怎么懂,哪位大神懂得求帮忙
全部程序如下
#include <AT89X51.H>
#define DB0_DB7  P0                              //液晶
#define busy 0x80                                   //*128*//
#define SCANPORT P1                          //键盘
sbit E=P2^2;                                       //*目标值*//
sbit RW=P2^1;
sbit RS=P2^0;
unsigned char uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F};         //列线扫描电压分为第1  2
34根列线 //
unsigned char key_ctt[4]={0};
unsigned int time_sq[4]={0};              //连续测得的三点的时间 //
unsigned char speed_bcd[4]={0};
unsigned char speed_sc[2]={0};
unsigned int speed_ck[4]={0};
unsigned int di_xx[2]={0};
unsigned char yy=0,temp;
unsigned int ct=0,ttb=0,xx=0,tt3=0,speedct=0,speed=0,speeded=10,cott=0;
typedef unsigned char uchar;
uchar code lcd3[]={"0123456789abcdef"};               
uchar code lcdnow[]={"NOW:000"};
uchar code lcdset[]={"SET:000"};
unsigned char CONTROL[8]={0x38,0x18,0x98,0x88,0xC8,0x48,0x68,0x28};
unsigned char codes1[8]={0xb8,0x98,0xd8,0xc8,0xe8,0x68,0x78,0x38};         
///9,18,36,45,54,63,72,81度 顺时针*/
unsigned char codes2[8]={0x38,0x78,0x68,0xe8,0xc8,0xd8,0x98,0xb8};        
//9,18,36,45,54,63,72,81度 逆时针
unsigned char counts,pt; bit flag=1;                                                      
  //    度数正/反转速度控制
bit a_ac=0;                                                                              
            //比较系统标志
unsigned char uc_KeyTemp=0;                                                               
       //按键键码暂存。
unsigned char uc_ClickCount=0;                                                            

unsigned char ucCount;                                                                    
        //按键次数
void vKeyProcess(unsigned char ucKeyCode);
void bleep();                                                                             
         //报警 bit bleept=0;//报警标准
bit moto=0;                                                                              
       //电机标志位
void ac();                                                                                
          ///电机速度比较
void akey();                                                                              
        //功能处理A
bit a_key=0;
bit b_key=0;
void getspeed();                                                                          
     //速度检测
void stdisplay();                                                                        
     //显示
void Delay(unsigned int t);                                                              
//延时
void delay_50ms(unsigned int t);
void SendCommand(unsigned char ch);                                                      
                                            //发送命令
void vWriteData(unsigned char ch);                                                        
                                              //发送数据
void InitLcd();                                                                           
                                                             //初始化
void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata);                     
                          //按指定位置显示一个字符
void DisplayListChar(unsigned char x, unsigned char y, unsigned char *DData);            
                                                //按指定位置显示一串字符
void Delay(unsigned int t)   
void SendCommand(unsigned char ch)                                                        
              //发送命令
{   
RS=0;                                                                                    
                 //RS,RW都为低电平时才能写入指令
RW=0;     
DB0_DB7=ch;                                                                              
             //液晶赋值
E=1;                        
Delay(1);     
E=0;     
Delay(5);                                                                                 
              //delay 40us
}
void vWriteData(unsigned char ch)                                                      
//发送数据
{  
RS=1;          //向lcd写入数据
RW=0;     
DB0_DB7=ch;     
E=1;     
Delay(1);     
E=0;     
Delay(5);
delay 40us
}
void InitLcd()                                                                           
            //初始化
{   
SendCommand(0x38);  
Delay(1);  
SendCommand(0x08);                                                                        
//设置工作方式  Delay(1);  
SendCommand(0x01);                                                                        
//显示状态设置  
Delay(1);  
SendCommand(0x06);                                                                        
//清屏  
Delay(200);  
SendCommand(0x0c);                                                                       
//输入方式设置 }  
void DisplayOneChar(unsigned char x,unsigned y,unsigned char ddata)   //按指定位置显示一
个字符
{  
y &= 0x1;  x &= 0xF;                                                                     
                    //限制X不能大于15Y不能大于1  
if (y) x |= 0x40;                                                                        
    //当要显示第二行时地址码+0x40;  
x |= 0x80;                                                                                
       // 算出指令码  
SendCommand(x);   
vWriteData(ddata);  
}  
void DisplayListChar(unsigned char x, unsigned char y, unsigned char  *DData) //按指定开
始位置显示字符串
{  
unsigned char ListLength;  
ListLength = 0;  
y &= 0x1;  
x &= 0xF;                                                                                 
//限制X不能大于15Y不能大于1  
while (DData[ListLength]>0x20)                                                     //若到
达字串尾则退出   
{      
if (x <= 0xF)                                       
{        
DisplayOneChar(x, y, DData[ListLength]);                             //显示单个字符      

ListLength++;        
x++;      
}  
  }
}
void vShowOneChar(unsigned char ucChar)
{  
switch(ucChar)   
{   
case '0': vWriteData(0x30);break;   
case '1': vWriteData(0x31);break;   
case '2': vWriteData(0x32);break;   
case '3': vWriteData(0x33);break;
case '4': vWriteData(0x34);break;   
case '5': vWriteData(0x35);break;   
case '6': vWriteData(0x36);break;   
case '7': vWriteData(0x37);break;   
case '8': vWriteData(0x38);break;   
case '9': vWriteData(0x39);break;   
case 'a': vWriteData(0x61);break;   
case 'b': vWriteData(0x62);break;   
case 'c': vWriteData(0x63);break;   
case 'd': vWriteData(0x64);break;   
case 'e': vWriteData(0x65);break;   
case 'f': vWriteData(0x66);break;   
default: break;  
}
}   unsigned char ucKeyScan()
{  
unsigned char ucTemp=0;                                                                  
//扫描状态暂存。
unsigned char ucRow=0,ucLine=0;                                                           
              //行号列号。   
for(ucLine=0;ucLine<4;ucLine++)                                       //列扫描   
{   
SCANPORT=uca_LineScan[ucLine];                                                //输出扫描
电位。   
ucTemp=SCANPORT&0x0F;                                                       //输入扫描电
位并屏蔽高4位。   
if(ucTemp!=0x0F)        
{               
switch(ucTemp)      
{      
case 0x0E: ucRow=10;break;                                                        //如果
有则判断行号。      
case 0x0D: ucRow=20;break;      
case 0x0B: ucRow=30;break;      
case 0x07: ucRow=40;break;      
default:   ucRow=50;break;      }     
break;     
}  
}  
SCANPORT=0x0F;                                                                       //恢
复P2口  
return ucRow+ucLine+1;                   //返回哪个按键按下。如返回12,则意思是2行1列的按
键按下
}   
void vKeyProcess(unsigned char ucKeyCode)
{
SendCommand(0xC4+uc_ClickCount);
if(a_key==1)
{   
switch(ucKeyCode)  
{         
case 41:vShowOneChar('7');temp=7;break;           //'7'   
case 42:vShowOneChar('8');temp=8;break;         //'8'   
case 43:vShowOneChar('9');temp=9;break;         //'9'   
case 31:vShowOneChar('4');temp=4;break;         //'4'   
case 32:vShowOneChar('5');temp=5;break;          //'5'   
case 33:vShowOneChar('6');temp=6;break;          //'6'   
case 21:vShowOneChar('1');temp=1;break;          //'1'   
case 22:vShowOneChar('2');temp=2;break;          //'2'   
case 23:vShowOneChar('3');temp=3;break;          //'3'   
case 12:vShowOneChar('0');temp=0;break;        //'0'
}
SendCommand(0xc4+uc_ClickCount);
SendCommand(0x0f);
}
switch(ucKeyCode)   
{   
case 44:/*vShowOneChar('c');*/temp=12;break;          //'/'   
case 34:/*vShowOneChar('d')*/temp=13;break;          //'*'   
case 24:/*vShowOneChar('e')*/temp=14;break;          //'-'   
case 14:/*vShowOneChar('f')*/temp=15;break;          //'+'            
case 13:/*vShowOneChar('b');*/temp=11;break;         //'='   
case 11:/*vShowOneChar('a');*/temp=10;break;          //'ON/C'   
default:break;   
}  
if(temp==11)                                 //判断按键与上一次所按的键是否相同。   
{   
delay_50ms(10);   
if(uc_ClickCount<255)                  //同一个按连续按下的次数:1~255。   
{
uc_ClickCount++;   
SendCommand(0xc3+uc_ClickCount);   
SendCommand(0x0f);
}   
if(uc_ClickCount==3)   
uc_ClickCount=0;   
SendCommand(0xc4+uc_ClickCount);   
SendCommand(0x0f);   
}
if(temp<=9)
{switch(uc_ClickCount)  
{
case 0:key_ctt[0]=temp;break;  
case 1:key_ctt[1]=temp;break;  
case 2:key_ctt[2]=temp;break;  
default:break;  
}
}
}
void int_timer0(void)
{
TMOD=0X10;
TMOD=0X01;
TH0=0X3C;
TL0=0XB0;
TH1=0X3C;
TL1=0XB0;
ET1=1;
TR1=1;
ET0=1;
TR0=1;
EA=1;
IT1=1;
EX1=1;
}
void Timer1() interrupt 3     //定时器1中断
{     
TH1=0X3c;     
TL1=0Xb0;  
pt++;                                //控制速度   
if(pt==2)  
{     
pt=0;         
if(flag==0&&moto==1)         
P2=(P2&0x0f)|CONTROL[counts];   
if(flag==0&&moto==0)   
P2=(P2&0x0f)|codes2[counts];   
counts++;   
if(counts==8)counts=0;                                    //角度重置  
}  
}
void Timer0()
interrupt 1
{      
TH0=0X3c;   
TL0=0Xb0;
yy++;
if(yy==2)
{  ct++; tt3+
yy=0;
if(ct==600)                                   //60秒定时
{   
ct=0;   
xx=0;   
}
if(tt3==20)
{
tt3=0;
di_xx[1]=di_xx[0];
di_xx[0]=xx;
if((di_xx[0]==di_xx[1])&&a_ac==1)
{bleept=1;flag=1;
}
}
}
}  
void Int1() interrupt 2
{  
static cott=0;
cott++;
if(cott==2)
{   xx++;   
time_sq[2]=time_sq[1];    //把当前检测到液滴的时间保存起来   
time_sq[1]=time_sq[0];  
time_sq[0]=ct;     
if(a_key==0)   
{   
DisplayOneChar(10,0,lcd3[speed/100]);   
DisplayOneChar(11,0,lcd3[speed%100/10]);   
DisplayOneChar(12,0,lcd3[speed%10]);   
DisplayOneChar(10,1,lcd3[xx/100]);   
DisplayOneChar(11,1,lcd3[xx%100/10]);   
DisplayOneChar(12,1,lcd3[xx%10]);   
SendCommand(0xC4+uc_ClickCount);
}   
getspeed();  
cott=0;
}
}
void stdisplay()
{
DisplayListChar(0,0,lcdnow);
DisplayListChar(0,1,lcdset);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x46);
DisplayListChar(8,0,"S:");
DisplayListChar(8,1,"T:");
}
void main(void)  
{
delay_50ms(1);
int_timer0();
InitLcd();
P2_3=1;
SCANPORT=0x0F;
stdisplay();
while(1)
{
bleep();
if(SCANPORT!=0x0F)  
{   
for(ucCount=0;ucCount<200;ucCount++);     
if(SCANPORT!=0x0F)   
vKeyProcess(ucKeyScan());   
};
switch(temp)  
{  
case 13:bleept=0;break;//D  
case 14:a_ac=1;b_key=1;
if(b_key==1)
{
DisplayOneChar(15,1,0x4f);
b_key=0;
};
SendCommand(0xC4+uc_ClickCount);
break;
case 15:if(a_key==1)
{
speedcd=key_ctt[0]*100+key_ctt[1]*10+key_ctt[2];
uc_ClickCount=0;};break;
case 10:a_key=1;akey();break;
case 12:a_key=0;akey();break;  
default:break;
  }
}
}   
void ac()
{
if(speedct>=(speedcd+5))
{moto=0;flag=0;}
else if(speedct<=(speedcd-5))
{moto=1;flag=0;} else  flag=1; }
void bleep()
{
if(a_ac==1)
{
if(bleept==1)
P2_3=0;
if(bleept==0) P2_3=1;
}
}
void akey()
{
if(a_key==1)
{
SendCommand(0x0c);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x4e);
On SendCommand(0xc4);
SendCommand(0x0f);
}
if(a_key==0)
{
SendCommand(0x0c);
DisplayOneChar(14,0,0x4f);
DisplayOneChar(15,0,0x46);
}
}
void getspeed()
{   
if(a_ac==1)   
{
ac();
};   
speed=1200/(time_sq[0]-time_sq[2]);   
speed_ck[3]=speed_ck[2];   
speed_ck[2]=speed_ck[1];    //把当前检测到液滴的速度保存起来   
speed_ck[1]=speed_ck[0];   
speed_ck[0]=speed;
if((speed_ck[0]!=speed_ck[1]))
{  
speed_sc[1]=speed_sc[0];  
speed_sc[0]=speed_ck[0];  
speedct=(speed_sc[0]+speed_sc[1])/2;
}
else
{
if((speed_ck[0]==speed_ck[2])&&(speed_ck[1]==speed_ck[3])) speedct=(speed_ck[0]+speed_ck
[1])/2;      
if((speed_ck[0]==speed_ck[1])||(speed_ck[0]==speed_ck[2]))
speedct=(speed_ck[1]+speed_ck[2])/2;  
if((speed_ck[0]!=speed_ck[1])&&(speed_ck[0]!=speed_ck[2])&&(speed_ck[1]==speed_ck[2]))
speedct=(speed_ck[0]+speed_ck[1])/2;  
if((speed_ck[0]!=speed_ck[1])&&(speed_ck[0]!=speed_ck[2])&&(speed_ck[1]!=speed_ck[2]))
speedct=(speed_ck[0]+speed_ck[1]+speed_ck[2]+speed_ck[4])/4;}  
speed_bcd[2]=speed/100;                                          //将speed值分为三位数
保存在数组中用来显示
speed_bcd[1]=speed%100/10;
speed_bcd[0]=speed%10;  
if(a_key==0)   
{   
DisplayOneChar(4,0,lcd3[speedct/100]);   
DisplayOneChar(5,0,lcd3[speedct%100/10]);   
DisplayOneChar(6,0,lcd3[speedct%10]);   
DisplayOneChar(4,1,lcd3[speedcd/100]);   
DisplayOneChar(5,1,lcd3[speedcd%100/10]);   
DisplayOneChar(6,1,lcd3[speedcd%10]);   
SendCommand(0xC4+uc_ClickCount);  
}  
}

把所有程序搞上,这样一段怎么看啊?

看楼上

说你的问题是什么?

亲,你的写全啊,部分的程序不好说啊。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top