06:PWM与电机驱动【MSP430F5529】

电机型号:

工作方式:

原理图以及接线:

根据官方例程,主要代码为drive.c

#include 
/**  函数:PWM_Init()*  功能:初始化PWM*  P1.2*  P1.3*/
void PWM_Init(void)
{//TA0CTL = 0;     //清除以前的设置//TA0CTL = MC_1;  //定时器TA选择为增记数模式TA0CTL |= ID_0; //设置分频系数/*设置PWM通道一P1.2的输出模式*///TA0CCTL1 = OUTMOD_7;    //高电平PWM输出,占空比设置的是高电平的占空比TA0CCTL1 = OUTMOD_3;    //低电平PWM输出,占空比设置的是低电平的占空比P1DIR |= BIT2;          //P1.2为输出P1SEL |= BIT2;          //P1.2为输出/*设置PWM通道二P1.3的输出模式*/TA0CCTL2 = OUTMOD_7;    //高电平PWM输出P1DIR |= BIT3;          //P1.3为输出P1SEL |= BIT3;          //P1.3为输出TA0CTL = TASSEL_2 + MC_1;
}
/** 函数:TAPwmSetPermill(char Channel,unsigned int Percent)* 功能:设置每一路的参数* 入口参数:*          Channel:当前设置的通道数*          Percent:PWM有效时间的千分比(0~1000)*/
void TAPwmSetPermill(char Channel,unsigned int Percent)
{unsigned long int Period;unsigned int Duty;Period = TA0CCR0;Duty   = Period * Percent /1000;switch(Channel){case 1:TA0CCR1 = Duty;break;case 2:TA0CCR2 = Duty;break;case 3:TA0CCR3 = Duty;break;case 4:TA0CCR4 = Duty;break;}
}

drive.h

#ifndef __DRIVE_H
#define __DRIVE_H
#include 
#include void PWM_Init(void);
void TAPwmSetPermill(char Channel,unsigned int Percent);#endif  

main.c

/** 通道1:P1.2* 通道2:P1.3* 通道1输出PWM信号,200HZ,20%占空比*/#include  
#include int main(void)
{WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timerPWM_Init();TA0CCR0 = 5000;TAPwmSetPermill(1,400);     //1通道,40%的占空比TAPwmSetPermill(2,500);     //2通道,50%的占空比while(1);
}

(后面好像使用的时候会有什么冲突导致1或者2通道无法正常运行,不太记得了,可以到实物上实验一下子)

下面是智能送药小车使用PWM驱动电机相关代码与注释(在实物中,均能正常运行)

car.h

#ifndef __CAR_H
#define __CAR_H
#include void CAR_PWM_Init(void);
void CAR_RUN_Init(void);
void Capture_Init(void);
void CAR_Init(void);void TAPwmSetPermill(char Channel,unsigned int Percent);#endif

car.c

#include /******************************** PWM初始化* 前轮:  左——P1.2    右——P1.3* 后轮:  左——P1.4    右——P1.5*******************************/
void CAR_PWM_Init()
{TA0CTL |= ID_0;P1DIR |= BIT2 + BIT3 + BIT4 + BIT5;P1SEL |= BIT2 + BIT3 + BIT4 + BIT5;TA0CCTL1 = OUTMOD_7;TA0CCTL2 = OUTMOD_7;TA0CCTL3 = OUTMOD_7;TA0CCTL4 = OUTMOD_7;TA0CTL = TASSEL_2 + MC_1 + TACLR;TA0CCR0 = 1000;}
/** 电机控制端GPIO设置*           AIN1        AIN2*  左前                  P6.0        P6.1*  右前                  P6.2        P6.3*  左后                  P6.4        P7.0*  右后                  P6.5        P6.6*/
void CAR_RUN_Init(void)
{P6DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6;P6OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6);P7DIR |= BIT0;P7OUT &= ~BIT0;
}/**************************** 输入捕获:* 前轮:  左——P2.0    右——P2.1* 后轮:  左——P2.2    右——P3.6***************************/
//IO口存在冲突,待改进,改为两个PWM以及两个输入捕获端口,解决定时器不足问题
/*void Capture_Init(void)
{P2DIR &= ~(BIT4 + BIT5);P2SEL |=   BIT4 + BIT5;TA2CTL   = MC_2 + TASSEL_2 + ID_0 + TACLR;TA2CCTL1 = CM_1 + SCS + CAP + CCIE + CCIS_0;TA2CCTL2 = CM_1 + SCS + CAP + CCIE + CCIS_0;P3DIR &= ~(BIT5 + BIT6);P3SEL |=   BIT5 + BIT6;TB0CTL   = MC_2 + TASSEL_2 + ID_0 + TACLR;TB0CCTL1 = CM_1 + SCS + CAP + CCIE + CCIS_0;TB0CCTL2 = CM_1 + SCS + CAP + CCIE + CCIS_0;
}*/void CAR_Init(void)//初始化
{CAR_PWM_Init();CAR_RUN_Init();//Capture_Init();
}void TAPwmSetPermill(char Channel,unsigned int Percent)//选择通道,设置该通道输出的占空比,改变小车速度
{unsigned long int Period;unsigned int Duty;Period = TA0CCR0;Duty   = Period * Percent /1000;switch(Channel){case 1:TA0CCR1 = Duty;break;case 2:TA0CCR2 = Duty;break;case 3:TA0CCR3 = Duty;break;case 4:TA0CCR4 = Duty;break;}
}

