Actividad 5. STM32: RCC y timer

Temas

  • STM TIMERS
  • RCC

Precauciones

  • Antes de conectar la tarjeta de desarrollo y sus pines a un circuito externo (especialmente señales que entran a la tarjeta de desarrollo) la tarjeta de desarrollo debe haber sido programada al menos una vez inicialmente antes de ser conectado a dicho circuito.

Instrucciones generales

  1. Lea completamente todos los pasos de la guía de esta actividad
  2. Anote, responda y agregue al reporte todas las preguntas e instrucciones que se realicen en la guía. Dichas preguntas e instrucciones se pueden denotar al estar enumeradas con el siguiente formato: “1) Anote el puerto asignado a su dispositivo Arduino”
  3. Debe realizar una descripción de lo logrado a lo largo de la actividad, incluyendo las dificultades que se presentaron. Una bitácora de lo sucedido es lo mejor. (Anote no solo lo que usted ejecutó sino también el resultado de lo que ejecuta)
  4. El reporte debe ser entregado mediante correo electrónico al asistente con copia al profesor del curso mediante correo electrónico. Debe utilizar formato PDF.
  5. El correo electrónico del reporte debe llevar el siguiente formato en el “subject”: “IE0624 - Reporte N”, donde N es el número de la actividad realizada.

Evaluación

El reporte debe incluir las siguientes secciones (se incluye el porcentaje de nota de cada sección)

  1. Portada (curso, semestre, año, fecha, número y nombre de práctica, integrantes). 2%
  2. Bitácora de trabajo describiendo el resultado de todos los pasos seguidos de la guía incluyendo dificultades y/o situaciones inesperadas. 30%
  3. Capturas o fotografías de puntos importantes realizadas durante la actividad (el circuito ensamblado, resultados observables en el osciloscopio, etc) 20%
  4. Respuestas al cuestionario de la guía. 20% (deben estar claramente identificadas con el número de pregunta, sin confundirse con otra numeración en el reporte)
  5. Todo el código fuente de todos los programas utilizados a lo largo de la actividad. Debe agregar al inicio del código una descripción sobre dicho código (a qué parte de la práctica corresponde, la función que cumple dicho código). 20%
  6. Referencias utilizadas en caso de acceder a alguna fuente de información de Internet o bibliográfica durante la realización de la actividad. 8%

Guía de laboratorio

Parte 1. STM32 basic setup

  • El objetivo de esta parte es obtener un programa base con la configuración más elevada de velocidad para el stm. Queremos llegar a la velocidad máxima posible con el STM32f303.
  • Cambie al directorio de los ejemplos del stm32f3 y copie el Makefile del ejemplo miniblink a un nuevo directorio:
cd ~/local/src/libopencm3-examples/examples/stm32/f3/stm32f3-discovery/
mkdir timer
cp miniblink/Makefile timer
cd timer
  • Edite el contenido del Makefile del nuevo ejemplo timer. Cambien la línea:
BINARY = miniblink

por la linea:

BINARY = timer
  • Cree un nuevo archivo llamado timer.c con el siguiente contenido:
  /*
   * Copyright (C) 2013 ARCOS-Lab Universidad de Costa Rica
   * Author: Federico Ruiz Ugalde <memeruiz@gmail.com>
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
   */
 
  #include <libopencm3/stm32/rcc.h>
  #include <libopencm3/stm32/gpio.h>
  #include <libopencm3/stm32/timer.h>
  #include "timer.h"
  #include <limits.h>
  #include <stdbool.h>
 
  void leds_init(void) {
  	rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_IOPEEN);
  	gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO8| GPIO9| GPIO10| GPIO11| GPIO12| GPIO13| GPIO14| GPIO15);
  }
 
  void system_init(void) {
    rcc_clock_setup_hsi(&rcc_hsi_configs[RCC_CLOCK_HSI_64MHZ]);
    leds_init();
  }
 
  int main(void)
  {
    system_init();
    int i;
 
    while (1){
      gpio_toggle(GPIOE, GPIO12);	/* LED on/off */
      for (i = 0; i < 2000000; i++) /* Wait a bit. */
        __asm__("nop");
    }
  }
  • recuerde crear el archivo timer.h con las definiciones de las funciones necesarias.
  • Compile y corra dicho program. 1) Describa lo que sucede
  • Comente la línea:
  rcc_clock_setup_hsi(&rcc_hsi_8mhz[RCC_CLOCK_64MHZ]);
  • Compile nuevamente. 2) Describa lo que sucede. Es distinto? En qué forma?

