最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

STM32控制編碼器電機(jī)速度閉環(huán)實(shí)現(xiàn)

2021-06-23 10:39 作者:老-_-白  | 我要投稿


STM32編程直流有刷電機(jī)PID速度閉環(huán)精準(zhǔn)變速控制 電機(jī)控制例程分享 (第十一期)
STM32編程利用HMI做上位機(jī)調(diào)參精準(zhǔn)PID閉環(huán)控制 (第十二期)
模塊連接圖(夠亂的吧 *-*)

利用STM32高級(jí)定時(shí)器的互補(bǔ)輸出模式驅(qū)動(dòng)電機(jī)運(yùn)行

/**

? * 函數(shù)功能: BDCMOTOR定時(shí)器初始化

? * 輸入?yún)?shù): 無

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void BDCMOTOR_TIMx_Init(void)

{

? TIM_ClockConfigTypeDef sClockSourceConfig;? ? ? ? ? ? ?// 定時(shí)器時(shí)鐘

? TIM_OC_InitTypeDef sConfigOC;? ? ? ? ? ? ? ? ? ? ? ? ? // 定時(shí)器通道比較輸出

? TIM_BreakDeadTimeConfigTypeDef? sBDTConfig;? ? ? ? ? ? // 定時(shí)器死區(qū)時(shí)間比較輸出


? /* 基本定時(shí)器外設(shè)時(shí)鐘使能 */

? BDCMOTOR_TIM_RCC_CLK_ENABLE();


? /* 定時(shí)器基本環(huán)境配置 */

? htimx_BDCMOTOR.Instance = BDCMOTOR_TIMx;? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 定時(shí)器編號(hào)

? htimx_BDCMOTOR.Init.Prescaler = BDCMOTOR_TIM_PRESCALER;? ? ? ? ? ? ? ? ? // 定時(shí)器預(yù)分頻器

? htimx_BDCMOTOR.Init.CounterMode = TIM_COUNTERMODE_UP;? ? ? ? ? ? ? ? ? // 計(jì)數(shù)方向:向上計(jì)數(shù)

? htimx_BDCMOTOR.Init.Period = BDCMOTOR_TIM_PERIOD;? ? ? ? ? ? ? ? ? ? ? ? // 定時(shí)器周期

? htimx_BDCMOTOR.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;? ? ? ? ? ? ? // 時(shí)鐘分頻

? htimx_BDCMOTOR.Init.RepetitionCounter = BDCMOTOR_TIM_REPETITIONCOUNTER;? // 重復(fù)計(jì)數(shù)器

? /* 初始化定時(shí)器比較輸出環(huán)境 */

? HAL_TIM_PWM_Init(&htimx_BDCMOTOR);


? /* 定時(shí)器時(shí)鐘源配置 */

? sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;? ? ? ?// 使用內(nèi)部時(shí)鐘源

? HAL_TIM_ConfigClockSource(&htimx_BDCMOTOR, &sClockSourceConfig);


? /* 死區(qū)剎車配置,配置有效電平是低電平 */

? sBDTConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE ;

? sBDTConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW ;

? sBDTConfig.BreakState = TIM_BREAK_DISABLE ;

? sBDTConfig.DeadTime = 0 ;

? sBDTConfig.LockLevel = TIM_LOCKLEVEL_OFF ;

? sBDTConfig.OffStateIDLEMode= TIM_OSSI_DISABLE ;

? sBDTConfig.OffStateRunMode = TIM_OSSR_ENABLE ;

? HAL_TIMEx_ConfigBreakDeadTime(&htimx_BDCMOTOR,&sBDTConfig);


? /* 定時(shí)器比較輸出配置 */

? sConfigOC.OCMode = TIM_OCMODE_PWM1;? ? ? ? ? ? ? ? ? // 比較輸出模式:PWM1模式

? sConfigOC.Pulse =? PWM_Duty;? ? ? ? ? ? ? ? ? ? ? ? ?// 占空比

? sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;? ? ? ? ? // 輸出極性

? sConfigOC.OCNPolarity = TIM_OCNPOLARITY_LOW;? ? ? ? // 互補(bǔ)通道輸出極性

? sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;? ? ? ? ? ?// 快速模式

? sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;? ? ? ?// 空閑電平

? sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;? ? ?// 互補(bǔ)通道空閑電平

? HAL_TIM_PWM_ConfigChannel(&htimx_BDCMOTOR, &sConfigOC, TIM_CHANNEL_1);


? HAL_TIM_Base_Start(&htimx_BDCMOTOR);

}

驅(qū)動(dòng)模塊連接圖

電機(jī)控制的幾個(gè)基本操作又一下幾個(gè)函數(shù)完成

