打印

各位大侠:请教一个正反转的小程序。。。

[复制链接]
4964|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
WXJPCY888|  楼主 | 2012-12-13 16:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 WXJPCY888 于 2012-12-21 10:00 编辑

各位大侠向你们请教一个小程序。。。控制小电机正反转的问题。
按SW0控制小电机前行,按SW1时电机停止运行,形成互锁。
按SW1控制小电机后退,按SW0时电机停止运行,形成互锁。
改用状态机加扫描是可以了,但只能控制正转,反转控制不到,因我把两个端口分开进行状态机扫描了。可能要把两个端口放在一起进行状态机扫描才会达到效果。只是不知怎样区分扫描状态机分离两个端口状态。。。 :L   
本人新手,恳请各位大侠高手指点迷津。。。多谢!!!


#include <pic.h>
#include <timers.h>
#include "delay.h"
void init();
void scan();
void runinit();

//主程序
void main (void)
{  
        init();            //初始化
        while(1)
        {
                scan();                            //  按键扫描
    }
}
//PWM调速程序
void runinit()
{           
        PR2 = 0xff;            
        CCPR4L = 0xdf;         
        TRISDbits.TRISD2= 0;   
        T2CONbits.T2OUTPS3=0;   
        T2CONbits.T2OUTPS2=0;   
        T2CONbits.T2OUTPS1=0;   
        T2CONbits.T2OUTPS0=0;   
        T2CONbits.T2CKPS1=0;   
        T2CONbits.T2CKPS0=0;   
        T2CONbits.TMR2ON = 1;   
        CCP4CON = 0x0c;                    
}

void scan()
{
    if(SW0==0)         //正转按钮
          {
                delayms(1);            
                if(SW0==0)            
                        {   
                                PORTBbits.RB2=1;  //蜂鸣器响一声
                                delayms(150);   
                                PORTBbits.RB2=0;
                                delayms(50);                     
                                while(!SW0)
                                   {
                                                PORTBbits.RB4=0;  
                                                PORTBbits.RB5=1;  // 正转
                                                runinit();                // PWM调速
                                   }
                                   
                      if(SW0==0 && SW1==0‖SW1==0)             //停止
                        {
                           PORTBbits.RB4=0;
                               PORTBbits.RB5=0;
                           TRISDbits.TRISD2= 1;
                        }
                     }
                        
           }        
                if(SW1==0)         //反转按钮
                  {
                        delayms(1);
                        if(SW1==0)
                          {
                                PORTBbits.RB2=1;    //蜂鸣器响一声
                                delayms(150);
                            PORTBbits.RB2=0;
                                delayms(50);
                                while(!SW1)
                                    {
                                            PORTBbits.RB4=1;     //反转
                                            PORTBbits.RB5=0;
                                                runinit();  PWM调速
                                    }
                                 if(SW0==0 && SW1==0‖SW0==0)       //  停止
                                    {
                                        PORTBbits.RB4=0;
                                    PORTBbits.RB5=0;
                                TRISDbits.TRISD2= 1;   
                                    }
                           }
                    }   
}

void init()              
{            
        ADCON1=0x0f;                //初始化IO端口
        CMCON=0x07;
        TRISBbits.TRISB2= 0;
        TRISBbits.TRISB4= 0;
        TRISBbits.TRISB5= 0;
        TRISDbits.TRISD0= 1;
        TRISDbits.TRISD1= 1;
        PORTB= 0x00;
        PORTC= 0x00;
}

使用状态机扫描修改后的程序如下:

#include <p18cxx.h>
#include <timers.h>
#include "delay.h"
#pragma config DEBUG = ON, XINST=OFF, STVR = ON, WDT=OFF, CP0 = OFF, FCMEN = ON, IESO = OFF, FOSC2=ON, FOSC=HSPLL,  ETHLED=OFF
#define beep_dr   PORTBbits.RB2     /* beep_dr *///蜂鸣器输出
#define TRIS_beep_dr  DDRBbits.RB2
#define key_sr1  PORTDbits.RD0     /* key_sr1 *///正转
#define TRIS_key_sr1  DDRDbits.RD0
#define key_sr2   PORTDbits.RD1     /* key_sr2 *///反转
#define TRIS_key_sr2  DDRDbits.RD1
#define cnt_delay4us_cnt1   10
#define cnt_delay4us_cnt2   10   //按键去抖动延时阀值
#define cnt_voice_time   10  //蜂鸣器响的声音长短的延时阀值
#define delay4us_cnt1
#define delay4us_cnt2   
#define KEY_LONG_PERIOD 150
#define KEY_STATE_INIT 0
#define KEY_STATE_WOBBLE 1
#define KEY_STATE_PRESS 2
#define KEY_STATE_LONG 3
#define KEY_INIT 0
#define KEY_WOBBLE 1
#define KEY_PRESS 2
#define KEY_LONG 3
#define KEY_sr1_1 0x01
#define KEY_sr2_2 0x02
#define KEY_NULL 0x03
void init();
void GetKey();
void KeyGet();
void runinit();
void key_scan();                       //按键扫描函数,放在定时中断里
void key_service();
void PIC18F_High_isr(void);/*中断服务函数声明*/                        
unsigned char key_step=1; //扫描步骤变量
unsigned char key_lock1=0;   //按键自锁标志
unsigned char key_lock2=0;   //按键自锁标志
unsigned char  Count=0;       //延时计数器的变量
unsigned char key_sate;
unsigned char key_step;
unsigned char key_sec=0;  //哪个按键被触发
#pragma code high_vector_section=0x8
void high_vector (void)
{
_asm goto PIC18F_High_isr _endasm   //跳转到中断服务函数处*/
}
#pragma code
#pragma interrupt PIC18F_High_isr
void PIC18F_High_isr (void)
{
  if(INTCONbits.TMR0IE==1&&INTCONbits.TMR0IF==1)    //定时中断
        {
           INTCONbits.TMR0IF=0;   //定时中断标志位关闭
           T0CONbits.TMR0ON=0;    //定时中断开关关闭
           key_scan();                    //按键扫描函数
           TMR1H=0x0b;     
           TMR0L=0xec;          //重新设置定时时间间隔
           T0CONbits.TMR0ON=1;      //定时中断开关打开
        }
}
void main()
{
init();   
    INTCONbits.GIE=0;
    //IPR1bits.TMR1IP=1;
    T0CON=0x08;     //定时器中断配置
    //TMR1H=0x0b;
    TMR0L=0xec;
    INTCONbits.TMR0IF=0;  //定时中断标志位关闭
    INTCONbits.TMR0IE=1; //开中断
    T0CONbits.TMR0ON=1;  //打开定时
    INTCONbits.GIE=1;    //开总中断
    beep_dr=0;           //关蜂鸣器,
   while(1)   
   {
         key_service(); //按键服务
        //key_scan();
         GetKey(); 正转按键扫描函数
         KeyGet(); 反转按键扫描函数
   }
}
void key_scan()
{
    if(key_sr1 == 0)return KEY_sr1_1 ;
    if(key_sr2 == 0)return KEY_sr2_2 ;
    return KEY_NULL ;
  
}      
void GetKey()             //正转按键扫描函数
{
switch(key_step)                //按键服务状态切换
     {

        case KEY_STATE_INIT:         //状态0
      {
     if(key_sr1==1)    //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
       {
        
        key_lock1=0;
    key_step=KEY_STATE_WOBBLE;      
       }
     else
   {
      key_step = KEY_STATE_INIT ;
   }  
      
              }
             break;
         
  case KEY_STATE_WOBBLE :      //状态1
   {
         
    key_lock1=0;  //按键自锁标志清零
             Count=0; //按键去抖动延时计数器清零,

    key_step = KEY_STATE_PRESS ;//消抖
   }
   break;
  case KEY_STATE_PRESS :      //状态2
  {
   
    if(key_sr1==0)
   {
    key_lock1=1;
       ++Count;
   if(Count>cnt_delay4us_cnt1 )
     {
     Count = 0 ;
     key_lock1=1;  //自锁按键置位,避免一直触发
              key_sec=1;

     key_step = KEY_STATE_LONG ;
     }
   }  
    else
   {
     key_step = KEY_STATE_INIT ;
   }
  }
   break ;
        case KEY_STATE_LONG :      //状态3
        {
    if(key_sr1==0)
     {
      ++Count;
   if(Count >= KEY_LONG_PERIOD)
     {
    Count = 0 ;
    key_sec=3;          //长按键事件发生
    key_step = KEY_STATE_INIT ;
        }
     }
   else
   {
     key_step = KEY_STATE_PRESS ;
   }
  }
  break ;
        
     // default : break ;      
    }  
}   
void KeyGet()             //反转按键扫描函数
{
switch(key_sate)                //按键服务状态切换
     {

        case KEY_INIT:         //状态0
      {
     if(key_sr2==1)    //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
       {
    key_sate=KEY_WOBBLE;      
       }
     else
   {
      key_sate = KEY_INIT ;
   }  
      
         }
             break;
         
  case KEY_WOBBLE :      //状态1
   {
     key_lock2=0;  //按键自锁标志清零
              Count=0; //按键去抖动延时计数器清零,
     key_sate = KEY_PRESS ;//消抖
   }
   break;
  case KEY_PRESS :      //状态2
  {
    if(key_sr2==0)
   {
    key_lock2=1;
    ++Count;
   if(Count >= cnt_delay4us_cnt2)
     {
     Count = 0 ;
     key_lock1=2;  //自锁按键置位,避免一直触发
              key_sec=2;

     key_sate = KEY_LONG ;
     }
   }  
    else
   {
     key_sate = KEY_INIT ;
   }
  }
   break ;
        case KEY_LONG :      //状态3
        {
    if(key_sr2==0)
     {
      ++Count;
   if(Count >= KEY_LONG_PERIOD)
     {
    Count = 0 ;
    key_sec=4;          //长按键事件发生
    key_sate = KEY_INIT ;
        }
     }
   else
   {
     key_sate = KEY_PRESS ;
   }
  }
  break ;
        
         
    }  
}   
void  key_service()                //按键服务函数
{
   switch(key_sec)                //按键服务状态切换
     {
                case 1:// 1号键
        beep_dr=1;         //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);                                                                                 
        key_sec=0;     //相应完按键处理程序之后,把按键选择变量清零,避免一直触发      
        PORTBbits.RB4=0;
  PORTBbits.RB5=1; //电机正转置位
  runinit();       //PWM 运行
                break;        
                case 2:// 2号键
        beep_dr=1;       //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);
        key_sec=0; //相应完按键处理程序之后,把按键选择变量清零,避免一直触发         
        PORTBbits.RB4=1;  //电机反转置位
  PORTBbits.RB5=0;
  runinit();        //PWM 运行
                break;   
                case 3:// 3号键
                case 4://4号键
        beep_dr=1;         //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);   
        key_sec=0;//相应完按键处理程序之后,把按键选择变量清零,避免一直触发   
        PORTBbits.RB4=0;     //停止
  PORTBbits.RB5=0;     //停止
  TRISDbits.TRISD2= 1; //停止
          break;
          default : break ;
     }               
}
void init()          //初始化IO端口
{            
ADCON1=0x0f;               
CMCON=0x07;
TRISBbits.TRISB2= 0;
TRISBbits.TRISB4= 0;
TRISBbits.TRISB5= 0;
TRISDbits.TRISD0= 1;
TRISDbits.TRISD1= 1;
PORTB= 0x00;
}
void runinit()
{   
PR2 = 0xff;             //PWM的周期
CCPR4L = 0xdf;          //PWM的占空比,不能大于PR2
TRISDbits.TRISD2= 0;    //设定RC2/CCP1为输出
T2CONbits.T2OUTPS3=0;   //后分频比
T2CONbits.T2OUTPS2=0;   //后分频比
T2CONbits.T2OUTPS1=0;   //后分频比
T2CONbits.T2OUTPS0=0;   //后分频比
T2CONbits.T2CKPS1=0;    //预分频比
T2CONbits.T2CKPS0=0;    //预分频比
T2CONbits.TMR2ON = 1;   //打开定时器2
CCP4CON = 0x0c;         //CCP4选择PWM模式  
}


沙发
yewuyi| | 2012-12-14 12:20 | 只看该作者
1、将按键扫描和马达驱动代码分开
2、使用简单的状态机扫描按键和驱动马达

使用特权

评论回复
板凳
WXJPCY888|  楼主 | 2012-12-14 16:14 | 只看该作者
yewuyi 发表于 2012-12-14 12:20
1、将按键扫描和马达驱动代码分开
2、使用简单的状态机扫描按键和驱动马达
...

感谢版主提示与指导!
1、将按键扫描和马达驱动代码分开
2、使用简单的状态机扫描按键和驱动马达
您说的第一项理解。第二项不懂有点迷糊,请多指教!谢谢!!!

使用特权

评论回复
地板
optec| | 2012-12-15 09:59 | 只看该作者
可将将按键抽象为4个状态:
(1)    未按下,假定为S0
(2)    确认有键按下,假定为S1
(3)    键稳定按下状态,假定为S2
(4)    键释放状态,假定为S3。
假定键按下时端口电平为0,未按下时为1(或者相反)。通过状态机实现按键检测的过程如下:
首先,按键的初始态为S0,当检测到输入为1时,表示没有键按下,保持S0。当按键输入为0时,则有键按下,转入状态S1。
在S1状态时,如果输入的信号为1,则表示刚才的按键操作为干扰,则状态跳转到S0;如果输入信号为0,则表示确实有键按下,此时可以读取键状态,产生相应的按键标志或者将该事件存入消息队列。同时状态机切换到S2状态。
在S2状态,如果输入信号为1,则没有键按下,切换到S3;如果输入信号为0,则保持S2状态,并进行计数。如果计数值超过一定的门限值,则可以认为该按键为长按键事件或者键一直按下状态,如果未超过门限值,则认为是短按键事件,保持S2状态。
在S3状态,如果输入信号为高电平,则切换到S0.

使用特权

评论回复
5
WXJPCY888|  楼主 | 2012-12-17 09:34 | 只看该作者
optec 发表于 2012-12-15 09:59
可将将按键抽象为4个状态:
(1)    未按下,假定为S0
(2)    确认有键按下,假定为S1

:handshake感谢 optec 的指点!您说的:保持S2状态,并进行计数。如果计数值超过一定的门限值,则可以认为该按键为长按键事件或者键一直按下状态,如果未超过门限值,则认为是短按键事件,保持S2状态。
这一点不知怎样操作,可否给个参考程序看下好吗?多谢!!!:)

使用特权

评论回复
6
songxu125400| | 2012-12-19 09:09 | 只看该作者
把if(sw0==0&&sw1==0||sw0==0)放到while(!sw1)循环里并改成if(sw0==0)

使用特权

评论回复
7
WXJPCY888|  楼主 | 2012-12-20 12:08 | 只看该作者
songxu125400 发表于 2012-12-19 09:09
把if(sw0==0&&sw1==0||sw0==0)放到while(!sw1)循环里并改成if(sw0==0)

:handshake多谢回复!试过不行滴。。。:L

使用特权

评论回复
8
弓长月月鸟| | 2012-12-20 13:10 | 只看该作者
/*********************************************************************
*
*       ScanKey   timer=10ms  interval~20ms
*
**********************************************************************
*/
#define Keystate0   0   //未按下
#define Keystate1   1   //发现按下
#define Keystate2   2   //稳定按下
#define Keystate3   3   //释放

unsigned char Keystate = Keystate0;  //初始化按键状态为S0

unsigned char Keypress;         //按键输入  1表示为按下 0表示按下