Parte 2. STM32 TIMER

  • Modifique el código anterior para soportar el TIMER del STM. Agregue las siguientes dos funciones y los defines al inicio del programa:
  //pwm-related timer configuration
  #define SYSFREQ     64000000 //168MHz
  #define PWMFREQ        16000  //32000
  #define PWMFREQ_F       ((float )(PWMFREQ)) //32000.0f
  #define PRESCALE        1                           //freq_CK_CNT=freq_CK_PSC/(PSC[15:0]+1)
  #define PWM_PERIOD_ARR  (SYSFREQ/( PWMFREQ*(PRESCALE+1) ))
 
  float duty=0.5;
 
  void tim_init(void)
  {
    /* Enable TIM1 clock. and Port E clock (for outputs) */
    rcc_periph_clock_enable(RCC_TIM1);
    rcc_periph_clock_enable(RCC_GPIOE);
 
    //Set TIM1 channel (and complementary) output to alternate function push-pull'.
    //f4 TIM1=> GIO9: CH1, GPIO11: CH2, GPIO13: CH3
    //f4 TIM1=> GIO8: CH1N, GPIO10: CH2N, GPIO12: CH3N
    gpio_mode_setup(GPIOE, GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO9);
    gpio_set_af(GPIOE, GPIO_AF2, GPIO9);
 
    /* Reset TIM1 peripheral. */
    //timer_reset(TIM1);
    rcc_periph_reset_pulse(RST_TIM1);
 
    /* Timer global mode:
     * - No divider
     * - Alignment edge
     * - Direction up
     */
    timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT, //For dead time and filter sampling, not important for now.
                   TIM_CR1_CMS_CENTER_3,  //TIM_CR1_CMS_EDGE
                   //TIM_CR1_CMS_CENTER_1
                   //TIM_CR1_CMS_CENTER_2
                   //TIM_CR1_CMS_CENTER_3 la frequencia del pwm se divide a la mitad.
                   TIM_CR1_DIR_UP);
 
    timer_set_prescaler(TIM1, PRESCALE); //1 = disabled (max speed)
    timer_set_repetition_counter(TIM1, 0); //disabled
    timer_enable_preload(TIM1);
    timer_continuous_mode(TIM1);
 
    /* Period (32kHz). */
    timer_set_period(TIM1, PWM_PERIOD_ARR); //ARR (value compared against main counter to reload counter aka: period of counter)
 
    /* Configure break and deadtime. */
    timer_set_enabled_off_state_in_idle_mode(TIM1);
    timer_set_enabled_off_state_in_run_mode(TIM1);
    timer_disable_break(TIM1);
    timer_set_break_polarity_high(TIM1);
    timer_disable_break_automatic_output(TIM1);
    timer_set_break_lock(TIM1, TIM_BDTR_LOCK_OFF);
 
    /* Disable outputs. */
    timer_disable_oc_output(TIM1, TIM_OC1);
    timer_disable_oc_output(TIM1, TIM_OC1N);
    timer_disable_oc_output(TIM1, TIM_OC2);
    timer_disable_oc_output(TIM1, TIM_OC2N);
    timer_disable_oc_output(TIM1, TIM_OC3);
    timer_disable_oc_output(TIM1, TIM_OC3N);
 
    /* -- OC1 and OC1N configuration -- */
    /* Configure global mode of line 1. */
    timer_enable_oc_preload(TIM1, TIM_OC1);
    timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1);
    /* Configure OC1. */
    timer_set_oc_polarity_high(TIM1, TIM_OC1);
    timer_set_oc_idle_state_unset(TIM1, TIM_OC1); //When idle (braked) put 0 on output
    /* Configure OC1N. */
    timer_set_oc_polarity_high(TIM1, TIM_OC1N);
    timer_set_oc_idle_state_unset(TIM1, TIM_OC1N);
    /* Set the capture compare value for OC1. */
    timer_set_oc_value(TIM1, TIM_OC1, PWM_PERIOD_ARR*duty);//duty_cycle*pwm_period_ARR);
 
    /* ARR reload enable. */
    timer_enable_preload(TIM1);
 
    /*
     * Enable preload of complementary channel configurations and
     * update on COM event.
     */
    timer_disable_preload_complementry_enable_bits(TIM1);
 
    /* Enable outputs in the break subsystem. */
    timer_enable_break_main_output(TIM1);
 
    /* Generate update event to reload all registers before starting*/
    timer_generate_event(TIM1, TIM_EGR_UG);
 
    timer_set_oc_mode(TIM1, TIM_OC1, TIM_OCM_PWM1);
    timer_enable_oc_output(TIM1, TIM_OC1 );
    timer_disable_oc_output (TIM1, TIM_OC1N);
 
    /* Counter enable. */
    timer_enable_counter(TIM1);
 
    //enable capture compare interrupt
    timer_enable_update_event(TIM1);
 
    timer_enable_irq(TIM1, TIM_DIER_UIE);
    nvic_enable_irq(NVIC_TIM1_UP_TIM16_IRQ);
  }
 
  void tim1_up_tim16_isr(void) {
    // Clear the update interrupt flag
    timer_clear_flag(TIM1,  TIM_SR_UIF);
    gpio_toggle(GPIOE, GPIO12);	/* LED on/off */
  }
  • Asegúrese que el tim_init() es ejecutado después del system_init
  • 3) Observe y describa el comportamiento de los LEDs. (Utilice el Osciloscopio)
  • Modifique el programa para que el LED GPIOE9 tenga in ciclo de trabajo de 10%

