我正在STM32L152
上运行一些测试,尝试使用按钮选择3种不同的速度来控制DC motor speed
,如下所示:
我已经尝试通过设置CCR1 (TIM4)
直接运行电机,它运行正常。所以我认为唯一的问题是按钮部分。这是代码:
#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;
}
}
当我运行代码时,没有任何物理上的工作。我试图运行调试器,我发现它在到达后立即退出 buttonpress 函数
if(GPIOA->IDR & GPIO_IDR_IDR_0)
知道它为什么不能正常工作?
答案 0 :(得分:1)
GPIO外设保持复位状态,应清除复位位:
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST
/* ... */
RCC->AHBRSTR |= RCC_AHBRSTR_GPIOARST;
RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOARST;
答案 1 :(得分:0)
确定它有效,以下是更正:
1 / PB6(连接到直流电机)被错误地设置为输出。改为替代功能。
2 / If-用于比较按钮数和选择电机速度的条件转移到一个名为runmotor
的单独函数
3 /读取指令if(GPIOA->IDR & 0x0001)
被移动到主函数内的while循环中,以确保连续检查按钮条件。
4 /根据@berendi
的建议清除GPIO的复位这里是更新后的代码:
#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();
}
}
}