直流电机驱动程序,采用DRV8833驱动,并用霍尔传感器测量转速,测量精确
所有资料51hei提供下载:
直流电机驱动程序,采用DRV8833驱动,并用霍尔传感器测量转速,测量精确.zip
(655.84 KB, 下载次数: 162)
msp430单片机源程序如下:
- /*
- * DC_Motor.c
- *
- * Created on: 8-31
- * Author: zdl
- */
- #include "global.h"
- //---------------------相关宏定义-------------------------
- #define ENCODE_NUM 4 //测速码盘齿轮数目
- #define MAX_SPEED 340 //最大转速(r/s)
- #define P_Coefficient 11 //PID反馈中的比例系数
- #define I_Coefficient 2 //PID反馈中的微分系数
- #define D_Coefficient 1 //PID反馈中的积分系数
- //---------------------相关变量定义-----------------------
- static uint16_t ui16Speed_Preset = 0; //预设速度
- static uint16_t ui16Speed_True = 0; //实测速度,单位XX转/分
- uint16_t ui16Speed_Measure = 0; //实测速度,单位XX转/分
- static uint16_t ui16Speed_Pecent = 0; //速度百分比,用于更新速度曲线
- uint16_t ui16TA0_Overflow_Cnt = 0; //定时器溢出计数
- uint16_t ui16TA1_Overflow_Cnt = 0; //定时器溢出计数
- static uint8_t ui8FirstFlag = 1; //PID算法中微分项需要判断首次上电
- //---------------------局部函数声明---------------------
- static void Speed_Disp();
- static uint16_t PID_PWM(int16_t i16Error);
- static void Get_Fre();
- void DC_Motor_Graph()
- {
- //-----Draw Title-----
- GrClearDisplay(&g_sContext);
- GrTaskRectDraw();
- //-----绘制转速单位-----
- GrStringDrawCentered(&g_sContext, "(r/s)", AUTO_STRING_LENGTH, 52, 20, OPAQUE_TEXT);
- //-----绘制波形坐标轴-----
- GrAxisDraw();
- GrFlush(&g_sContext);
- }
- void DC_Motor_Begin()
- {
- //--------GPIO Init--------
- P2DIR &= ~BIT7; //-----测速中断IO初始化-----
- P2IES |= BIT7;
- P2IE |= BIT7;
- P1DIR |= BIT3 +BIT4; //-----配置P1.3和P1.4电机PWM控制IO参数-----
- P1OUT |= BIT3;
- P1SEL |= BIT4;
- //-----TA1 ContinuousMode Init-----
- TIMER_A_configureContinuousMode(__MSP430_BASEADDRESS_T1A3__,//选择TA1定时器
- TIMER_A_CLOCKSOURCE_SMCLK,
- TIMER_A_CLOCKSOURCE_DIVIDER_1,
- TIMER_A_TAIE_INTERRUPT_ENABLE,
- TIMER_A_DO_CLEAR);
- TA1CTL = TASSEL_2 + MC_2 + TACLR + TAIE; //启动测速
- //-----TA0.3 PWM Init------
- TIMER_A_generatePWM( __MSP430_BASEADDRESS_T0A5__,//选择TA0定时器
- TIMER_A_CLOCKSOURCE_SMCLK,
- TIMER_A_CLOCKSOURCE_DIVIDER_1,
- SYSMCLK/10000-1, //PWM 10K
- TIMER_A_CAPTURECOMPARE_REGISTER_3,
- TIMER_A_OUTPUTMODE_SET_RESET ,
- SYSMCLK/10000-1
- );
- //-----首次PID算法置标志位-----
- ui8FirstFlag = 1; //PID算法中用于判断第一次的标志位
- }
- void DC_Motor_Main()
- {
- Draw_Histogram(0); //更新柱状图
- Get_Fre();
- Speed_Disp(); //更新预设与实测速度值
- Draw_Waveform(&ui16Speed_Pecent,1); //更新速度曲线
- GrFlush(&g_sContext); //刷新屏幕
- LPM3; //执行函数由WDT定时唤醒
- }
- void DC_Motor_Quit()
- {
- //-----GPIO Quit-----
- P2DIR |= BIT7;
- P2IE &= ~BIT7;
- P1SEL &= ~BIT4;
- P1OUT &= ~(BIT3+BIT4);
- ui8FirstFlag=1;
- //-----TA0 Quit-----
- TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T0A5__);
- //-----TA1 Quit-----
- TIMER_A_disableInterrupt(__MSP430_BASEADDRESS_T1A3__);
- }
- //-------------速度显示-------------
- static void Speed_Disp()
- {
- //-----更新变量值-----
- ui16Speed_Preset=MAX_SPEED*ui8Wheel_Pecent/100;
- ui16Speed_Pecent=ui16Speed_True*100/MAX_SPEED;
- //-----刷新显示-----
- GrStringDrawCentered(&g_sContext, " ",
- AUTO_STRING_LENGTH,20,20, OPAQUE_TEXT); //清除前一次显示
- GrStringNumberCentered(&g_sContext,
- ui16Speed_True,0,20,20);
- GrStringDrawCentered(&g_sContext, " ",
- AUTO_STRING_LENGTH,113,20, OPAQUE_TEXT); //清除前一次显示
- GrStringNumberCentered(&g_sContext,
- ui16Speed_Preset,0,113,20);
- ui16Speed_True=0;
- ui16Speed_Preset=0;
- }
- //----PID算法,计算出PWM占空比,8192等同100%占空比------
- static uint16_t PID_PWM(int16_t i16Error)
- {
- static int16_t i16Error_Prev = 0;
- static int16_t i16Integral = 0;
- int16_t i16P_Component ,i16I_Component ,i16D_Component ;
- int16_t i16Result;
- if(ui8FirstFlag) //首次上电缺乏前次误差,补上。
- {
- ui8FirstFlag = 0;
- i16Error_Prev = i16Error;
- i16Integral=0;
- }
- i16P_Component = P_Coefficient*i16Error;
- i16I_Component = I_Coefficient*i16Integral;
- i16D_Component = D_Coefficient*(i16Error-i16Error_Prev);
- //-----误差积分-----
- i16Integral += i16Error;
- i16Result = i16P_Component + i16I_Component + i16D_Component;
- //-----输出限幅----
- if(i16Result > 8192)
- i16Result = 8192;
- if(i16Result < 0)
- i16Result = 0;
- return(i16Result);
- }
- /********************************************************
- *
- * 以下函数需要放置在中断服务子函数中调用
- *
- ********************************************************/
- //-----WDT中断定时更新占空比-----
- void Change_PWM_Duty()
- {
- int16_t i16Error = ui16Speed_Preset - ui16Speed_True;
- uint32_t ui16PWM_Duty = PID_PWM(i16Error);
- TA0CCR3 = (uint16_t)((ui16PWM_Duty)*TA0CCR0/8192); //改变PWM占空比
- }
- //-----测量实际转速,此函数在P2中断中被调用-----
- static uint16_t ui16PreTemp=0;
- void Measure_Freq()
- {
- uint32_t Speed_Sum;
- uint16_t ui16Temp;
- ui16Temp=TA1R;
- Speed_Sum = (uint32_t)ui16Temp + (uint32_t)65536*ui16TA1_Overflow_Cnt-ui16PreTemp;//测速前的值减去测速后的计数值,那么就是在一段时间内计数的次数
- ui16PreTemp = ui16Temp;
- ui16TA1_Overflow_Cnt = 0;
- ui16Speed_Measure = (uint16_t)( SYSMCLK / Speed_Sum); //计算频率 , 开孔圆盘上有许多小孔,开孔圆盘旋转一周,光敏元件输出的电脉冲个数等于圆盘的开孔数,因此,可通过测量光敏元件输出的脉冲频率
- }
- //获取测量的速度,应该是获取转速
- static void Get_Fre()
- {
- ui16Speed_True = ui16Speed_Measure/ENCODE_NUM; //返回实测转速值,除以齿轮数目
- }
复制代码
|