/**
******************************************************************************
* @file : main.c
* @author : Auto-generated by STM32CubeIDE
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
#include <stdint.h>
#include "stm32f103xb.h"
void delay_ms(uint32_t ms){
volatile uint32_t i;
while(ms--)
{
for(i = 0; i < 8000; i++);
}
}
// Control de motor
void motor_stop(void)
{
GPIOB->ODR &= ~(1 << 0);
GPIOB->ODR &= ~(1 << 1);
}
void motor_forward(void)
{
GPIOB->ODR |= (1 << 0);
GPIOB->ODR &= ~(1 << 1);
}
void motor_reverse(void)
{
GPIOB->ODR &= ~(1 << 0);
GPIOB->ODR |= (1 << 1);
}
int main(void)
{
// Enable GPIOA y GPIOB
RCC->APB2ENR |= (1 << 2); // IOPA
RCC->APB2ENR |= (1 << 3); // IOPB
/* ---------- CONFIGURACIÓN GPIO ---------- */
// PA0 como entrada con pull-down
GPIOA->CRL &= ~(0xF << 0); // Limpia PA0
GPIOA->CRL |= (0x8 << 0); // Input pull-up/pull-down
GPIOA->ODR |= (1 << 0); // Pull-down activo
// PB0 y PB1 como salidas push-pull 2MHz
GPIOB->CRL &= ~(0xFF << 0); // Limpia PB0 y PB1
GPIOB->CRL |= (0x22 << 0); // Output PP 2 MHz
motor_stop();
uint8_t last_btnA = 1;
uint8_t last_btnB = 1;
while(1)
{
uint8_t btnA = (GPIOA->IDR & (1 << 0) ? 1 : 0);
uint8_t btnB = (GPIOA->IDR & (1 << 1) ? 1 : 0);
/* Botón A -> Giro forward */
if(!btnA && last_btnA)
{
motor_stop();
delay_ms(2000);
motor_forward();
}
/* Botón B -> Giro reverse */
if(!btnB && last_btnB)
{
motor_stop();
delay_ms(2000);
motor_reverse();
}
last_btnA = btnA;
last_btnB = btnB;
delay_ms(20); // Anti-rebote
}
}