/**

? * 函數(shù)功能: 設(shè)置電機(jī)速度

? * 輸入函數(shù): Duty,輸出脈沖占空比

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void SetMotorSpeed(int16_t Duty)

{

? __HAL_TIM_SetCompare(&htimx_BDCMOTOR,TIM_CHANNEL_1,Duty);

}


/**

? * 函數(shù)功能: 設(shè)置電機(jī)轉(zhuǎn)動(dòng)方向

? * 輸入函數(shù): Dir,電機(jī)轉(zhuǎn)動(dòng)方向

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void SetMotorDir(int16_t Dir)

{

? if(Dir)

? {

? ? HAL_TIM_PWM_Start(&htimx_BDCMOTOR,TIM_CHANNEL_1);

? ? HAL_TIMEx_PWMN_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);? ? ? ? ?// 停止輸出

? }

? else

? {

? ? HAL_TIM_PWM_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);

? ? HAL_TIMEx_PWMN_Start(&htimx_BDCMOTOR,TIM_CHANNEL_1);? ? ? ? ?// 停止輸出

? }

}


/**

? * 函數(shù)功能: 設(shè)置電機(jī)停止

? * 輸入函數(shù): 無

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void SetMotorStop()

{

? HAL_TIM_PWM_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);

? HAL_TIMEx_PWMN_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);? ? ? ? ?// 停止輸出

}

/**

? * 函數(shù)功能: 設(shè)置電機(jī)啟動(dòng)

? * 輸入函數(shù): 無

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void SetMotorStart()

{

? HAL_TIM_PWM_Start(&htimx_BDCMOTOR,TIM_CHANNEL_1);

? HAL_TIMEx_PWMN_Stop(&htimx_BDCMOTOR,TIM_CHANNEL_1);? ? ? ? ?// 停止輸出

}

編碼器電機(jī)連接圖

電機(jī)速度控制反饋信號(hào)是利用STM32定時(shí)器編碼器模式讀取電機(jī)編碼器脈沖信號(hào)

/**

? * 函數(shù)功能: 通用定時(shí)器初始化并配置編碼器模式

? * 輸入?yún)?shù): 無

? * 返 回 值: 無

? * 說? ? 明: 無

? */

void ENCODER_TIMx_Init(void)

{

? ENCODER_TIM_RCC_CLK_ENABLE();

? htimx_Encoder.Instance = ENCODER_TIMx;

? htimx_Encoder.Init.Prescaler = ENCODER_TIM_PRESCALER;

? htimx_Encoder.Init.CounterMode = TIM_COUNTERMODE_UP;

? htimx_Encoder.Init.Period = ENCODER_TIM_PERIOD;

? htimx_Encoder.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;


? sEncoderConfig.EncoderMode? ? ? ? = TIM_ENCODERMODE_TIx;

? sEncoderConfig.IC1Polarity? ? ? ? = TIM_ICPOLARITY_RISING;

? sEncoderConfig.IC1Selection? ? ? ?= TIM_ICSELECTION_DIRECTTI;

? sEncoderConfig.IC1Prescaler? ? ? ?= TIM_ICPSC_DIV1;

? sEncoderConfig.IC1Filter? ? ? ? ? = 0;


? sEncoderConfig.IC2Polarity? ? ? ? = TIM_ICPOLARITY_RISING;

? sEncoderConfig.IC2Selection? ? ? ?= TIM_ICSELECTION_DIRECTTI;

? sEncoderConfig.IC2Prescaler? ? ? ?= TIM_ICPSC_DIV1;

? sEncoderConfig.IC2Filter? ? ? ? ? = 0;

? __HAL_TIM_SET_COUNTER(&htimx_Encoder,0);


? HAL_TIM_Encoder_Init(&htimx_Encoder, &sEncoderConfig);


? __HAL_TIM_CLEAR_IT(&htimx_Encoder, TIM_IT_UPDATE);? // 清除更新中斷標(biāo)志位

? __HAL_TIM_URS_ENABLE(&htimx_Encoder);? ? ? ? ? ? ? ?// 僅允許計(jì)數(shù)器溢出才產(chǎn)生更新中斷

? __HAL_TIM_ENABLE_IT(&htimx_Encoder,TIM_IT_UPDATE);? // 使能更新中斷


? HAL_NVIC_SetPriority(ENCODER_TIM_IRQn, 0, 0);

? HAL_NVIC_EnableIRQ(ENCODER_TIM_IRQn);


? HAL_TIM_Encoder_Start(&htimx_Encoder, TIM_CHANNEL_ALL);

}

編碼器電機(jī)PID速度閉環(huán)控制


編碼器電機(jī)速度閉環(huán)控制由PID算法在調(diào)控周期里進(jìn)行反饋調(diào)整

