單片機控制馬達驅動IC的應用


8位機最常見的應用單片機驅動馬達IC工作,馬達可支持無級調速(PWM),正轉,反轉,剎車。該應用簡單高效適應於各種應用,節約成本的不二選擇。

今天就跟大家分享曾經做過的馬達驅動IC的應用。

主電路由8位單片機提供控制信號,正轉,反轉,PWM調速,以及一個峰值電流400ma的馬達驅動IC構成。見電路圖。

P1

微信圖片_20200619104446

S1按一下正轉,按一下停機

S2按一下反轉,按一下停機

S3按一下加一級速度

S4按一下減一級速度

由於硬件不支持PWM,PWM使用IO模擬的方式產生。

/* =========================================================================
 * Project:       GPIO_Setting
 * File:          main.c
 * Description:   Set GPIO of PORTB
 *                  1. PORTB I/O state
 *                      - PB4 set input mode and enable pull-high resistor
 *                      - PB2 set output mode 
 *                      - PB1 set input mode and enable pull-low resistor
 *                      - PB0 set open-drain output mode                               
 *                                                          
 * Author:        JasonLee
 * Version:       V1.1                              
 * Date:          2018/09/07
 =========================================================================*/
#include <ny8.h>
#include "ny8_constant.h"
#include <stdint.h>
#define UPDATE_REG(x)    __asm__("MOVR _" #x ",F")

uint8_t pwmdcycle = 0;  //計數1000為一個周期
uint8_t pwmduty1 = 0;
uint8_t pwmduty2 = 0;
uint8_t pwmduty1s = 0;
uint8_t pwmduty2s = 0;
uint8_t spstate = 1;
uint8_t direction = 0; //stop 0  fw 1 bk 2

//uint8_t spdstate = 1;     //10檔
int16_t seccount = 0;    

int16_t tim1count = 0;
int16_t tim1scount = 0;
uint8_t sw1flg = 0;
int16_t tim2count = 0;
int16_t tim2scount = 0;
uint8_t sw2flg = 0;
uint16_t tim3count = 0;
uint8_t sw3flg = 0;
uint8_t tim4count = 0;
uint8_t sw4flg = 0;

void peripinit(void)
{
    //;Initial GPIO  
    //      ; PORTB I/O state
    //        ; PB0、PB1、PB2 set output mode and enable pull-high resister   
    BPHCON = (uint8_t) ~( C_PB5_PHB | C_PB4_PHB | C_PB2_PHB) ;        // Enable PB5、PB4、PB2 Pull-High Resistor,others disable
    IOSTB = (uint8_t) (C_PB5_Input | C_PB4_Input | C_PB3_Input | C_PB2_Input) ;    // Set PB5、PB3、PB3 PB2 to output mode,others set to input mode
    PORTB = 0x00;
    
    //;Initial time1
    //      ;instrclk i_hrc 4/4M  div = 1  計數8次溢出即可
    //      ;
    TMR1 = 0xC8;    //到0下溢出中斷,計數 //4M/200 = 20K/20 = 1K
    T1CR1 = C_TMR1_Reload | C_TMR1_En;   //自動重載
    T1CR2 = C_TMR1_ClkSrc_Inst | C_PS1_Dis ;  //指令時鍾
   
    //T1CR1 =( T1CR1 | C_TMR1_En ); //使能定時器
    INTE = INTE | C_INT_TMR1;    
}