main.c

/** 第四个版本* 红外循迹四轮小车,旋转式转向,可前进与倒退** 下一个版本改进计划:*          小车改为两个PWM驱动*          添加输入捕获,更新为闭环控制*          添加PID算法,运动控制更稳定*          修改定时器工作方式,精确计算时间,计算行驶路程*          添加OLED,实时显示参数*/#include  
#include 
#include void delay(int ms);
void RED_LED_Flag(void);void CAR_F_R(int mode_1);
void CAR_R_F(unsigned int a,unsigned int b,unsigned int c,unsigned int d);
void CAR_TEXT(void);int main(void)
{WDTCTL = WDTPW | WDTHOLD;//RED_LED_Init();//开启红外功能,初始化CAR_Init();while(1){//RED_LED_Flag();//开启小车全部功能CAR_TEXT();//测试小车功能}
}
void CAR_TEXT(void)
{CAR_R_F(200,200,200,200);CAR_F_R(0);}//延时函数——伪
void delay(int ms)
{int i,j;for( i = 0; i < ms; i ++){for( j = 0; j < 240; j ++);}
}void RED_LED_Flag(void) //小车功能实现
{if( (P4IN & BIT1) != 0 && (P4IN & BIT2) != 0)//都识别到黑线{CAR_F_R(4);     //停止CAR_R_F(000,000,000,000);}if( (P4IN & BIT1) == 0 && (P4IN & BIT2) == 0)//都未识别到黑线{CAR_F_R(0);     //前进CAR_R_F(200,200,200,200);}if( (P4IN & BIT1) != 0 && (P4IN & BIT2) == 0)//左识别到黑线,左转{CAR_F_R(6);     //旋转左转CAR_R_F(300,300,300,300);}if( (P4IN & BIT1) == 0 && (P4IN & BIT2) != 0)//右识别到黑线,右转{CAR_F_R(5);     //旋转右转CAR_R_F(300,300,300,300);}
}void CAR_F_R(int mode_1)//控制前后行动,控制IN1,IN2
{switch(mode_1){case 0://前行P6OUT &= ~(BIT0 + BIT2 + BIT4 + BIT5);      //0P6OUT |= BIT1 + BIT3 + BIT6;                //1P7OUT |= BIT0;break;case 1://后退P6OUT |= BIT0 + BIT2 + BIT4 + BIT5;     //1P6OUT &= ~(BIT1 + BIT3 + BIT6);         //0P7OUT &= ~BIT0;                         //0break;case 2://左转P6OUT &= ~BIT0;      //0,P6.0P6OUT &= ~BIT1;      //0P6OUT &= ~BIT2;      //0,P6.2P6OUT |= BIT3;       //1P6OUT &= ~BIT4;      //0,P6.4P7OUT &= ~BIT0;      //0P6OUT &= ~BIT5;      //0P6OUT |= BIT6;       //1break;case 3://右转P6OUT &= ~BIT0;      //0P6OUT |= BIT1;       //1P6OUT &= ~BIT2;      //0P6OUT &= ~BIT3;      //0P6OUT &= ~BIT4;      //0P7OUT |= BIT0;       //1P6OUT &= ~BIT5;      //0P6OUT &= ~BIT6;      //0break;case 4://停止P6OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6);      //0P7OUT &= ~BIT0;break;case 5://左旋转P6OUT &= ~BIT0;      //0P6OUT |=  BIT1;      //1P6OUT |=  BIT2;      //1P6OUT &= ~BIT3;      //0P6OUT &= ~BIT4;      //0P7OUT |=  BIT0;      //1P6OUT |=  BIT5;      //1P6OUT &= ~BIT6;      //0break;case 6://右旋转P6OUT |=  BIT0;      //1P6OUT &= ~BIT1;      //0P6OUT &= ~BIT2;      //0P6OUT |=  BIT3;      //1P6OUT |=  BIT4;      //1P7OUT &= ~BIT0;      //0P6OUT &= ~BIT5;      //0P6OUT |=  BIT6;      //1break;default:break;}
}void CAR_R_F(unsigned int a,unsigned int b,unsigned int c,unsigned int d)//控制速度
{TAPwmSetPermill(1,a);TAPwmSetPermill(2,b);TAPwmSetPermill(3,c);TAPwmSetPermill(4,d);
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部