8位机最常见的应用单片机驱动马达IC工作,马达可支持无级调速(PWM),正转,反转,刹车。该应用简单高效适应于各种应用,节约成本的不二选择。
今天就跟大家分享曾经做过的马达驱动IC的应用。
主电路由8位单片机提供控制信号,正转,反转,PWM调速,以及一个峰值电流400ma的马达驱动IC构成。见电路图。
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#include "ny8_constant.h" #include #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 disableIOSTB = (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 modePORTB = 0x00;//;Initial time1// ;instrclk i_hrc 4/4M div = 1 计数8次溢出即可// ;TMR1 = 0xC8; //到0下溢出中断,计数 //4M/200 = 20K/20 = 1KT1CR1 = 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; //延时3stim2scount = 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;}} }