//盡量減小中斷代碼時長
void isr_hw(void) __interrupt(0)
{
    if(INTFbits.T1IF)        //占空比為 cycle-duty
    {
        pwmdcycle++;       
         
        if( pwmdcycle == pwmduty1s )
        {
            if(direction == 1)  //FW
            {
                PORTBbits.PB0 = 1;
                PORTBbits.PB1 = 0;
            }
            else if(direction == 2)  //BK
            {
                PORTBbits.PB0 = 0;
                PORTBbits.PB1 = 1;
            }
            else if(direction == 0)    //停機
            {
                PORTBbits.PB0 = 0;
                PORTBbits.PB1 = 0;
            }
        }
        
        if(pwmdcycle == 20)
        {
            pwmduty1s = pwmduty1;  //必須保證周期結束才能更改此值
            pwmduty2s = pwmduty2;  //必須保證周期結束才能更改此值
            PORTBbits.PB1 = 0;
            PORTBbits.PB0 = 0;
            pwmdcycle = 0;
            
            seccount ++;
        }
        INTFbits.T1IF = 0;
    }
}

void main(void)
{
    DISI();
    peripinit();
    ENI();
      
    while(1)
    {
        //PB2 正轉 
        if(PORTBbits.PB4 == 0)
        {
            if(sw1flg == 0)
            {
                tim1count = seccount + 3000;
                tim1scount = seccount + 40;
                sw1flg = 1;
            }
            
            if((tim1count == seccount)&&(sw1flg == 2))
            {
                if(direction != 0)        //關機
                {
                    direction = 0;
                    
                }
                else 
                {
                    direction = 1;
                    spstate = 1;
                }
                sw1flg = 3;
            }
            if((seccount ==  tim1scount)&&(sw1flg == 1))
            {
                sw1flg = 2;
            }
        }
        else
        {
            if(sw1flg == 2 )                //短按有效
            {
                if(direction == 1)
                {
                    direction = 2;
                }
                else if(direction == 2)
                {
                    direction = 1;
                }
            }
            
            tim1count = 0;
            tim1scount = 0;
            sw1flg = 0;
        }
        //PB3 
        if(PORTBbits.PB3 == 0)
        {
            if(sw2flg == 0)
            {
                tim2count = seccount + 3000;    //延時3s
                tim2scount = seccount + 40 ;
                sw2flg = 1;
            }
            
            if((tim2count == seccount)&&(sw2flg == 2))
            {
                if(direction != 0)        //開機
                {
                    direction = 0;
                    
                }
                else 
                {
                    direction = 1;
                    spstate = 1;
                }
                sw2flg = 3;
            }
            
            if((seccount ==  tim2scount)&&(sw2flg == 1))
            {
                sw2flg = 2;
            }
        }
        else
        {
            if(sw2flg == 2 )
            {
                if(direction == 1)
                {
                    direction = 2;
                }
                else if(direction == 2)
                {
                    direction = 1;
                }
            }
            tim2count = 0;
            tim2scount = 0;
            sw2flg = 0;
        }
        //PB5 加速換擋
        if(PORTBbits.PB5 == 0)
        {
            if(sw3flg == 0)
            {
                tim3count = seccount + 30;
                sw3flg = 1;
            }
            
            if((tim3count == seccount)&&(sw3flg == 1))
            {
                spstate ++;
                if(spstate == 11)
                {
                    spstate = 1;
                }
                sw3flg = 2;
            }
        }
        else
        {
            tim3count = 0;
            sw3flg = 0;
        }
        
    
        //CLRWDT(); //pb4/pb5_加減速
        if(spstate == 1)
        {
            pwmduty1 = 10;
        }
        else if(spstate == 2)
        {
            pwmduty1 = 9;
        }
        else if(spstate == 3)
        {
            pwmduty1 = 8;
        }
        else if(spstate == 4)
        {
            pwmduty1 = 7;
        }
        else if(spstate == 5)
        {
            pwmduty1 = 6;
        }
        else if(spstate == 6)
        {
            pwmduty1 = 5;
        }
        else if(spstate == 7)
        {
            pwmduty1 = 4;
        }
        else if(spstate == 8)
        {
            pwmduty1 = 3;
        }
        else if(spstate == 9)
        {
            pwmduty1 = 2;
        }
        else if(spstate == 10)
        {
            pwmduty1 = 1;
        }
    }
}
有8位單片機需求聯系我:18665321219


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM