μCOSII 下的步进电机控制,高手帮忙看看

hero886666   2009-6-17 19:06 楼主
/*
电脑鼠设计任务安排
1,按键做开关
2,用LED8闪烁表示开,不亮表示关
3,AD采样设置电脑鼠快慢,调节步进电机的转速
4,用LED1~LED5表示电脑鼠速度,LED1亮最慢,5个都亮最快
5,p0.9的状态值做正反转标志
*/
#include "config.h"

#define   KEY       1<<20
#define   LED1           1<<16       // P2.16   
#define   LED2           1<<17           // P2.17   
#define   LED3      1<<18           // P2.18   
#define   LED4      1<<19                   // P2.19   
#define   LED5      1<<20       // P2.20   
#define   LED6      1<<21           // P2.21  
#define   LED7      1<<22           // P2.22  
#define   LED8      1<<23           // P2.23  

#define   MOTOA            1<<24       // P2.24  
#define   MOTOB                1<<25                // P2.25
#define   MOTOC         1<<26                // P2.26
#define   MOTOD                1<<27                // P2.27
#define   MOTOCON        (MOTOA | MOTOB | MOTOC |MOTOD)  // MOTO控制字

void DelayNS(uint32  dly);
void MOTO_Mode1(uint8 i);               // A-B-C-D


void         FireKey(void *pdata);                       
void         AdjustSpeed(void *pdata);                       
void         Running(void *pdata);
void         MouseRunning(void *pdata);
void         Reverse(void *pdata);

void        MouseInit(void);
void         PowerOn(void);
void         PowerOff(void);
void         ReadAD_SetSpeed(void);

volatile int   MouseRun=0,speed=0,direction=0;

OS_STK        TaskStk [5][128];

int main (void)
{
        OSInit();       
/*
点火开关 FireKey
速度调节 AdjustSpeed
运行状态 Running
方向控制 Reverse
驱动输出 MouseRunning
*/                                                                                                                                                                                                       
        OSTaskCreate(FireKey                ,(void *)0, &TaskStk[0][128 - 1], 2);
        OSTaskCreate(AdjustSpeed        ,(void *)0, &TaskStk[1][128 - 1], 3);
        OSTaskCreate(Running                ,(void *)0, &TaskStk[2][128 - 1], 4);
        OSTaskCreate(Reverse                ,(void *)0, &TaskStk[4][128 - 1], 5);
        OSTaskCreate(MouseRunning        ,(void *)0, &TaskStk[3][128 - 1], 6);/* 该任务无等待事件,必须是最低优先级 */
        OSStart();
        return 0;                                                                                                                       
}

void MouseInit(void)
{   int i;
    PINSEL1 = PINSEL1 & (~(1<<23)) | 1<<22;                // 设置P0.27连接到AIN0
   
    // 进行ADC模块设置,其中x<     ADCR = (1 << 0)                     |                // SEL = 1 ,选择通道0
           ((Fpclk / 1000000 - 1) << 8) |                 // CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
           (0 << 16)                    |                // BURST = 0 ,软件控制转换操作
           (0 << 17)                    |                 // CLKS = 0 ,使用11clock转换
           (1 << 21)                    |                 // PDN = 1 , 正常工作模式(非掉电转换模式)
           (0 << 22)                    |                 // TEST1:0 = 00 ,正常工作模式(非测试模式)
           (1 << 24)                    |                 // START = 1 ,直接启动ADC转换
           (0 << 27);                                                        // EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
    OSTimeDly(10);                                                               
    i = ADDR;                                                                        // 读取ADC结果,并清除DONE标志位

        IO2DIR = LED1 | LED2 | LED3 | LED4 | LED5 | LED8  | MOTOCON;      // 配置LED、MOTO控制I/O方向
        IO2SET = LED1 | LED2 | LED3 | LED4 | LED5 | LED8  ;          // 关闭所有的LED灯和MOTO输出
    IO2SET = MOTOCON;// 关闭所有的MOTO输出
       
        PowerOff();
}

void PowerOff(void)
{
    MouseRun = 0;
    IO2CLR = MOTOCON;
    IO2SET = LED1 | LED2 | LED3 | LED4 | LED5 | LED8;
}

void PowerOn(void)
{
    MouseRun = 1;

    ReadAD_SetSpeed();
}

void FireKey(void *pdata)
{
/*
点火开关 FireKey 任务
   检查是否按了点火开关,并做相应的处理。
*/
        TargetInit ();
        MouseInit();

        while (1)
        {
        if( (IO0PIN&KEY) == 0 )  {                               
            OSTimeDly(3);                                                
            if( (IO0PIN&KEY) == 0 ) {                       
                while( (IO0PIN&KEY) == 0 )               
                        OSTimeDly(2);                       //如果没有时间延时,系统将可能被键盘卡住
                if(MouseRun == 0)
                        PowerOn();       
                else
                        PowerOff();
            }                                                                       
        }                                                                               

                OSTimeDly(50);
    }
}

void ReadAD_SetSpeed(void)
{
    int  ADC_Data;
       
    ADCR = (ADCR&0x00FFFF00)|0x01|(1 << 24);        // 设置通道1,并进行第一次转换
    while( (ADDR&0x80000000)==0 );                    // 等待转换结束
    ADC_Data = (ADDR>>6)&0x3ff;                                // 读取ADC结果,10位有效数据d6~d15

    speed = ADC_Data /205;                            // ADC_Data的值是0~1023,speed值将是0~4,表示设置5级速度
}                               

