/examples/stm32/f1/stm32-h103/timer/timer.c

https://github.com/kkmonster/libopencm3-examples · C · 167 lines · 87 code · 33 blank · 47 comment · 4 complexity · cae5fe4797b83bff2637ecffd74b5c0f MD5 · raw file

  1. /*
  2. * This file is part of the libopencm3 project.
  3. *
  4. * Copyright (C) 2011 Piotr Esden-Tempski <piotr@esden.net>
  5. *
  6. * This library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this library. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <libopencm3/stm32/rcc.h>
  20. #include <libopencm3/stm32/gpio.h>
  21. #include <libopencm3/stm32/timer.h>
  22. #include <libopencm3/cm3/nvic.h>
  23. #include <libopencm3/stm32/exti.h>
  24. uint16_t frequency_sequence[18] = {
  25. 1000,
  26. 500,
  27. 1000,
  28. 500,
  29. 1000,
  30. 500,
  31. 2000,
  32. 500,
  33. 2000,
  34. 500,
  35. 2000,
  36. 500,
  37. 1000,
  38. 500,
  39. 1000,
  40. 500,
  41. 1000,
  42. 5000,
  43. };
  44. int frequency_sel = 0;
  45. uint16_t compare_time;
  46. uint16_t new_time;
  47. uint16_t frequency;
  48. int debug = 0;
  49. static void clock_setup(void)
  50. {
  51. rcc_clock_setup_in_hse_8mhz_out_72mhz();
  52. }
  53. static void gpio_setup(void)
  54. {
  55. /* Enable GPIOC clock. */
  56. rcc_periph_clock_enable(RCC_GPIOC);
  57. /* Set GPIO12 (in GPIO port C) to 'output push-pull'. */
  58. gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ,
  59. GPIO_CNF_OUTPUT_PUSHPULL, GPIO12);
  60. gpio_set(GPIOC, GPIO12);
  61. }
  62. static void tim_setup(void)
  63. {
  64. /* Enable TIM2 clock. */
  65. rcc_periph_clock_enable(RCC_TIM2);
  66. /* Enable TIM2 interrupt. */
  67. nvic_enable_irq(NVIC_TIM2_IRQ);
  68. /* Reset TIM2 peripheral. */
  69. timer_reset(TIM2);
  70. /* Timer global mode:
  71. * - No divider
  72. * - Alignment edge
  73. * - Direction up
  74. */
  75. timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
  76. TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
  77. /* Reset prescaler value. */
  78. timer_set_prescaler(TIM2, 36000);
  79. /* Enable preload. */
  80. timer_disable_preload(TIM2);
  81. /* Continous mode. */
  82. timer_continuous_mode(TIM2);
  83. /* Period (36kHz). */
  84. timer_set_period(TIM2, 65535);
  85. /* Disable outputs. */
  86. timer_disable_oc_output(TIM2, TIM_OC1);
  87. timer_disable_oc_output(TIM2, TIM_OC2);
  88. timer_disable_oc_output(TIM2, TIM_OC3);
  89. timer_disable_oc_output(TIM2, TIM_OC4);
  90. /* -- OC1 configuration -- */
  91. /* Configure global mode of line 1. */
  92. timer_disable_oc_clear(TIM2, TIM_OC1);
  93. timer_disable_oc_preload(TIM2, TIM_OC1);
  94. timer_set_oc_slow_mode(TIM2, TIM_OC1);
  95. timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_FROZEN);
  96. /* Set the capture compare value for OC1. */
  97. timer_set_oc_value(TIM2, TIM_OC1, 1000);
  98. /* ---- */
  99. /* ARR reload enable. */
  100. timer_disable_preload(TIM2);
  101. /* Counter enable. */
  102. timer_enable_counter(TIM2);
  103. /* Enable commutation interrupt. */
  104. timer_enable_irq(TIM2, TIM_DIER_CC1IE);
  105. }
  106. void tim2_isr(void)
  107. {
  108. if (timer_get_flag(TIM2, TIM_SR_CC1IF)) {
  109. /* Clear compare interrupt flag. */
  110. timer_clear_flag(TIM2, TIM_SR_CC1IF);
  111. /*
  112. * Get current timer value to calculate next
  113. * compare register value.
  114. */
  115. compare_time = timer_get_counter(TIM2);
  116. /* Calculate and set the next compare value. */
  117. frequency = frequency_sequence[frequency_sel++];
  118. new_time = compare_time + frequency;
  119. timer_set_oc_value(TIM2, TIM_OC1, new_time);
  120. if (frequency_sel == 18)
  121. frequency_sel = 0;
  122. /* Toggle LED to indicate compare event. */
  123. gpio_toggle(GPIOC, GPIO12);
  124. }
  125. }
  126. int main(void)
  127. {
  128. clock_setup();
  129. gpio_setup();
  130. tim_setup();
  131. while (1)
  132. __asm("nop");
  133. return 0;
  134. }