Temporizadores

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 55

TEMPORIZADORES

GERSON PEREZ
TEMPORIZADORES

 Un temporizador es un contador de pulsos de reloj, cuyo conteo puede ser reducido con la
utilización de prescalers.
 Un prescaler define el número de pulsos de reloj que permiten que el contador del
temporizador se incremente en una unidad. Por ejemplo, un prescaler de 4 incrementa el
contador del temporizador en una unidad cada cuatro pulsos del reloj.
 Un temporizador puede ser utilizado como:
➢Como base para medir tiempo (temporizador)
➢Como contador de eventos.
 Un temporizador puede ser configurado para trabajar como:
➢Como capturador de señales externas (mide la frecuencia de un evento externo).
➢Como comparador (indica cuando a transcurrido un periodo de tiempo dado), y
➢Para generar modulación por ancho de pulsos (también conocida como PWM)
TEMPORIZADORES

Los temporizadores de los STM32 se pueden agrupar en varias categorías:

 Temporizadores básicos – Basic timers


 Temporizadores de propósito general – General purpose timers.
 Temporizadores avanzados – Advanced timers
 Temporizador de alta resolución – High resolution timer
 Temporizadores de bajo consumo – Low power timers
TEMPORIZADORES
CARACTERISRICAS
RELEVANTES DE CADA
CATEGORIA DE
TEMPORIZADOR
TEMPORIZADORES
 TEMPORIZADORES
IMPLEMENTADOS EN LA
FAMILIA STM32
TEMPORIZADORES
 TIMER QUE SON
IMPLEMENTADOS EN CADA
STM32
TEMPORIZADOR BÁSICO

La estructura de configuración es:


typedef struct
{
uint32_t Prescaler;

uint32_t CounterMode;
RELACION ENTRE LAS TRES CATEGORIAS DE TIMERS
TIPO DE CONTEO
uint32_t Period;
Ascendente, descendente y
Temporizador Avanzado alineado al centro
uint32_t ClockDivision;
Ascendente, descendente y
Temporizador de propósito general alineado al centro
uint32_t RepetitionCounter;
Temporizador Ascendente
} TIM_Base_InitTypeDef; Básico
TEMPORIZADOR BÁSICO

La estructura de configuración es: Reduce la velocidad del conteo, dividiendo el reloj del
temporizador entre un factor cuyo rango va desde 1 a 65535
typedef struct
{
uint32_t Prescaler; Define la forma de contar del temporizador, puede tomar
cualquiera de los siguientes valores:
uint32_t CounterMode;

uint32_t Period; TIM_COUNTERMODE_UP


Cuneta desde 0 hasta el valor del periodo generando un evento de desbordamiento
uint32_t ClockDivision; TIM_COUNTERMODE_DOWN
Cuenta desde el valor del periodo hasta 0 generando un evento de desbordamiento
uint32_t RepetitionCounter; TIM_COUNTERMODE_CENTERALIGNED1
Cuenta desde 0 hasta el periodo -1, generando un evento de desbordamiento, luego
} TIM_Base_InitTypeDef; cuenta de forma descendente desde el periodo hasta 1 generando otro desbordamiento
TIM_COUNTERMODE_CENTERALIGNED2
Igual que el anterior, con la diferencia de que la bandera de interrupción de salida del
modo comparador, se activa cuando el conteo va de manera ascendente
TIM_COUNTERMODE_CENTERALIGNED3
Igual que el anterior, con la diferencia de que la bandera de interrupción de salida del
modo comparador, se activa cuando el conteo va de manera ascendente y descendente
TEMPORIZADOR BÁSICO

La estructura de configuración es: Define el valor máximo del contador del temporizador antes de
que se reinicie el conteo, este puede asumir un valor desde 1
typedef struct hasta 65535
{
uint32_t Prescaler; Indica la relación entre la frecuencia del reloj interno y el reloj de
uint32_t CounterMode; muestreo utilizado por los filtros digitales Rx y Tx. Estas
relaciones de campo pueden ser:
uint32_t Period;
TIM_CLOCKDIVISION_DIV1
uint32_t ClockDivision; Realiza una muestra de la señal de entrada en los pines
uint32_t RepetitionCounter; ETRx y TIx
TIM_CLOCKDIVISION_DIV2
} TIM_Base_InitTypeDef; Realiza 2 muestras de la señal de entrada en los pines
ETRx y TIx
TIM_CLOCKDIVISION_DIV4
Realiza 4 muestras de la señal de entrada en los pines
ETRx y TIx
TEMPORIZADOR BÁSICO

