#include <stdint.h>
#include "stm32f103_hal.h"
/* ================= VARIABLES ================= */
volatile uint32_t last_count = 0;
volatile uint32_t current_count = 0;
volatile uint32_t pulse_count = 0;
volatile float rpm = 0;
volatile uint32_t delta_t = 0;
volatile uint8_t flag_90 = 0;
/* ================= PROTOTIPOS ================= */
float leer_temp(void);
uint32_t calcular_delta_t(float rpm, float temp);
/* ================= MAIN ================= */
int main(void)
{
/* Clock a 72 MHz */
rcc_set_clock(RCC_SYSCLK_HSI, RCC_PLL_X9);
/* GPIO */
gpio_set_mode(GPIOA, 0, 0); // PA0 -> CKPSENS
gpio_set_mode(GPIOA, 1, 0); // PA1 -> CKPZSENS
gpio_set_mode(GPIOB, 6, 2); // PB6 -> PWM salida
/* EXTI en PA1 (referencia 0°) */
exti_set_interrupt(PA1, EXTI_IRQ_RISING);
/* ================= TIMER 1: ENCODER ================= */
rcc_clock_enable(RCC_TIM1);
timer_set_encoder_mode(TIM1, TIMER_ENCODER_MODE_TI1);
/* ================= TIMER 3: 90° ================= */
rcc_clock_enable(RCC_TIM3);
/* ================= TIMER 2: Δt ================= */
rcc_clock_enable(RCC_TIM2);
/* ================= TIMER 4: PWM ================= */
rcc_clock_enable(RCC_TIM4);
/* PWM 100 kHz, 20% duty */
TIM4->PSC = 0;
TIM4->ARR = 720 - 1;
TIM4->CCR1 = 144;
TIM4->CCMR1 |= (6 << 4); // PWM mode
TIM4->CCER |= 1; // Enable CH1
TIM4->CR1 |= (1 << 3); // One-shot
/* ================= ADC ================= */
rcc_clock_enable(RCC_ADC1);
adc_set_channel(ADC1, ADC_CHANNEL_0, ADC_SMP_71_5);
/* ================= LOOP ================= */
while (1)
{
/* Leer encoder */
current_count = timer_get_encoder_count(TIM1);
if(current_count != last_count)
{
pulse_count++;
/* 180 pulsos = 1 vuelta */
if(pulse_count >= 180)
{
rpm = 60.0f; // simplificado
pulse_count = 0;
}
last_count = current_count;
}
/* Si ya llegaste a 90° */
if(flag_90)
{
float temp = leer_temp();
delta_t = calcular_delta_t(rpm, temp);
/* Timer Δt */
TIM2->PSC = 72 - 1; // 1 MHz
TIM2->ARR = delta_t;
TIM2->CR1 |= (1 << 3); // one-shot
TIM2->CR1 |= 1;
flag_90 = 0;
}
}
}
/* ================= EXTI (0°) ================= */
void EXTI1_IRQHandler(void)
{
/* Configurar timer para 90° */
TIM3->PSC = 72 - 1;
TIM3->ARR = 45; // 90°
TIM3->CR1 |= (1 << 3);
TIM3->CR1 |= 1;
EXTI->PR |= (1 << 1);
}
/* ================= TIMER 3 ================= */
void TIM3_IRQHandler(void)
{
flag_90 = 1;
TIM3->SR &= ~(1);
}
/* ================= TIMER 2 ================= */
void TIM2_IRQHandler(void)
{
/* Activar PWM (inyector) */
TIM4->CR1 |= 1;
TIM2->SR &= ~(1);
}
/* ================= FUNCIONES ================= */
float leer_temp(void)
{
uint16_t adc = adc_read(ADC1);
return (adc * 3.3f / 4096.0f) / 0.01f;
}
uint32_t calcular_delta_t(float rpm, float temp)
{
if(temp < 85)
return (uint32_t)(1000 + rpm * 2);
else
return (uint32_t)(800 + rpm);
}