/**

? * 函數(shù)名稱:速度閉環(huán)PID控制設(shè)計(jì)

? * 輸入?yún)?shù):當(dāng)前控制量

? * 返 回 值:目標(biāo)控制量

? * 說? ? 明:無

? */

int32_t SpdPIDCalc(float NextPoint)

{

? float iError,iIncpid;

? iError = (float)sPID.SetPoint - NextPoint; //偏差


? if((iError<0.2f )&& (iError>-0.2f))

? ? iError = 0.0f;


? iIncpid=(sPID.Proportion * iError)? ? ? ? ? ? ? ? ?//E[k]項(xiàng)

? ? ? ? ? ? ? -(sPID.Integral * sPID.LastError)? ? ?//E[k-1]項(xiàng)

? ? ? ? ? ? ? +(sPID.Derivative * sPID.PrevError);? //E[k-2]項(xiàng)


? sPID.PrevError = sPID.LastError;? ? ? ? ? ? ? ? ? ? //存儲(chǔ)誤差,用于下次計(jì)算

? sPID.LastError = iError;

? return(iIncpid);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //返回增量值


}


? /* 速度環(huán)周期100ms */

? if(uwTick % pid_n_s == 0) //到達(dá)一個(gè)調(diào)控周期

? {

? ? //Spd_Pulse? 編碼器捕獲值 Pulse = 累計(jì)捕獲中斷次數(shù)*65535 + 通過編碼器接口HAL接口讀取的脈沖數(shù)

Spd_Pulse = (OverflowCount*CNT_MAX) + (int32_t)__HAL_TIM_GET_COUNTER(&htimx_Encoder);

? ? //檢測周期里累計(jì)的脈沖數(shù)=編碼器捕獲的脈沖數(shù) - 上次捕獲的脈沖值

? ? Spd_PPS = Spd_Pulse - LastSpd_Pulse;

//記錄為上次捕獲的脈沖值(為下次計(jì)算使用

? ? LastSpd_Pulse = Spd_Pulse ;


? ? /*變量pid_1=(圈數(shù)/周期)*/

float pid_1 = (float)Spd_PPS/(float)PPR ;

//pid_1:pid_n_s周期內(nèi)電機(jī)轉(zhuǎn)動(dòng)的圈數(shù)=周期內(nèi)捕獲的脈沖數(shù) / 每圈的脈沖數(shù)

/*變量pid_2=(轉(zhuǎn)/毫秒)*/

float pid_2 = pid_1 / (float)pid_n_s ;

//pid_2:計(jì)算實(shí)際測量速度(轉(zhuǎn)/毫秒)=周期內(nèi)轉(zhuǎn)過的圈數(shù) / 周期時(shí)間值 (因?yàn)橹芷趩挝粸楹撩耄?/span>


/*Spd_RPM=(轉(zhuǎn)/秒)*/

Spd_RPM = pid_2 * (float)1000 ;//單位轉(zhuǎn)換為(轉(zhuǎn)/秒)


? ?

? ? /* 計(jì)算PID結(jié)果 */

? ? if(Start_flag == 1)

? ? {

? ? ? PWM_Duty += SpdPIDCalc(Spd_RPM);


? ? ? /* 判斷當(dāng)前運(yùn)動(dòng)方向 */

? ? ? if(PWM_Duty < 0)

? ? ? {

? ? ? ? Motor_Dir = CW;

? ? ? ? BDDCMOTOR_DIR_CW();

? ? ? ? SetMotorSpeed(-PWM_Duty);

? ? ? }

? ? ? else

? ? ? {

? ? ? ? Motor_Dir = CCW;

? ? ? ? BDDCMOTOR_DIR_CCW();

? ? ? ? SetMotorSpeed(PWM_Duty);

? ? ? }

? ? }

? }

編碼器電機(jī)PID速度閉環(huán)上位機(jī)調(diào)試


STM32控制編碼器電機(jī)速度閉環(huán)實(shí)現(xiàn)的評(píng)論 (共 條)

分享到微博請遵守國家法律
乌兰察布市| 抚宁县| 孝感市| 通城县| 公安县| 济宁市| 乐陵市| 南通市| 乐平市| 阿荣旗| 定边县| 剑阁县| 广德县| 峨边| 华蓥市| 镇平县| 凤城市| 奎屯市| 铜梁县| 永嘉县| 鄂温| 方城县| 沅陵县| 阿荣旗| 徐汇区| 得荣县| 铁岭县| 绿春县| 宝山区| 资兴市| 轮台县| 大丰市| 洞口县| 耿马| 泰顺县| 溆浦县| 昌邑市| 崇左市| 花莲县| 衡阳县| 六枝特区|