首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的用按钮控制直流电动机速度

简单的用按钮控制直流电动机速度
EN

Stack Overflow用户
提问于 2017-05-09 21:18:13
回答 2查看 1.1K关注 0票数 0

我正在STM32L152上运行一些测试,通过使用按钮选择3种不同的速度来控制DC motor speed,如下所示:

  1. 理想模式,电机关闭。
  2. 按下按钮,电机以1的速度运行。
  3. 再次按下按钮,电机以2的速度运行。
  4. 再次按下按钮,电机停止。

我已经尝试过通过设置CCR1 (TIM4)来直接运行马达,而且它工作得很好。所以我相信唯一的问题就是按钮部分。下面是代码:

代码语言:javascript
复制
#include <stdio.h>
#include "stm32l1xx.h"                  // Keil::Device:Startup

// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init()
{
// initialization of GPIOB
    RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST; /* Reset GPIOB clock */
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN; /* Enable GPIOB clock*/
    GPIOB->MODER &= ~(0x03 << (2 * 6)); /* Clear bit 12 & 13 Output mode*/
    GPIOB->MODER |= 0x01 << (2 * 6); /* set as Output mode*/
    GPIOB->OSPEEDR &= ~(0x03 << (2 * 6)); /* 40 MHz  speed */
    GPIOB->OSPEEDR |= 0x03 << (2 * 6); /* 40 MHz  speed*/
    GPIOB->PUPDR &= ~(1 << 6); /* NO PULL-UP PULL-DOWN*/
    GPIOB->OTYPER &= ~(1 << 6); /* PUSH-PULL*/
    GPIOB->AFR[0] |= 0x2 << (4 * 6);

// initialization of GPIOA
    RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST; /* Reset GPIOA clock*/
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN; /* Enable GPIOA clock*/
    GPIOA->MODER &= ~(0x03); /* Clear & set as input*/
    GPIOA->OSPEEDR &= ~(0x03); /* 2 MHz  speed */
    GPIOA->OSPEEDR |= 0x01; /* 2 MHz  speed */
    GPIOA->PUPDR &= ~(0x03); /* No PULL-UP/DOWN */
    GPIOA->OTYPER &= ~(0x1); /* PUSH-PULL */

//initialization of PWM & TIM4 
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    TIM4->PSC = 100;
    TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1

    TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2;   // 111: PWM mode 1 
    TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
    TIM4->CR1 |= TIM_CR1_ARPE;
    TIM4->CCER |= TIM_CCER_CC1E;
    TIM4->EGR |= TIM_EGR_UG;
    TIM4->SR &= ~TIM_SR_UIF;
    TIM4->DIER |= TIM_DIER_UIE;
    TIM4->CR1 |= TIM_CR1_CEN;
}

// Delay conf

void setSysTick(void)
{
// ---------- SysTick timer (1ms) -------- //
    if (SysTick_Config(SystemCoreClock / 1000))
    {
        // Capture error
        while (1)
        {
        };
    }
}

volatile uint32_t msTicks;      //counts 1ms timeTicks
void SysTick_Handler(void)
{
    msTicks++;
}

static void Delay(__IO uint32_t dlyTicks)
{
    uint32_t curTicks = msTicks;
    while ((msTicks - curTicks) < dlyTicks);
}

int returnVal = 0;
int updatedpress = 0;

int buttonpress()   // function to check & add, if the pushbutton is pressed
{

    if (GPIOA->IDR & GPIO_IDR_IDR_0)    //condition: if PA0 is set
    {
        Delay(500);   // avoid debouncing
        if (GPIOA->IDR & GPIO_IDR_IDR_0)   //confirm condition: if PA0 is set
        {
            returnVal = 1 + updatedpress;
            while (GPIOA->IDR & GPIO_IDR_IDR_0)
            {
            }
        }

    }

    return returnVal;
}

int main(void)
{

    GPIO_Init();
    setSysTick();

    while (1)
    {

        int buttonpress();

        updatedpress = returnVal;

        if (updatedpress == 1)
            TIM4->CCR1 = 30;

        else if (updatedpress == 2)
            TIM4->CCR1 = 37;

        else if (updatedpress == 3)
            TIM4->CCR1 = 46;

        else if (updatedpress > 3)
            returnVal = 0;

    }

}

当我运行代码时,没有任何东西能物理地工作。我试着运行调试器,我发现它在到达后立即退出了按钮按函数。

代码语言:javascript
复制
 if(GPIOA->IDR & GPIO_IDR_IDR_0)