Parte 2. Servo

  • Modifique el programa para que la señal sea compatible con un servo. Igualmente como se realizó en la actividad 3, desde el ciclo principal del programa (while) cambie el valor del PWM de tal forma que el servo se mueva del máximo al mínimo de posición de manera intermitente cada 2 segundos. Observe el servo moverse del máximo al mínimo de posición. 4) Capture ambos casos con el osciloscopio.

Opcional

En esta parte opcional se logrará reproducir una pieza simple con el STM. Necesita el STM32F3 Discovery, un buzzer, y una resistencia para limitar la corriente por el buzzer. O) Cuál pieza es esta? haga un video

  • Cree la función delay, que toma como entrada un entero y hace que el STM se espere esa cantidad de tiempo.
  • Cree la función tone, que se encarga de crear una señal cuadrada en un pin específico a una frecuencia dada y por un tiempo específico.
  • Cree l función song, que contiene ls instrucciones para reproducir una pieza musical simple.
  • A continuación se muestra las definiciones de dichas funciones:
  /* 
   * delay(time_ms)
   * Waits a certain amount of mili seconds
   * time_ms: integer with the miliseconds to wait
   *
   * Example: delay(100);
   * Will wait for 100 miliseconds
   */
  void delay(uint32_t time_ms);
 
  /*
   * tone(port, pin, frequency, duration)
   * Sends a square signal to the port/pin at the specified frequency, for duration miliseconds
   * port: Port at which the signal must be sent
   * pin: The pin that should be used
   * frequency: Frequency in Hz of the desired signal
   * duration: duration of the tone in miliseconds
   *
   * Example: tone(GPIOE, GPIO09, 440, 100);
   * Will generate a sqare signal at pin E9, for 100 milisceonds at 440Hz
   */
  void tone(uint32_t gpioport,uint16_t gpios, uint32_t frequency, uint32_t duration);
 
  /*
   * song()
   * Reproduces a song
   *
   * Eample: song()
   * Reproduces a song
   */
  void song(void); 
  • También se incluye la implementación de la función song:
void song(void) {
  tone(9,660,100);
  delay(150);
  tone(9,660,100);
  delay(300);
  tone(9,660,100);
  delay(300);
  tone(9,510,100);
  delay(100);
  tone(9,660,100);
  delay(300);
  tone(9,770,100);
  delay(550);
  tone(9,380,100);
  delay(575);
 
  tone(9,510,100);
  delay(450);
  tone(9,380,100);
  delay(400);
  tone(9,320,100);
  delay(500);
  tone(9,440,100);
  delay(300);
  tone(9,480,80);
  delay(330);
  tone(9,450,100);
  delay(150);
  tone(9,430,100);
  delay(300);
  tone(9,380,100);
  delay(200);
  tone(9,660,80);
  delay(200);
  tone(9,760,50);
  delay(150);
  tone(9,860,100);
  delay(300);
  tone(9,700,80);
  delay(150);
  tone(9,760,50);
  delay(350);
  tone(9,660,80);
  delay(300);
  tone(9,520,80);
  delay(150);
  tone(9,580,80);
  delay(150);
  tone(9,480,80);
  delay(500);
 
  tone(9,510,100);
  delay(450);
  tone(9,380,100);
  delay(400);
  tone(9,320,100);
  delay(500);
  tone(9,440,100);
  delay(300);
  tone(9,480,80);
  delay(330);
  tone(9,450,100);
  delay(150);
  tone(9,430,100);
  delay(300);
  tone(9,380,100);
  delay(200);
  tone(9,660,80);
  delay(200);
  tone(9,760,50);
  delay(150);
  tone(9,860,100);
  delay(300);
  tone(9,700,80);
  delay(150);
  tone(9,760,50);
  delay(350);
  tone(9,660,80);
  delay(300);
  tone(9,520,80);
  delay(150);
  tone(9,580,80);
  delay(150);
  tone(9,480,80);
  delay(500);
 
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300);
 
  tone(9,650,150);
  delay(300);
  tone(9,380,100);
  delay(150);
  tone(9,430,100);
  delay(150);
 
  tone(9,500,100);
  delay(300);
  tone(9,430,100);
  delay(150);
  tone(9,500,100);
  delay(100);
  tone(9,570,100);
  delay(220);
 
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300);
 
  tone(9,650,200);
  delay(300);
 
  tone(9,1020,80);
  delay(300);
  tone(9,1020,80);
  delay(150);
  tone(9,1020,80);
  delay(300);
 
  tone(9,380,100);
  delay(300);
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300);
 
  tone(9,650,150);
  delay(300);
  tone(9,380,100);
  delay(150);
  tone(9,430,100);
  delay(150);
 
  tone(9,500,100);
  delay(300);
  tone(9,430,100);
  delay(150);
  tone(9,500,100);
  delay(100);
  tone(9,570,100);
  delay(420);
 
  tone(9,585,100);
  delay(450);
 
  tone(9,550,100);
  delay(420);
 
  tone(9,500,100);
  delay(360);
 
  tone(9,380,100);
  delay(300);
  tone(9,500,100);
  delay(300);
  tone(9,500,100);
  delay(150);
  tone(9,500,100);
  delay(300);
 
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300);
 
  tone(9,650,150);
  delay(300);
  tone(9,380,100);
  delay(150);
  tone(9,430,100);
  delay(150);
 
  tone(9,500,100);
  delay(300);
  tone(9,430,100);
  delay(150);
  tone(9,500,100);
  delay(100);
  tone(9,570,100);
  delay(220);
 
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300);
 
  tone(9,650,200);
  delay(300);
 
  tone(9,1020,80);
  delay(300);
  tone(9,1020,80);
  delay(150);
  tone(9,1020,80);
  delay(300);
 
  tone(9,380,100);
  delay(300);
  tone(9,500,100);
  delay(300);
 
  tone(9,760,100);
  delay(100);
  tone(9,720,100);
  delay(150);
  tone(9,680,100);
  delay(150);
  tone(9,620,150);
  delay(300); 
 
  tone(9,650,150);
  delay(300);
  tone(9,380,100);
  delay(150);
  tone(9,430,100);
  delay(150);
 
  tone(9,500,100);
  delay(300);
  tone(9,430,100);
  delay(150);
  tone(9,500,100);
  delay(100);
  tone(9,570,100);
  delay(420);
 
  tone(9,585,100);
  delay(450);
 
  tone(9,550,100);
  delay(420);
 
  tone(9,500,100);
  delay(360);
 
  tone(9,380,100);
  delay(300);
  tone(9,500,100);
  delay(300);
  tone(9,500,100);
  delay(150);
  tone(9,500,100);
  delay(300);
 
  tone(9,500,60);
  delay(150);
  tone(9,500,80);
  delay(300);
  tone(9,500,60);
  delay(350);
  tone(9,500,80);
  delay(150);
  tone(9,580,80);
  delay(350);
  tone(9,660,80);
  delay(150);
  tone(9,500,80);
  delay(300);
  tone(9,430,80);
  delay(150);
  tone(9,380,80);
  delay(600);
 
  tone(9,500,60);
  delay(150);
  tone(9,500,80);
  delay(300);
  tone(9,500,60);
  delay(350);
  tone(9,500,80);
  delay(150);
  tone(9,580,80);
  delay(150);
  tone(9,660,80);
  delay(550);
 
  tone(9,870,80);
  delay(325);
  tone(9,760,80);
  delay(600);
 
  tone(9,500,60);
  delay(150);
  tone(9,500,80);
  delay(300);
  tone(9,500,60);
  delay(350);
  tone(9,500,80);
  delay(150);
  tone(9,580,80);
  delay(350);
  tone(9,660,80);
  delay(150);
  tone(9,500,80);
  delay(300);
  tone(9,430,80);
  delay(150);
  tone(9,380,80);
  delay(600);
 
  tone(9,660,100);
  delay(150);
  tone(9,660,100);
  delay(300);
  tone(9,660,100);
  delay(300);
  tone(9,510,100);
  delay(100);
  tone(9,660,100);
  delay(300);
  tone(9,770,100);
  delay(550);
  tone(9,380,100);
  delay(575);
  }

Referencias

  • teaching/ie0624/actividad_stm32_timer_uart.txt
  • Last modified: 2018/11/05 14:39
  • by dgarcia