06:PWM与电机驱动【MSP430F5529】 您所在的位置:网站首页 l298n电机驱动模块使用方法pwm 06:PWM与电机驱动【MSP430F5529】

06:PWM与电机驱动【MSP430F5529】

2024-06-18 01:31| 来源: 网络整理| 查看: 265

目录

电机型号

驱动方式

工作方式

代码

drive.c

drive.h

main.c

智能送药小车

car.h

car.c

main.c

电机型号

        步进电机:图解: 步进电机原理与驱动方式 - 知乎 (zhihu.com)

驱动方式

        L298N:L298N 电机驱动板 - 详细介绍 - 知乎 (zhihu.com)

工作方式

        PWM驱动,控制电机运动的速度、力矩

代码 drive.c

参考官方的代码,输出程序: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 timer PWM_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); //0 P6OUT |= BIT1 + BIT3 + BIT6; //1 P7OUT |= BIT0; break; case 1://后退 P6OUT |= BIT0 + BIT2 + BIT4 + BIT5; //1 P6OUT &= ~(BIT1 + BIT3 + BIT6); //0 P7OUT &= ~BIT0; //0 break; case 2://左转 P6OUT &= ~BIT0; //0,P6.0 P6OUT &= ~BIT1; //0 P6OUT &= ~BIT2; //0,P6.2 P6OUT |= BIT3; //1 P6OUT &= ~BIT4; //0,P6.4 P7OUT &= ~BIT0; //0 P6OUT &= ~BIT5; //0 P6OUT |= BIT6; //1 break; case 3://右转 P6OUT &= ~BIT0; //0 P6OUT |= BIT1; //1 P6OUT &= ~BIT2; //0 P6OUT &= ~BIT3; //0 P6OUT &= ~BIT4; //0 P7OUT |= BIT0; //1 P6OUT &= ~BIT5; //0 P6OUT &= ~BIT6; //0 break; case 4://停止 P6OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6); //0 P7OUT &= ~BIT0; break; case 5://左旋转 P6OUT &= ~BIT0; //0 P6OUT |= BIT1; //1 P6OUT |= BIT2; //1 P6OUT &= ~BIT3; //0 P6OUT &= ~BIT4; //0 P7OUT |= BIT0; //1 P6OUT |= BIT5; //1 P6OUT &= ~BIT6; //0 break; case 6://右旋转 P6OUT |= BIT0; //1 P6OUT &= ~BIT1; //0 P6OUT &= ~BIT2; //0 P6OUT |= BIT3; //1 P6OUT |= BIT4; //1 P7OUT &= ~BIT0; //0 P6OUT &= ~BIT5; //0 P6OUT |= BIT6; //1 break; 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); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有