知道它为什么不能正常工作吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-05-12 18:49:38

好的,它起作用了,下面是所做的更正:

1/ PB6 (与直流电机连接)被错误地设置为输出。改为备用函数。

2/ If-用于比较按下按钮数和选择电机转速的条件被移到一个称为runmotor的单独函数中。

3/读取指令if(GPIOA->IDR & 0x0001)被移动到主函数内的check循环中,以确保对按钮状态的连续检查。

4如@berendi所建议的,GPIOs重置已被清除

以下是更新的代码:

代码语言:javascript
复制
#include <stdio.h>
#include "stm32l1xx.h"                  // Keil::Device:Startup


// initialization of GPIOB, GPIOA & PWM/TIM4
void GPIO_Init(){
    // initialization of GPIOB
    RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST;     /* Reset GPIOB clock*/
    RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST;   /* Clear Reset */
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;      /* Enable GPIOB clock*/
    GPIOB->MODER   &=   ~(0x03 << (2*6));  /* Clear bit 12 & 13 */
    GPIOB->MODER   |=   0x02 << (2*6);    /* set as Alternate function*/
    GPIOB->OSPEEDR &=   ~(0x03<< (2*6)); /* 40 MHz  speed*/
    GPIOB->OSPEEDR |=   0x03<< (2*6);   /* 40 MHz  speed */
    GPIOB->PUPDR &=         ~(1<<6);   /* NO PULL-UP PULL-DOWN*/
    GPIOB->OTYPER &=        ~(1<<6);  /* PUSH-PULL*/
    GPIOB->AFR[0] |=        0x2 << (4*6);

    // initialization of GPIOA
    RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;    /* Reset GPIOA clock */
    RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST;  /* Clear Reset  */
    RCC->AHBENR |= RCC_AHBENR_GPIOAEN;     /* Enable GPIOA clock  */
    GPIOA->MODER   &=   ~(0x03);          /* Clear & set as input */
    GPIOA->OSPEEDR &=   ~(0x03);         /* 2 MHz  speed  */
    GPIOA->OSPEEDR |=   0x01;           /* 2 MHz  speed   */
    GPIOA->PUPDR &=         ~(0x03);   /* reset PULL-DOWN  */
    GPIOA->OTYPER &=        ~(0x1);   /* PUSH-PULL  */

    //initialization of PWM & TIM4 
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
    TIM4->PSC = 100; 
    TIM4->ARR = 414; // F=2.097MHz , Fck= 2097000/(100+1)= 20.762KHz, Tpwm = 0.02, ARR= (Fck x Tpwm)-1

    TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // 111: PWM mode 1 
    TIM4->CCMR1 |= TIM_CCMR1_OC1PE;
    TIM4->CR1 |= TIM_CR1_ARPE;
    TIM4->CCER |= TIM_CCER_CC1E;
    TIM4->EGR |= TIM_EGR_UG;
    TIM4->SR &= ~TIM_SR_UIF;
    TIM4->DIER |= TIM_DIER_UIE;
    TIM4->CR1 |= TIM_CR1_CEN;
    }

    void setSysTick(void){
    // ---------- SysTick timer (1ms) -------- //
    if (SysTick_Config(SystemCoreClock / 1000)) {
        // Capture error
        while (1){};
    }
}


    volatile uint32_t msTicks;      //counts 1ms timeTicks
void SysTick_Handler(void) {
    msTicks++;
}

static void Delay(__IO uint32_t dlyTicks){                                              
  uint32_t curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks);
}

    int buttonpress=0; 

     static void runmotor(void)
{
    if (buttonpress ==1){
            TIM4->CCR1 = 30;
    return;
        }
         if (buttonpress ==2){
            TIM4->CCR1 = 37;
    return;
         }
         if (buttonpress ==3){
            TIM4->CCR1 = 46;
    return;
         }
        if (buttonpress > 3){
            TIM4->CCR1 = 0;
            buttonpress = 0;
    return;
         }

}


int main(void){

    GPIO_Init();
    setSysTick();

while (1){  

      if(GPIOA->IDR & 0x0001)
    {
        Delay(5);
            if(GPIOA->IDR & 0x0001) 
                buttonpress = buttonpress + 1;
      runmotor();

}   
        }

    }
票数 0
EN

Stack Overflow用户

发布于 2017-05-10 06:25:56

GPIO外围设备处于重置状态,您应该清除重置位:

代码语言:javascript
复制
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST

/* ... */

RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43880023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档