La estructura de configuración es: Sirve para darle seguimiento a las veces que el temporizador se
desborda ya sea de manera ascendente o descendente.
typedef struct
{
uint32_t Prescaler;

uint32_t CounterMode;

uint32_t Period;

uint32_t ClockDivision;

uint32_t RepetitionCounter;

} TIM_Base_InitTypeDef;
TEMPORIZADOR BÁSICO
Los valores numéricos de los campos Prescaler y
Period determinan la frecuencia del temporizador,
es decir, el tiempo que tardara en desbordarse.
Estos valores se pueden definir de las siguientes
formulas: 𝐹𝐶
𝐹𝑇 =
𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1
𝑃𝑒𝑟𝑖𝑜𝑑 + 1
𝑇=
𝐹𝑇
𝐹𝐶
Actualización del Evento= 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟+1 𝑃𝑒𝑟𝑖𝑜𝑑+1

𝐹𝑇 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑡𝑖𝑚𝑒𝑟


𝐹𝑐 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑚ó𝑑𝑢𝑙𝑜 𝑑𝑒𝑙 𝑟𝑒𝑙𝑜𝑗
𝑇 = 𝑒𝑠 𝑒𝑙 𝑡𝑖𝑒𝑚𝑝𝑜 𝑞𝑢𝑒 𝑡𝑎𝑟𝑑𝑎 𝑒𝑛 𝑜𝑐𝑢𝑟𝑟𝑖𝑟 𝑒𝑙 𝑒𝑣𝑒𝑛𝑡𝑜
TEMPORIZADOR BÁSICO

La interrupción debe ser inicializada por el usuario. Por tanto, luego de generar el código
con CubeMX, es debe agregar la función:

HAL_TIM_Base_Start_IT(&htimX);

Donde &htimX representa el timer que se usará, por ejemplo:


&htim1, &htim2, &htim3, etc.
TEMPORIZADOR BÁSICO EJEMPLO 1

Escribir un programa donde el temporizador


básico este configurado para prender y apagar un
led cada 0,5 s
TEMPORIZADOR BÁSICO EJEMPLO 1
𝐹𝑇 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑡𝑖𝑚𝑒𝑟 𝐹𝑐 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑟𝑒𝑙𝑜𝑗 𝑇 = 𝑒𝑠 𝑒𝑙 𝑡𝑖𝑒𝑚𝑝𝑜 𝑞𝑢𝑒 𝑡𝑎𝑟𝑑𝑎 𝑒𝑛 𝑜𝑐𝑢𝑟𝑟𝑖𝑟 𝑒𝑙 𝑒𝑣𝑒𝑛𝑡𝑜

𝐹𝐶 𝑃𝑒𝑟𝑖𝑜𝑑 + 1 𝐹𝐶
𝐹𝑇 = 𝑇= 𝐹𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 =
𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝐹𝑇 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝑃𝑒𝑟𝑖𝑜𝑑 + 1

Calculamos los valores del Period y Prescaler:


Estableceremos que la frecuencia del reloj del microcontrolador sea de 8MHz (FC)
Estableceremos que la frecuencia del timer se de 1KHz.(FT)
Sabemos que el tiempo que tarda en ocurrir un evento es de 0,5s (T)

Por tanto:
𝑃𝑒𝑟𝑖𝑜𝑑 + 1 8000000
0,5 = 𝐹𝑇 = = 1000
1000 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1

𝑃𝑒𝑟𝑖𝑜𝑑 = 499 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 = 7999


TEMPORIZADOR BÁSICO EJEMPLO 1
Creamos un nuevo proyecto dentro de STM32CubeMX accionando sobre el icono correspondiente y seleccionando
nuestro Microcontrolador STM32F103C8T6

Los Timers cuentan con canales que


permiten tener múltiples señales
generadas por un solo Timer. El
Timer 13 (TIM3) tiene 4 canales con
la capacidad de ser utilizados como
comparadores, modos de captura o
como PWM.