void AdjustSpeed(void *pdata)
{
/* 速度调节 AdjustSpeed 任务
   通过检测AD转换信息,调节步进电机的换相延时参数,从而达到调节速度的作用。
*/
        while (1)
        {
            if(MouseRun == 1){
                        ReadAD_SetSpeed();       
            }
                   
                OSTimeDly(50);
    }
}

void Reverse(void *pdata)
{
/* 判断正反转任务
   通过检测p0.9端口的值决定正反转,注意切换方向时的处理。
*/
        int t;
        while (1)
        {
            if(MouseRun == 1){
                        if( IO0PIN&(1<<9) )
                                t = 1;
                        else
                                t = 0;
                        if (t!=direction){
                                MouseRun = 0;
                                OSTimeDly(200);
                                direction = t;
                                MouseRun = 1;
                        }
            }
                   
                OSTimeDly(50);
    }
}

void Running(void *pdata)
{
/*
运行状态 Running 任务
        显示运行状态(开关状态、速度大小)
        还可加入WDT内容,当系统异常后重新复位
*/       
        int count=0;                                                                                                                                                                                               
        while (1)
        {
                if(MouseRun==1){
                        if(count++<4)
                                IO2CLR = LED8;            // 开关状态显示
                else  
                        IO2SET = LED8;
                count %= 7;
        
                    switch(speed){                // 显示速度大小
                    case 0:
                        IO2CLR = LED1;           
                        IO2SET = LED2 | LED3 | LED4 | LED5;
                        break;
                    case 1:
                        IO2CLR = LED1 | LED2 ;           
                        IO2SET = LED3 | LED4 | LED5;
                        break;
                    case 2:
                        IO2CLR = LED1 | LED2 | LED3;           
                        IO2SET = LED4 | LED5;
                        break;
                    case 3:
                        IO2CLR = LED1 | LED2 | LED3 | LED4;           
                        IO2SET = LED5;
                        break;
                    case 4:
                        IO2CLR = LED1 | LED2 | LED3 | LED4 | LED5;           
                        break;
                    }
        }
            
        OSTimeDly(50);
        }
}

void MouseRunning(void *pdata)
{
        while(1){
            if(MouseRun == 1)
                        MOTO_Mode1(9-speed*2);
        }
}

void DelayNS(uint32  dly)
{   uint32  i;

    for(; dly>0; dly--)
    {
        for(i=0; i<5000; i++);
    }
}

/****************************************************************************
* 名    称:MOTO_Mode1()
* 功    能:单四拍程序
* 入口参数:uint8 i                延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void MOTO_Mode1(uint8 i)            // A-B-C-D
{
#define   MOTO_ON(PIN)   IO2SET = PIN   
#define   MOTO_OFF(PIN)         IO2CLR = PIN   
    if(direction)
    {
        /* A */
        MOTO_ON (MOTOA);
        DelayNS(i);
        MOTO_OFF(MOTOA);
        /* B */
        MOTO_ON (MOTOB);
        DelayNS(i);
        MOTO_OFF(MOTOB);
        /* C */
        MOTO_ON (MOTOC);
        DelayNS(i);
        MOTO_OFF(MOTOC);
        /* D */
        MOTO_ON (MOTOD);            
        DelayNS(i);
        MOTO_OFF(MOTOD);
    }
    else
    {
        /* D */
        MOTO_ON (MOTOD);            
        DelayNS(i);
        MOTO_OFF(MOTOD);
        /* C */
        MOTO_ON (MOTOC);
        DelayNS(i);
        MOTO_OFF(MOTOC);
        /* B */
        MOTO_ON (MOTOB);
        DelayNS(i);
        MOTO_OFF(MOTOB);
        /* A */
        MOTO_ON (MOTOA);
        DelayNS(i);
        MOTO_OFF(MOTOA);
    }
}

******************************************
以上是代码,我也不知道到底完不完整,使用的开发板是周立功的LPC 2200,其他的都没问题,就是在速度控制上,要用到AD转换,我看着好像没有相应的代码,请问这个代码是不是完整的,假如是不完整的,我该怎么加?谢谢大牛们。

回复评论 (7)

void ReadAD_SetSpeed(void);
应该还有个这个函数的实现, 从其名字应该能看出要实现什么功能来.

LPC2200带ZLG的步进电机驱动库吗? 能否共享一下?
点赞  2009-6-19 11:02
看错了 原来函数已经提供了, 光看觉得应该是完整的, 跑一下试试
点赞  2009-6-19 11:04
我用串口线连了PC的COM1和LPC2200的UART0 ,然后打开EASY ARM,可是EASY ARM什么反应都没有啊,跑了一下,按独立开关,步进电机能跑,就是速度不能调,也就是PC端不能控制速度,大牛帮帮忙啊,谢谢了~
点赞  2009-6-19 12:16
看这个程序, 速度调节是通过ADC读取"电脑鼠"的数值变化来调节步进电机的速度的, 所以从两个方面找原因: 1) "电脑鼠"是否正常运行了? 2) ADC采样程序是否正常执行了
点赞  2009-6-19 13:08
电脑鼠也就是步进电机可以确定正常,会转,ADC采样,说实话,我不是很懂,我以为是模数转换.我做过模数转换的实验,好象要对UATRT0进行初始化,还要写那些传数值的函数,但这个程序没有,不知道有没有关系.大牛留下QQ吧~
点赞  2009-6-19 14:26
I'm not 大牛, 有问题可以互相探讨下, 我的邮箱是:arnold-fly@hotmail.com
点赞  2009-6-20 16:39
解决了,其实代码已经完整,AD取样,不需要串口通讯,呵呵,小白了一次
点赞  2009-6-23 10:08
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复