void ScanKey()
{
  Keypress = PIO_Get(pin13);

  switch (Keystate){
   
    case Keystate0:
      if(Keypress == 0x00){
         Keystate = Keystate0;
      }
      else{
         Keystate = Keystate1;
      }
      break;
      
    case Keystate1:
      if(Keypress == 0x00){
         Keystate = Keystate2;
         WM_OnKey(GUI_KEY_ENTER, 1);
      }
      else{
         Keystate = Keystate0;
      }
      break;
      
    case Keystate2:
      if(Keypress == 0x00){
         Keystate = Keystate2;     //保持
         //可以计数,增加长按键响应门限
      }
      else{
         Keystate = Keystate3;
      }
      break;
      
    case Keystate3:
      if(!Keypress ){Keystate = Keystate0;}
      break;
      
    default:
      Keystate = Keystate0;
      break;
  
  }   
}

我从网上下的,按照optec的说法试了一下,可以的。你试一下

使用特权

评论回复
9
WXJPCY888|  楼主 | 2012-12-21 09:45 | 只看该作者
弓长月月鸟 发表于 2012-12-20 13:10
/*********************************************************************
*
*       ScanKey   timer=10m ...

:handshake非常感谢你 弓长月月鸟 !我试着用状态机加扫描是可以了,但只能控制正转,反转控制不到,我把两个端口分开进行状态机扫描了。可能要把两个端口放在一起进行状态机扫描才会达到效果。只是不知怎样区分扫描状态机分离两个端口状态。。。:L    还要请高手指点迷津。。。
#include <p18cxx.h>
#include <timers.h>
#include "delay.h"

#pragma config DEBUG = ON, XINST=OFF, STVR = ON, WDT=OFF, CP0 = OFF, FCMEN = ON, IESO = OFF, FOSC2=ON, FOSC=HSPLL,  ETHLED=OFF

#define beep_dr   PORTBbits.RB2                   /* beep_dr *///蜂鸣器输出
#define TRIS_beep_dr  DDRBbits.RB2
#define key_sr1  PORTDbits.RD0                   /* key_sr1 *///正转
#define TRIS_key_sr1  DDRDbits.RD0
#define key_sr2   PORTDbits.RD1                   /* key_sr2 *///反转
#define TRIS_key_sr2  DDRDbits.RD1

#define cnt_delay4us_cnt1   10
#define cnt_delay4us_cnt2   10   //按键去抖动延时阀值
#define cnt_voice_time   10  //蜂鸣器响的声音长短的延时阀值
#define delay4us_cnt1
#define delay4us_cnt2   
#define KEY_LONG_PERIOD 150

#define KEY_STATE_INIT 0
#define KEY_STATE_WOBBLE 1
#define KEY_STATE_PRESS 2
#define KEY_STATE_LONG 3

#define KEY_INIT 0
#define KEY_WOBBLE 1
#define KEY_PRESS 2
#define KEY_LONG 3
#define KEY_sr1_1 0x01
#define KEY_sr2_2 0x02
#define KEY_NULL 0x03
void init();
void GetKey();
void KeyGet();
void runinit();
void key_scan();                       //按键扫描函数,放在定时中断里
void key_service();

void PIC18F_High_isr(void);/*中断服务函数声明*/                        
unsigned char key_step=1; //扫描步骤变量
unsigned char key_lock1=0;   //按键自锁标志
unsigned char key_lock2=0;   //按键自锁标志

unsigned char  Count=0;       //延时计数器的变量
unsigned char key_sate;
unsigned char key_step;
unsigned char key_sec=0;  //哪个按键被触发

#pragma code high_vector_section=0x8
void high_vector (void)
{
        _asm goto PIC18F_High_isr _endasm   //跳转到中断服务函数处*/
}
#pragma code
#pragma interrupt PIC18F_High_isr