Para comenzar a trabajar con el


Timer seleccionado se debe indicar
la fuente del reloj interna.
Una vez seleccionado el Timer, el
nombre cambia a color verde,
indicando que está en uso.
TEMPORIZADOR BÁSICO EJEMPLO 1
En la configuración del reloj del sistema y de los módulos de Hardware, utilizaremos el de 8MHz.
TEMPORIZADOR BÁSICO EJEMPLO 1
Accionando en el botón para el Timer3 aparece una ventana , donde configuramos los valores del
Prescaler y Period que hemos calculado de 7999 y 499 respectivamente
TEMPORIZADOR BÁSICO EJEMPLO 1

Usamos interrupciones para saber cuando ha ocurrido un


desborde. Habilitaremos las interrupciones globales; para
no tener que hacer encuestas para saber si ha terminado
de contar. Para nos dirigirnos a la pestaña “NVIC Settings”
y dentro de la pestaña de configuración del Timer 3 y
habilitar dicha casilla
TEMPORIZADOR BÁSICO EJEMPLO 1

Generamos el código base

SW4STM2
TEMPORIZADOR BÁSICO EJEMPLO 1
#include "main.h" static void MX_TIM3_Init(void)
#include "stm32f1xx_hal.h" {
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_HandleTypeDef htim3; TIM_MasterConfigTypeDef sMasterConfig;
htim3.Instance = TIM3;
void SystemClock_Config(void); htim3.Init.Prescaler = 7999;
static void MX_GPIO_Init(void); htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
static void MX_TIM3_Init(void); htim3.Init.Period = 499;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
int main(void) if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{ {
_Error_Handler(__FILE__, __LINE__);
HAL_Init(); }
SystemClock_Config(); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
MX_GPIO_Init(); if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
MX_TIM3_Init(); {
HAL_TIM_Base_Start_IT(&htim3); _Error_Handler(__FILE__, __LINE__);
}
while (1) sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
{ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
} {
_Error_Handler(__FILE__, __LINE__);
} }
}
TEMPORIZADOR BÁSICO EJEMPLO 1

static void MX_GPIO_Init(void) void TIM3_IRQHandler(void)


{ {
HAL_TIM_IRQHandler(&htim3);
GPIO_InitTypeDef GPIO_InitStruct; }

/* GPIO Ports Clock Enable */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)


__HAL_RCC_GPIOC_CLK_ENABLE(); {
__HAL_RCC_GPIOD_CLK_ENABLE(); if(htim->Instance==TIM3)
{
/*Configure GPIO pin Output Level */ HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); }
}
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}
TEMPORIZADOR BÁSICO EJEMPLO 2

Realizar un programa que rote a la izquierda el encendido de uno


de ocho LEDs conectados a un puerto configurado como salida. El
salto de la rotación de LED a LED debe ser en primera instancia
cada 0,0625 segundos durante 4 segundos y luego de 0,25
segundos durante los siguientes 4 segundos.
TEMPORIZADOR BÁSICO

Funciones adicionales
● Para detener el timer:
HAL_TIM_Base_Stop_IT(&htimx)
● Cambiar prescaler:
__HAL_TIM_SET_PRESCALER(&htimx, val_prescaler)
● Cambiar periodo:
__HAL_TIM_SET_AUTORELOAD(&htimx, val_periodo)
Cambiar el contador del timer:
● __HAL_TIM_SET_COUNTER(&htimx, val_contador)
TEMPORIZADOR CON FUENTE EXTERNA
Un temporizador puede recibir estímulos de una fuente externa a uno de los pines asociados
con los TIMERS.

La estructura de configuración es: Indica la fuente de la señal del reloj usada para alimentar el
typedef struct temporizador, y puede asumir cualquiera de los siguientes
{ valores:
uint32_t ClockSource;
uint32_t ClockPolarity; TIM_CLOCKSOURCE_INTERNAL
uint32_t ClockPrescaler; El temporizador esta polarizado con el reloj del bus APBx
uint32_t ClockFilter; TIM_CLOCKSOURCE_ETRMODE1
} TIM_ClockConfigTypeDef; Configurado como modo1 de reloj externo, el temporizador esta
polarizado por una señal interna o externa conectada a los pines
ITR0, ITR1, ITR2, ITR3, TI1FP1 o TI2FP2
TIM_CLOCKSOURCE_ETRMODE2
Configurado como modo 2 de reloj externo, y esta polarizado por
una fuente externa que se encuentra conectado al pin ETR
TEMPORIZADOR CON FUENTE EXTERNA
Un temporizador puede recibir estímulos de una fuente externa a uno de los pines asociados
con los TIMERS.

