1.背景
前幾天找出個步進電機,用L298N驅動測試了一下,具體見上篇文章簡單的步進電機驅動調試。但是L298N無法實現細分控制,在低速轉動時,聲音比較大,且振動厲害,因此想著嘗試一下細分控制效果。于是花十二塊大洋某寶購買了一塊T“MC2209步進電機超靜音驅動模塊”來測試一下。
2.硬件及連接
2.1硬件
2.2接口連接
TMC2009模塊的接口連接如下:
3.原理介紹
3.1 TMC2209模塊介紹
TMC2209是TRIAMINIC推出的一款步進電機驅動模塊。驅動模塊靜音且高精度,可以實現高達1/256步細分控制,實現更平滑靜音的步進電機控制。模塊內嵌12.5 MHz的內部振蕩器,簡單串行數據傳輸的UART。性價比較高的步進電機驅動模塊。
3.2 TMC2209規格
工作電壓:5.5 – 38V
最大內部時鐘頻率:12.5 MHz
每相最大電流:2 A
峰值輸出電流:2.8A
邏輯工作電壓:3/5V
3.3 TMC2209針腳定義
3.4 微步細分配置
1)硬件細分配置
TMC2209模塊提供了硬件微步配置,通過MS1和MS2可以實現1/8、1/16、1/32、1/64的細分控制,具體如下:
2)軟件細分配置
如果想實現更高的細分控制,則需要通過USART口進行配置,具體如下:
(測試中,測試完完善進來)
4.程序代碼
4.1 TMC2209初始化
//硬件微步設置
void micro_step_set(rt_uint8_t step)
{
switch (step) {
case 8:
rt_pin_write(MS1_PIN, PIN_LOW);
rt_pin_write(MS2_PIN, PIN_LOW);
break;
case 16:
rt_pin_write(MS1_PIN, PIN_HIGH);
rt_pin_write(MS2_PIN, PIN_HIGH);
break;
case 32:
rt_pin_write(MS1_PIN, PIN_HIGH);
rt_pin_write(MS2_PIN, PIN_LOW);
break;
case 64:
rt_pin_write(MS1_PIN, PIN_LOW);
rt_pin_write(MS2_PIN, PIN_HIGH);
break;
default:
break;
}
}
static int tmc2209_init(void)
{
rt_pin_mode(EN_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(MS1_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(MS2_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(STEP_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(DIR_PIN, PIN_MODE_OUTPUT);
rt_pin_write(EN_PIN, PIN_LOW);
micro_step_set(MICRO_STEP);
hwtimer_init();
return 0;
}
INIT_APP_EXPORT(tmc2209_init);
4.2 PWM設置
這里采用了PWM(ART-Pi默認的PWM5通道1)來輸出脈沖信號控制步進電機的轉動速度,下面是使用函數:
int pwm_set(rt_uint16_t fre, rt_uint8_t duty_cycle)
{
rt_uint32_t period = 0;
rt_uint32_t pulse = 0;
pwm_dev = (struct rt_device_pwm )rt_device_find(PWM_DEV_NAME);
if (pwm_dev == RT_NULL)
{
rt_kprintf("pwm sample run failed! can't find %s device!n", PWM_DEV_NAME);
return RT_ERROR;
}
period = 1000000000 / fre;
pulse = period * duty_cycle / 100;
/ 設置PWM周期和脈沖寬度默認值 /
rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
/ 使能設備 */
rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
return 0;
}
4.3 定時器配置
這里采用硬件定時器(ART-Pi默認TIM13,PS:settings雖然可以直接配置,但是cubemx默認沒配置TIM13,所以直接使用還是不行,需要cubemx配置后才能使用)來控制PWM輸出指定的脈沖數量,通過計算步進電機轉動的角度所需要的脈沖個數,以及轉動速度計算的脈沖時間,計算出定時器的計時時間,超時后停止PWM輸出,并禁止TMC2209(不禁止的話電機會發熱)。
#define HWTIMER_DEV_NAME "timer13" /* 定時器名稱 /
/ 定時器超時回調函數 /
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL);//停止PWM輸出
rt_pin_write(EN_PIN, PIN_HIGH);//禁止TMC2209
return 0;
}
int hwtimer_init(void)
{
rt_err_t ret = RT_EOK;
rt_hwtimer_mode_t mode; / 定時器模式 /
rt_uint32_t freq = 1000000; / 計數頻率 /
/ 查找定時器設備 /
hw_dev = rt_device_find(HWTIMER_DEV_NAME);
if (hw_dev == RT_NULL)
{
rt_kprintf("hwtimer sample run failed! can't find %s device!n", HWTIMER_DEV_NAME);
return RT_ERROR;
}
/ 以讀寫方式打開設備 /
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
if (ret != RT_EOK)
{
rt_kprintf("open %s device failed!n", HWTIMER_DEV_NAME);
return ret;
}
/ 設置超時回調函數 /
rt_device_set_rx_indicate(hw_dev, timeout_cb);
/ 設置計數頻率(若未設置該項,默認為1Mhz 或 支持的最小計數頻率) /
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
/ 設置模式為周期性定時器(若未設置,默認是HWTIMER_MODE_ONESHOT)*/
mode = HWTIMER_MODE_ONESHOT;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
rt_kprintf("set mode failed! ret is :%dn", ret);
return ret;
}
return ret;
}
int hwtimer_start(rt_hwtimerval_t timeout)
{
if (rt_device_write(hw_dev, 0, &timeout, sizeof(timeout)) != sizeof(timeout))
{
rt_kprintf("set timeout value failedn");
return RT_ERROR;
}
return RT_EOK;
}
4.4 步進電機控制
這里采用了兩種方式來輸出脈沖及數量,一種是通過延時和翻轉DIR管腳電平實現,一種是通過定時器和PWM來實現。
/*
dir:電機轉動方向,0 正轉;1 反轉
speed:電機轉動速度:0-300r/min,注意不同的電機最高轉速不一樣
angle:電機轉動角度:°
/
void turn_control(rt_uint8_t dir, rt_uint16_t speed, float_t angle)
{
rt_uint32_t pulse_num = 0;//脈沖數量
rt_uint16_t delay_time = 0;
rt_uint16_t pulse_fre = 0;//脈沖頻率
rt_hwtimerval_t timeout_value;
float_t temp = 0.0;
temp = (angle / (360.0 / 200.0 / MICRO_STEP));
float_t t = 1000000 / ((360.0 / (360.0 / 200.0 / MICRO_STEP)) / 60.0 * speed);
pulse_num = temp;
delay_time = t / 2;
pulse_fre = 1000000 / t;
timeout_value.sec = 0;
timeout_value.usec = t * pulse_num;
//rt_kprintf("%dn", pulse_num);
//rt_kprintf("%dn", delay_time);
//rt_kprintf("%dn", pulse_fre);
//rt_kprintf("%dn", timeout_value.usec);
rt_pin_write(EN_PIN, PIN_LOW);
//設置電機轉動方向
if(dir == 0)
rt_pin_write(DIR_PIN, PIN_HIGH);
if(dir == 1)
rt_pin_write(DIR_PIN, PIN_LOW);
pwm_set(pulse_fre, 50);//設置PWM頻率并輸出
hwtimer_start(timeout_value);//設置定時時間并啟動定時器
/ for (int i = 0; i < pulse_num; ++i) {
rt_pin_write(STEP_PIN, PIN_LOW);
//rt_thread_mdelay(speed);
rt_hw_us_delay(delay_time);
rt_pin_write(STEP_PIN, PIN_HIGH);
//rt_thread_mdelay(speed);
rt_hw_us_delay(delay_time);
}
rt_pin_write(EN_PIN, PIN_HIGH);*/
}
4.5 MSH控制臺
這里把電機控制加入MSH指令,可以通過控制臺來手動實現電機任意控制測試:
static void step_motor_turn(int argc, char**argv)
{
if (argc < 3)
{
rt_kprintf("Please input'step_motor_turn direction speed angle'n");
return;
}
if (!rt_strcmp(argv[1], "forward"))
{
turn_control(0, atof(argv[2]), atof(argv[3]));
}
else if (!rt_strcmp(argv[1], "reverse"))
{
turn_control(1, atoi(argv[2]), atof(argv[3]));
}
else
{
rt_kprintf("Please input'step_motor_turn direction speed angle'n");
}
}
MSH_CMD_EXPORT(step_motor_turn, step_motor_turn );
5.總結
電機的轉動確實非常安靜,完全聽不到聲音,在低速控制時轉動也比較平滑,完全感受不到振動。性價比不錯,有需要做步進電機控制的小伙伴可以參考使用。
-
振蕩器
+關注
關注
28文章
3812瀏覽量
138869 -
步進電機
+關注
關注
150文章
3095瀏覽量
147344 -
L298N驅動
+關注
關注
0文章
2瀏覽量
735 -
TMC2209
+關注
關注
1文章
5瀏覽量
5933 -
ART-Pi
+關注
關注
0文章
23瀏覽量
1285
發布評論請先 登錄
相關推薦
評論