Table of Contents

Actividad 5. STM32: RCC y timer

Temas

Precauciones

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

cd ~/local/src/libopencm3-examples/examples/stm32/f3/stm32f3-discovery/
mkdir timer
cp miniblink/Makefile timer
cd timer
BINARY = miniblink

por la linea:

BINARY = timer
  /*
   * 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");
    }
  }
  rcc_clock_setup_hsi(&rcc_hsi_8mhz[RCC_CLOCK_64MHZ]);

Parte 2. STM32 TIMER

  //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 */
  }

Parte 2. Servo

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

  /* 
   * 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); 
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

http://libopencm3.org/

https://github.com/libopencm3/libopencm3/wiki/Datasheets

https://github.com/libopencm3/libopencm3-examples

https://github.com/arcoslab/open-coroco-legacy