void PIC18F_High_isr (void)
{
         if(INTCONbits.TMR0IE==1&&INTCONbits.TMR0IF==1)    //定时中断
        {
           INTCONbits.TMR0IF=0;   //定时中断标志位关闭
           T0CONbits.TMR0ON=0;    //定时中断开关关闭
           key_scan();                    //按键扫描函数
           TMR1H=0x0b;     
           TMR0L=0xec;          //重新设置定时时间间隔
           T0CONbits.TMR0ON=1;      //定时中断开关打开
        }
}
void main()
{
        init();   
    INTCONbits.GIE=0;
    //IPR1bits.TMR1IP=1;
    T0CON=0x08;     //定时器中断配置
    //TMR1H=0x0b;
    TMR0L=0xec;
    INTCONbits.TMR0IF=0;  //定时中断标志位关闭
    INTCONbits.TMR0IE=1; //开中断
    T0CONbits.TMR0ON=1;  //打开定时
    INTCONbits.GIE=1;    //开总中断
           beep_dr=0;           //关蜂鸣器,

   while(1)   
   {
         key_service(); //按键服务
        //key_scan();
         GetKey(); 正转按键扫描函数
         KeyGet(); 反转按键扫描函数
   }

}
void key_scan()
{
    if(key_sr1 == 0)return KEY_sr1_1 ;
    if(key_sr2 == 0)return KEY_sr2_2 ;

    return KEY_NULL ;
         
}      

void GetKey()             //正转按键扫描函数
{
        switch(key_step)                //按键服务状态切换
     {

        case KEY_STATE_INIT:         //状态0
             {
                   if(key_sr1==1)    //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
                     {
                             
                             key_lock1=0;
                                key_step=KEY_STATE_WOBBLE;      
                     }
                   else
                        {
                           key_step = KEY_STATE_INIT ;
                        }  
                     
              }
             break;
         
                case KEY_STATE_WOBBLE :      //状态1
                        {
                        
                                key_lock1=0;  //按键自锁标志清零
                    Count=0; //按键去抖动延时计数器清零,
       
                                key_step = KEY_STATE_PRESS ;//消抖
                        }
                        break;
                case KEY_STATE_PRESS :      //状态2
                {
                       
                  if(key_sr1==0)
                        {
                                key_lock1=1;
                            ++Count;
                        if(Count>cnt_delay4us_cnt1 )
                          {
                                 Count = 0 ;
                                 key_lock1=1;  //自锁按键置位,避免一直触发
                     key_sec=1;
       
                                 key_step = KEY_STATE_LONG ;
                          }
                        }  
                  else
                        {
                          key_step = KEY_STATE_INIT ;
                        }
                }
                        break ;
        case KEY_STATE_LONG :      //状态3
        {
                  if(key_sr1==0)
                   {
                           ++Count;
                        if(Count >= KEY_LONG_PERIOD)
                          {
                                Count = 0 ;
                                key_sec=3;          //长按键事件发生
                                key_step = KEY_STATE_INIT ;
                      }
                   }
                        else
                        {
                          key_step = KEY_STATE_PRESS ;
                        }
                }
                break ;
        
                    default : break ;                    
    }  
}   
void KeyGet()             //反转按键扫描函数
{
        switch(key_sate)                //按键服务状态切换
     {

        case KEY_INIT:         //状态0
             {
                   if(key_sr2==1)    //IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
                     {
                                key_sate=KEY_WOBBLE;      
                     }
                   else
                        {
                           key_sate = KEY_INIT ;
                        }  
                     
         }
             break;
         
                case KEY_WOBBLE :      //状态1
                        {
                          key_lock2=0;  //按键自锁标志清零
              Count=0; //按键去抖动延时计数器清零,

                          key_sate = KEY_PRESS ;//消抖
                        }
                        break;
                case KEY_PRESS :      //状态2
                {
                  if(key_sr2==0)
                        {
                                key_lock2=1;
                                ++Count;
                        if(Count >= cnt_delay4us_cnt2)
                          {
                                 Count = 0 ;
                                 key_lock1=2;  //自锁按键置位,避免一直触发
                     key_sec=2;
       
                                 key_sate = KEY_LONG ;
                          }
                        }  
                  else
                        {
                          key_sate = KEY_INIT ;
                        }
                }
                        break ;
                                    default : break ;
        case KEY_LONG :      //状态3
        {
                  if(key_sr2==0)
                   {
                           ++Count;
                        if(Count >= KEY_LONG_PERIOD)
                          {
                                Count = 0 ;
                                key_sec=4;          //长按键事件发生
                                key_sate = KEY_INIT ;
                      }
                   }
                        else
                        {
                          key_sate = KEY_PRESS ;
                        }
                }
                break ;
        
                               
    }  
}   
void  key_service()                //按键服务函数
{
   switch(key_sec)                //按键服务状态切换
     {
                case 1:// 1号键
        beep_dr=1;         //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);                                                                                 
        key_sec=0;     //相应完按键处理程序之后,把按键选择变量清零,避免一直触发      
        PORTBbits.RB4=0;
                PORTBbits.RB5=1; //电机正转置位
                runinit();       //PWM 运行
                break;        
                case 2:// 2号键
        beep_dr=1;       //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);
        key_sec=0; //相应完按键处理程序之后,把按键选择变量清零,避免一直触发         
        PORTBbits.RB4=1;  //电机反转置位
                PORTBbits.RB5=0;
                runinit();        //PWM 运行
                break;          
                case 3:// 3号键
                case 4://4号键
        beep_dr=1;         //蜂鸣器响
        delayms(150);
        beep_dr=0;      //蜂鸣器停止
        delayms(50);   
        key_sec=0;//相应完按键处理程序之后,把按键选择变量清零,避免一直触发   
        PORTBbits.RB4=0;     //停止
                PORTBbits.RB5=0;     //停止
                TRISDbits.TRISD2= 1; //停止
                        break;
                        default : break ;
     }               
}

