引言
直接減速電機就是在直流電機上加上霍爾編碼器,霍爾編碼器可用于電機轉(zhuǎn)動的測速,A、B相會產(chǎn)生相位相差90°的方波信號。stm32可以使用硬件資源或者軟件模擬來捕獲編碼器信號。這里我介紹的是stm32自帶的編碼器模式來使用直流減速電機。
1.模塊介紹
1.1直流減速編碼電機
以下是直流減速電機的商品圖
??
同時我使用的是轉(zhuǎn)速為620的直流電機,此直流電機的電流在0.07A(空載)到1.8A(堵轉(zhuǎn))之間。
直流電機和編碼盤互相獨立供電,紅色和白色需要連接到電機驅(qū)動模塊的輸出。黑色和綠色是編碼器電源,3.3V供電。黃色和綠色就是編碼器的AB相,硬件資源會占用定時器的ch1和ch2通道。
1.2電機驅(qū)動模塊
直流電機沒有辦法直接接在單片機上面使用,大部分的單片機引腳通過的電流在100mA左右,沒有辦驅(qū)動直流電機,同時單片機也無法承受直流電機的反饋脈沖電流強度,會導致單片機燒毀。所以單片機驅(qū)動電機時添加驅(qū)動電路來控制電機的轉(zhuǎn)動。也就是由外部電源來提供電流,驅(qū)動電機轉(zhuǎn)動。
這里使用的是L298N驅(qū)動模塊來驅(qū)動電機轉(zhuǎn)動。
驅(qū)動模塊的5V連接到單片機的5V接口,L298N模塊在連接外部電源時會給單片機5V供電,L298N模塊的GND連接電池的負極以及單片機板載GND,輸出A和輸出B連接電機的正負極。
在測試模塊是否正常使用時,使能端(ENA和ENB)的跳線帽可以不拔(這樣相當于ENA、ENB接高電平,),IN1,IN2設置高低電平來讓電機轉(zhuǎn)動。當使用PWM信號控制電機轉(zhuǎn)速時,使能端的跳線帽要拔下來,同時PWM信號要輸入在使能端。
以下是L298N驅(qū)動模塊的引腳使用方法
ENA | IN1 | IN2 | 轉(zhuǎn)動 |
---|---|---|---|
1 | 1 | 0 | 是 |
1 | 0 | 1 | 是 |
1 | 1 | 1 | 否 |
0 | - | - | 否 |
ENB | IN3 | IN4 | 轉(zhuǎn)動 |
---|---|---|---|
1 | 1 | 0 | 是 |
1 | 0 | 1 | 是 |
1 | 1 | 1 | 否 |
0 | - | - | 否 |
接線如下
ENA–>PA8
ENB–>PA9
IN1–>PB12
IN2–>PB13
IN3–>PB14
IN4–>PB15
編碼器1–>PA0 PA1
編碼器2–>PA6 PA7
之后的代碼只舉例一個編碼電機,也就是編碼器2。
2.軟件部分
2.1中斷配置
使用TIM4定時器進行軟件中斷,用于刷新OLED顯示stm32捕獲編碼器的速度值,單獨寫在Timer.c的文件中
#include "stm32f10x.h" // Device header
void Timer_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4時鐘
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優(yōu)先級0級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //從優(yōu)先級0級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設NVIC寄存器
TIM_TimeBaseStructure.TIM_Period = 10000-1; //總的值設置為0xFFFF,設定計數(shù)器自動重裝值
TIM_TimeBaseStructure.TIM_Prescaler = 7200-1; //預分頻器
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數(shù)模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位
TIM_Cmd(TIM4, ENABLE); //開啟定時器
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); //開啟定時器更新中斷
}
中斷函數(shù)可以寫在Timer.c文件或者main.c文件
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
//LED_ON();//用于測試是否進入中斷
Speed1 = Encoder_Get1();
Speed2 = Encoder_Get2();
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
}
這里需要說明一下LED_ON();的函數(shù),這個函數(shù)的作用是點亮stm32f103c8t6最小系統(tǒng)板自帶的LED燈,新手在配置中斷時候可以使用這樣的方法快速檢驗是否進入中斷。
2.2編碼器模式配置
這里把TIM3配置為編碼器模式,當定時器配置為編碼器模式的時候,時鐘會被占用,無法處理其他任何工作,并且編碼器模式會占用時鐘的1和2通道。
#include "stm32f10x.h" // Device header
void Encoder_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//開啟時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;//配置GPIO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//配置時基單元
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;//配置編碼器模式
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
//開啟編碼器模式
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
TIM_Cmd(TIM3, ENABLE);//使能時鐘
}
int16_t Encoder_Get(void)//獲取編碼器模式讀取的值,用于OLED顯示
{
int16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
return Temp;
}
2.3主函數(shù)代碼
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "OLED.h"
#include "L298N.h"
#include "Timer.h"
#include "Encoder.h"
int16_t Speed1,Speed2;
int main(void)
{
OLED_Init();
Timer_Init();
LED_Init();
Encoder_Init();
L298N_Init();
OLED_ShowString(1, 1, "Speed1:");
OLED_ShowString(2, 1, "Speed2:");
while (1)
{
OLED_ShowSignedNum(1, 7, Speed1, 5);
OLED_ShowSignedNum(2, 7, Speed2, 5);
L298N_TurnText();
}
}
void TIM4_IRQHandler(void)//中斷函數(shù)一直刷新編碼器模式捕獲的值
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
//LED_OFF();//用于測試是否進入中斷
Speed1 = Encoder_Get1();
Speed2 = Encoder_Get2();
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
}
OLED顯示刷新放在中斷函數(shù)中是為了多任務考慮,如果只需要單片機顯示編碼器的值,那OLED的刷新放在主函數(shù)中就可以,但是會占用主程序的資源,單片機執(zhí)行其他任務就會有壓力。所以將OLED顯示刷新放在中斷函數(shù)中顯示
3.總結(jié)
使用stm32來捕獲編碼電機信號,主要是使用TIM_EncoderInterfaceConfig函數(shù)來開啟和配置編碼器模式。stm32的編碼器模式相關函數(shù)只有這一個。文章來源:http://www.zghlxwxcb.cn/news/detail-545898.html
stm32使用PWM信號控制直流電機速度會在我的其他文章中說明(還沒有更新出來),更新后我會把文章鏈接放在末尾。文章來源地址http://www.zghlxwxcb.cn/news/detail-545898.html
到了這里,關于直流減速編碼電機的使用(STM32f103c8t6)L298N電機驅(qū)動模塊的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!