La estructura de configuración es: Indica la polaridad de la señal del reloj usada para alimentar el
typedef struct temporizador, puede asignarse cualquiera de los siguientes
{ valores:
uint32_t ClockSource;
uint32_t ClockPolarity; TIM_CLOCKPOLARITY_INVERTED
uint32_t ClockPrescaler; Polarity for ETRx clock sources
uint32_t ClockFilter; TIM_CLOCKPOLARITY_NONINVERTED
} TIM_ClockConfigTypeDef; Polarity for ETRx clock sources
TIM_CLOCKPOLARITY_RISING
Polarity for TIx clock sources
TIM_CLOCKPOLARITY_FALLING
Polarity for TIx clock sources
TIM_CLOCKPOLARITY_BOTHEDGE
Polarity for TIx clock sources
TEMPORIZADOR CON FUENTE EXTERNA
Un temporizador puede recibir estímulos de una fuente externa a uno de los pines asociados
con los TIMERS.

La estructura de configuración es: Especifica el prescaler de la fuente externa del reloj, puede
typedef struct asignarse cualquiera de los siguientes valores:
{
uint32_t ClockSource;
uint32_t ClockPolarity; TIM_CLOCKPRESCALER_DIV1 No prescaler is used
uint32_t ClockPrescaler; TIM_CLOCKPRESCALER_DIV2 Prescaler for External ETR
uint32_t ClockFilter; Clock: Capture performed once every 2 events.
} TIM_ClockConfigTypeDef; TIM_CLOCKPRESCALER_DIV4 Prescaler for External ETR
Clock: Capture performed once every 4 events.
TIM_CLOCKPRESCALER_DIV8 Prescaler for External ETR
Clock: Capture performed once every 8 events.
TEMPORIZADOR CON FUENTE EXTERNA
Un temporizador puede recibir estímulos de una fuente externa a uno de los pines asociados
con los TIMERS.

La estructura de configuración es: Este campo de 4 bits de valor numérico, define la frecuencia
typedef struct usada para el muestreo de la señal del reloj externo y el ancho
{ del filtro digital aplicada a este:
uint32_t ClockSource;
uint32_t ClockPolarity;
uint32_t ClockPrescaler;
uint32_t ClockFilter;

} TIM_ClockConfigTypeDef;
TEMPORIZADOR CON FUENTE EXTERNA

Escribir un programa donde el temporizador este configurado para prender y


apagar un led cada 0,5 s, utilizando el MOC (MASTER CLOCK OUTPUT) el
cual es una línea de reloj que puede funcionar como una salida a una
frecuencia de 8MHz.
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
𝐹𝑇 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑡𝑖𝑚𝑒𝑟 𝐹𝑐 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑟𝑒𝑙𝑜𝑗 𝑇 = 𝑒𝑠 𝑒𝑙 𝑡𝑖𝑒𝑚𝑝𝑜 𝑞𝑢𝑒 𝑡𝑎𝑟𝑑𝑎 𝑒𝑛 𝑜𝑐𝑢𝑟𝑟𝑖𝑟 𝑒𝑙 𝑒𝑣𝑒𝑛𝑡𝑜

𝐹𝐶 𝑃𝑒𝑟𝑖𝑜𝑑 + 1 𝐹𝐶
𝐹𝑇 = 𝑇= 𝐹𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 =
𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝐹𝑇 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝑃𝑒𝑟𝑖𝑜𝑑 + 1

Calculamos los valores del Period y Prescaler:


Estableceremos que la frecuencia del reloj del microcontrolador sea de 8MHz (FC)
Estableceremos que la frecuencia del timer se de 1KHz.(FT)
Sabemos que el tiempo que tarda en ocurrir un evento es de 0,5s (T)

