/**
******************************************************************************
* @file : main.c
* @author : Fernando Hermosillo Reynoso
* @brief : Main program body
******************************************************************************
*/
#include <stdint.h>
#include "stm32f103_hal.h"
/* Defines -----------------------------------------------------*/
/* Private Variables ------------------------------ */
/* Private constants -------------------------------*/
/* Prototype Function ------------------------------*/
/* User code -----------------------------------------------------*/
void delay_ms(uint16_t ms) {
volatile unsigned long t = 0;
for(uint16_t i = 0; i < ms; i++)
{
for(t = 0; t < 800; t++);
}
}
void delay_us(uint16_t us)
{
for (volatile unsigned int cycles = 0; cycles < us; cycles++);
}
volatile uint32_t nd = 0;
volatile uint32_t contd = 0;
volatile int interrupciones = 0;
volatile int contintr = 0;
volatile uint32_t delta_t=0;
void exti0_init(void);
void exti1_init(void);
void exti2_init(void);
int main(void)
{
rcc_clock_enable(RCC_GPIOA);
rcc_clock_enable(RCC_GPIOB);
rcc_clock_enable(RCC_GPIOC);
rcc_clock_enable(RCC_TIM2);
rcc_clock_enable(RCC_TIM3);
rcc_clock_enable(RCC_TIM4);
/* Configurar I/Os */
gpio_set_output(GPIOC,GPIO_PIN_13,GPIO_OUTPUT_PP,GPIO_SPEED_2MHZ);
gpio_set_output(GPIOB,GPIO_PIN_6,GPIO_OUTPUT_PP,GPIO_SPEED_2MHZ);
gpio_set_input(GPIOA,GPIO_PIN_0,GPIO_INPUT_FLOAT);
gpio_set_input(GPIOA,GPIO_PIN_1,GPIO_INPUT_FLOAT);
gpio_set_input(GPIOA,GPIO_PIN_2,GPIO_INPUT_FLOAT);
gpio_set_input(GPIOA, GPIO_PIN_3, GPIO_INPUT_ANALOG);
adc_init(ADC1, ADC_MODE_SINGLE, ADC_TRIG_SOFTWARE, ADC_ALIGN_RIGHT);
adc_set_channel(ADC1, ADC_CHANNEL_3, ADC_SMP_28_5);
timer_init(TIM2,TIMER_MODE_UP,9999,799);
timer_set_interrupt(TIM2,TIMER_IRQ_UPDATE, IRQ_ENABLE);
NVIC->ISER[0] = 1 << 28;
timer_start(TIM2, TIMER_CONTINUOUS);
timer_init(TIM3,TIMER_MODE_UP,0,7999);
timer_set_interrupt(TIM3,TIMER_IRQ_UPDATE, IRQ_ENABLE);
NVIC->ISER[0] = 1 << 29;
timer_init(TIM4, TIMER_MODE_UP, 9, 7); // ARR=9, PSC=7
timer_set_oc_channel(
TIM4, // TIMER4
TIMER_CHANNEL_1, // T4C1 (PB6)
TIMER_OC_PWM2, // OC Mode: PWM1
TIMER_OC_POLARITY_HIGH, // Polarity: Active high
2, // CCR1=500 (CCR1 <= ARR)
true);
exti0_init();
exti1_init();
exti2_init();
float constante=0;
int rpm=0;
uint32_t Tmotor=0;
int temperatura=0;
while (1)
{
uint16_t adc_value=adc_read(ADC1);
// Vo = VREF*(ADC_VALUE)/ADC_MAX_VALUE
// Vo = 3.3*(ADC_VALUE)/4095
// El sensor tiene una conversion de temperatur de 10mV/grado celcius
// temperatura=Vo*(1C/0.01V)=3.3*(ADC_VALUE)*100/4095=33*(ADC_VALUE)*2/819
temperatura=(33*(adc_value)*2)/819;
constante=60/nd;
rpm=interrupciones*constante;
Tmotor=60*(1000000/rpm);
delta_t=(Tmotor/4)*(1+(200*(85-temperatura)));
if (delta_t<(Tmotor/4)){
delta_t=(Tmotor/4);
}
if (delta_t>(Tmotor/2)){
delta_t=(Tmotor/2);
}
}
}
void exti0_init(void)
{
// Enable EXTI clock
RCC->APB2ENR |= 1 << 0;
AFIO->EXTICR[0] &= ~(0x0F << 0);
// Enable the 'rising edge' trigger.
EXTI->RTSR |= (1 << 0);
// Disable the 'falling edge' trigger.
EXTI->FTSR &= ~(1<< 0);
// Setup EXTI0 line as an interrupt.
EXTI->IMR |= 1 << 0;
NVIC->IP[6] = (uint8_t)(0x03 << 4);
NVIC->ISER[0] = 1 << 6;
}
void EXTI0_IRQHandler(void)
{
// Check EXTI0 pending flag
if (EXTI->PR & (1 << 0))
{
// Clear the EXTI pending flag
EXTI->PR = (1 << 0);
// User code
nd=contd;
contd=0;
}
}
void exti1_init(void)
{
// Enable EXTI clock
AFIO->EXTICR[0] &= ~(0x0F << 4);
// Enable the 'rising edge' trigger.
EXTI->RTSR |= (1 << 1);
// Disable the 'falling edge' trigger.
EXTI->FTSR &= ~(1<< 1);
// Setup EXTI1 line as an interrupt.
EXTI->IMR |= 1 << 1;
NVIC->ISER[0] = 1 << 7;
}
void EXTI1_IRQHandler(void)
{
// Check EXTI1 pending flag
if (EXTI->PR & (1 << 1))
{
// Clear the EXTI pending flag
EXTI->PR = (1 << 1);
// User code
contd=contd+1;
contintr=contintr+1;
}
}
void exti2_init(void)
{
// Enable EXTI clock
AFIO->EXTICR[0] &= ~(0x0F << 8);
// Enable the 'rising edge' trigger.
EXTI->RTSR |= (1 << 2);
// Disable the 'falling edge' trigger.
EXTI->FTSR &= ~(1<< 2);
// Setup EXTI1 line as an interrupt.
EXTI->IMR |= 1 << 2;
NVIC->ISER[0] = 1 << 8;
}
void EXTI2_IRQHandler(void)
{
// Check EXTI1 pending flag
if (EXTI->PR & (1 << 2))
{
// Clear the EXTI pending flag
EXTI->PR = (1 << 2);
// User code
TIM3->ARR=((delta_t/1000)-1);
timer_start(TIM3, TIMER_ONESHOT);
}
}
void TIM2_IRQHandler(void){
TIM2->SR &= ~TIM_SR_UIF;
interrupciones=contintr;
contintr=0;
}
void TIM3_IRQHandler(void){
TIM3->SR &= ~TIM_SR_UIF;
GPIOC->ODR ^= (1<<13);
timer_start(TIM4, TIMER_ONESHOT);
}