void init()          //初始化IO端口
{            
        ADCON1=0x0f;               
        CMCON=0x07;
        TRISBbits.TRISB2= 0;
        TRISBbits.TRISB4= 0;
        TRISBbits.TRISB5= 0;
        TRISDbits.TRISD0= 1;
        TRISDbits.TRISD1= 1;
        PORTB= 0x00;
}

void runinit()
{          
        PR2 = 0xff;             //PWM的周期
        CCPR4L = 0xdf;          //PWM的占空比,不能大于PR2
        TRISDbits.TRISD2= 0;    //设定RC2/CCP1为输出
        T2CONbits.T2OUTPS3=0;   //后分频比
        T2CONbits.T2OUTPS2=0;   //后分频比
        T2CONbits.T2OUTPS1=0;   //后分频比
        T2CONbits.T2OUTPS0=0;   //后分频比
        T2CONbits.T2CKPS1=0;    //预分频比
        T2CONbits.T2CKPS0=0;    //预分频比
        T2CONbits.TMR2ON = 1;   //打开定时器2
        CCP4CON = 0x0c;         //CCP4选择PWM模式               
}

使用特权

评论回复
10
弓长月月鸟| | 2012-12-21 10:34 | 只看该作者
你用SW0和SW1控制两个电机还是一个电机?这个问题有点弱啊。

使用特权

评论回复
11
WXJPCY888|  楼主 | 2012-12-21 10:41 | 只看该作者
控制一个小电机

使用特权

评论回复
12
弓长月月鸟| | 2012-12-21 10:46 | 只看该作者
按SW0控制小电机前行,按SW1时电机停止运行,形成互锁。
按SW1控制小电机后退,按SW0时电机停止运行,形成互锁。
我个人,感觉好像有点冲突。说下我的认识。按下SW0,电机前行,再按下SW1,电机停止。下面的电机又是后退运行。是不是矛盾了?
目前我的理解是这样的。

使用特权

评论回复
13
WXJPCY888|  楼主 | 2012-12-21 11:50 | 只看该作者
本帖最后由 WXJPCY888 于 2012-12-21 11:53 编辑
弓长月月鸟 发表于 2012-12-21 10:46
按SW0控制小电机前行,按SW1时电机停止运行,形成互锁。
按SW1控制小电机后退,按SW0时电机停止运行,形成 ...


没有冲突。一个键实现两个功能:点按启动,长按停止。按下SW0,电机前行,再长按下SW0,电机停止。点按下SW1,后退运行,再长按下SW1,电机停止。实现正反转动作。

使用特权

评论回复
14
弓长月月鸟| | 2012-12-21 12:30 | 只看该作者
这样操作跟互锁好像没有关系了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

134

帖子

0

粉丝