Por tanto:
𝑃𝑒𝑟𝑖𝑜𝑑 + 1 8000000
0,5 = 𝐹𝑇 = = 1000
1000 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1

𝑃𝑒𝑟𝑖𝑜𝑑 = 499 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 = 7999


TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
Creamos un nuevo proyecto dentro de STM32CubeMX accionando sobre el icono correspondiente y seleccionando
nuestro Microcontrolador STM32F103C8T6

Para comenzar a trabajar con el


Timer seleccionado se debe indicar
la fuente del reloj externa.
Una vez seleccionado el Timer, el
nombre cambia a color verde,
indicando que está en uso.
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
En la configuración del reloj del sistema y de los
módulos de Hardware, utilizaremos el de 8MHz.
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
Accionando en el botón para el Timer2 aparece una ventana , donde configuramos los valores del
Prescaler y Period que hemos calculado de 7999 y 499 respectivamente
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
Usamos interrupciones para saber cuando ha ocurrido un desborde. Habilitaremos las interrupciones globales; para no
tener que hacer encuestas para saber si ha terminado de contar. Para eso nos dirigirnos a la pestaña “NVIC Settings” y
dentro de la pestaña de configuración del Timer 2 y habilitamos dicha casilla

Usamos interrupciones para saber cuando ha ocurrido un


desborde. Habilitaremos las interrupciones globales; para
no tener que hacer encuestas para saber si ha terminado
de contar. Para nos dirigirnos a la pestaña “NVIC Settings”
y dentro de la pestaña de configuración del Timer 2 y
habilitar dicha casilla

Generamos el código base


TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
#include "main.h" void SystemClock_Config(void)
#include "stm32f1xx_hal.h" {

TIM_HandleTypeDef htim2; RCC_OscInitTypeDef RCC_OscInitStruct;


RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Initializes the CPU, AHB and APB busses clocks */
void SystemClock_Config(void);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
static void MX_GPIO_Init(void); RCC_OscInitStruct.HSIState = RCC_HSI_ON;
static void MX_TIM2_Init(void); RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
int main(void) {
{ _Error_Handler(__FILE__, __LINE__);
}
HAL_Init(); /**Initializes the CPU, AHB and APB busses clocks*/
SystemClock_Config(); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
MX_GPIO_Init();
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
MX_TIM2_Init();
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
HAL_TIM_Base_Start_IT(&htim2); RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

while (1) HAL_RCC_MCOConfig(RCC_MCO, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);


{
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
} HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
} HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
static void MX_TIM2_Init(void)
{

TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;

htim2.Instance = TIM2;
htim2.Init.Prescaler = 7999;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 499;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 0;

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

}
TEMPORIZADOR CON FUENTE EXTERNA - EJEMPLO 3
static void MX_GPIO_Init(void)
{ void TIM2_IRQHandler(void)
GPIO_InitTypeDef GPIO_InitStruct; {
HAL_TIM_IRQHandler(&htim2);
/* GPIO Ports Clock Enable */ }
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE(); void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/*Configure GPIO pin Output Level */ if(htim->Instance==TIM2)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); {
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
/*Configure GPIO pin : PC13 */ }
GPIO_InitStruct.Pin = GPIO_PIN_13; }
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : PA8 */


GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO

Escribir un programa que aumente y reduzca la intensidad de un led


conectado a una salida PWM.

El temporizador será configurado para generar una salida PWM con un


periodo de 1ms, y el ciclo de trabajo ira incrementándose hasta llegar a ser el
100%, luego se decrementará hasta llegar cerca del 0%.

Se realizaran todos los cálculos tomando en cuenta que la frecuencia del reloj
principal será de 8MHz (HSE).
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO

CICLO DE
TRABAJO
PERIODO: Es fijo
CICLO DE TRABAJO: Es variable

PERIODO
La cantidad de pasos que le
tomará al PWM llegar al
100% de su ciclo de trabajo
𝐹𝐶 𝑃𝑒𝑟𝑖𝑜𝑑 + 1
𝐹𝑇 = 𝑇=
𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝐹𝑇

𝐹𝑇 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑡𝑖𝑚𝑒𝑟 𝐹𝑐 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑟𝑒𝑙𝑜𝑗 𝑇 = 𝑒𝑠 𝑒𝑙 𝑝𝑒𝑟𝑖𝑜𝑑𝑜 𝑑𝑒 𝑙𝑎 𝑃𝑊𝑀


TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
𝐹𝑇 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑡𝑖𝑚𝑒𝑟 𝐹𝑐 = 𝑒𝑠 𝑙𝑎 𝑓𝑟𝑒𝑐𝑢𝑒𝑛𝑐𝑖𝑎 𝑑𝑒𝑙 𝑟𝑒𝑙𝑜𝑗 𝑇 = 𝑒𝑠 𝑒𝑙 𝑝𝑒𝑟𝑖𝑜𝑑𝑜 𝑑𝑒 𝑙𝑎 𝑃𝑊𝑀

𝐹𝐶 𝑃𝑒𝑟𝑖𝑜𝑑 + 1
𝐹𝑇 = 𝑇=
𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1 𝐹𝑇

Calculamos los valores del Period y Prescaler:


Estableceremos que la frecuencia del reloj del microcontrolador sea de 8MHz (FC)
Estableceremos que la frecuencia del timer se de 1MHz.(FT)
Sabemos que el periodo de la PWM es 1ms(T)

Por tanto:
𝑃𝑒𝑟𝑖𝑜𝑑 + 1 8000000
0,001 = Son 999 los de pasos que le 𝐹𝑇 = = 1000000
1000000 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 + 1
tomará al PWM llegar al
𝑃𝑒𝑟𝑖𝑜𝑑 = 999 100% de su ciclo de trabajo 𝑃𝑟𝑒𝑠𝑐𝑎𝑙𝑒𝑟 = 7
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
Creamos un nuevo proyecto dentro de STM32CubeMX accionando sobre el icono correspondiente y seleccionando
nuestro Microcontrolador STM32F103C8T6

Para comenzar a trabajar con el


Timer seleccionado se debe indicar
la fuente del reloj interna.
Una vez seleccionado el Timer, el
nombre cambia a color verde,
indicando que está en uso.
Al Habilitar el canal 1 como PWM,
el pin PA8 se configura para la
salida de PWM
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
En la configuración del reloj del sistema y de los módulos de Hardware, utilizaremos el de 8MHz.
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
Accionando en el botón para el Timer2 aparece una ventana , donde configuramos los valores del
Prescaler y Period que hemos calculado de 7 y 999 respectivamente
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
Se configura el comparador de salida en modo
PWM.

No se indica el pulso, pues este será modificado en


un bucle permanente.

Deshabilitamos la modalidad rápida.

Se configura la polaridad de la señal en estado alto


cuando exista una igualdad.

Pulse: puede tomar un valor desde 1 hasta el valor del


couter period que hemos calculado (en este caso desde
0 hasta 999).
Pulse define el CICLO DE TRABAJO. Para nuestro
ejemplo, si deseamos un Ciclo de Trabajo del 50%, el
valor de Pulse debe ser de: 999x0,50=499,5
redondeándolo será 500.
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
Generamos el código base
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
#include "main.h"
#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

void user_pwm_setvalue(uint16_t);
uint8_t valor_pwm=0;
uint8_t paso=0;
int main(void) Antes de poder controlar nuestro PWM debemos de
{ inicializarlo con la función Hal_TIM_PWM_Start(); la cual
HAL_Init();
SystemClock_Config();
requiere dos parámetros. El primer parámetro es el Timer
a usar y el segundo es el canal del Timer que controlará el
MX_GPIO_Init(); GPIO.
MX_TIM1_Init();

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
while (1)
static void MX_GPIO_Init(void)
{
{
HAL_Delay(100);
__HAL_RCC_GPIOD_CLK_ENABLE();
if(valor_pwm == 0) paso = 50;
__HAL_RCC_GPIOA_CLK_ENABLE();
if(valor_pwm == 1000) paso = -50;
valor_pwm += paso;
}
pwm_por_usuario(valor_pwm);
}
} // fin del main(void)

void pwm_por_usuario(uint16_t valor)


{
TIM_OC_InitTypeDef sConfigOC;
Inicializamos la función
sConfigOC.OCMode = TIM_OCMODE_PWM1; Hal_TIM_PWM_Start();
sConfigOC.Pulse = valor;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; Se realiza la inicialización del
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); comparador de salida
} relacionando al canal 1del
temporizador 1
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
static void MX_TIM1_Init(void) sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
{ if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
TIM_ClockConfigTypeDef sClockSourceConfig; {
TIM_MasterConfigTypeDef sMasterConfig; _Error_Handler(__FILE__, __LINE__);
TIM_OC_InitTypeDef sConfigOC; }
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
htim1.Instance = TIM1; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
htim1.Init.Prescaler = 7; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
htim1.Init.Period = 999; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
htim1.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; {
if (HAL_TIM_Base_Init(&htim1) != HAL_OK) _Error_Handler(__FILE__, __LINE__);
{ }
_Error_Handler(__FILE__, __LINE__); sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
} sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) sBreakDeadTimeConfig.DeadTime = 0;
{ sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
_Error_Handler(__FILE__, __LINE__); sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
} sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{ {
_Error_Handler(__FILE__, __LINE__); _Error_Handler(__FILE__, __LINE__);
} }
HAL_TIM_MspPostInit(&htim1);
}
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
#include "main.h"
#include "stm32f1xx_hal.h"

TIM_HandleTypeDef htim1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM1_Init(void);
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

int main(void)
{
HAL_Init();
SystemClock_Config(); Antes de poder controlar nuestro PWM debemos de
inicializarlo con la función Hal_TIM_PWM_Start(); la cual
MX_GPIO_Init();
MX_TIM1_Init();
requiere dos parámetros. El primer parámetro es el Timer
a usar y el segundo es el canal del Timer que controlará el
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); GPIO.
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
while (1)
{ static void MX_GPIO_Init(void)
for (int pwm=0;pwm<=999;pwm++) // {
{ __HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwm); // __HAL_RCC_GPIOA_CLK_ENABLE();
HAL_Delay(10);
} }
HAL_Delay(200); //
for (int pwm=999;pwm>=0;pwm--) //
{
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwm);
HAL_Delay(10);
}
La función que se encarga de controlar el GPIO mapeado por el
HAL_Delay(200); //
} Microcontrolador es __Hal_TIM_SET_COMPARE(); Esta función
} // fin del main(void) recibe tres parámetros: el Timer a usar, el canal y el número de pasos.
Este último valor es el valor de Pulse del Timer1, por consiguiente
únicamente podemos colocar valores entre 0 y 999, es decir, el 100%
de nuestro ciclo de trabajo es 999. Si deseamos que el ciclo de trabajo
se encuentre a la mitad (50%) debemos de colocar 499,5 como tercer
parámetro, redondeándolo da 500.
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
static void MX_TIM1_Init(void) sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
{ if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
TIM_ClockConfigTypeDef sClockSourceConfig; {
TIM_MasterConfigTypeDef sMasterConfig; _Error_Handler(__FILE__, __LINE__);
TIM_OC_InitTypeDef sConfigOC; }
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig; sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
htim1.Instance = TIM1; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
htim1.Init.Prescaler = 7; sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
htim1.Init.Period = 999; sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
htim1.Init.RepetitionCounter = 0; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; {
if (HAL_TIM_Base_Init(&htim1) != HAL_OK) _Error_Handler(__FILE__, __LINE__);
{ }
_Error_Handler(__FILE__, __LINE__); sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
} sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) sBreakDeadTimeConfig.DeadTime = 0;
{ sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
_Error_Handler(__FILE__, __LINE__); sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
} sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK) if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{ {
_Error_Handler(__FILE__, __LINE__); _Error_Handler(__FILE__, __LINE__);
} }
HAL_TIM_MspPostInit(&htim1);
}
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
Diseñar un programa que genere una señal PWM con un periodo de 1ms, con un ciclo de trabajo que varié cuando se
presiona un pulsador. Inicialmente el ciclo de trabajo debe ser del 30%. Si se presiona el pulsador el ciclo de trabajo
cambiará al 70%. Si se vuelve a presionar el pulsador el ciclo de trabajo regresará a ser de 30%.
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO
TEMPORIZADOR COMO MODULADOR POR ANCHO DE PULSO

También podría gustarte

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy