ledc_fade_example_main.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* LEDC (LED Controller) fade example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "driver/ledc.h"
  11. #include "esp_err.h"
  12. #include "freertos/FreeRTOS.h"
  13. #include "freertos/semphr.h"
  14. /*
  15. * About this example
  16. *
  17. * 1. Start with initializing LEDC module:
  18. * a. Set the timer of LEDC first, this determines the frequency
  19. * and resolution of PWM.
  20. * b. Then set the LEDC channel you want to use,
  21. * and bind with one of the timers.
  22. *
  23. * 2. You need first to install a default fade function,
  24. * then you can use fade APIs.
  25. *
  26. * 3. You can also set a target duty directly without fading.
  27. *
  28. * 4. This example uses GPIO18/19/4/5 as LEDC output,
  29. * and it will change the duty repeatedly.
  30. *
  31. * 5. GPIO18/19 are from high speed channel group.
  32. * GPIO4/5 are from low speed channel group.
  33. *
  34. */
  35. #if CONFIG_IDF_TARGET_ESP32
  36. #define LEDC_HS_TIMER LEDC_TIMER_0
  37. #define LEDC_HS_MODE LEDC_HIGH_SPEED_MODE
  38. #define LEDC_HS_CH0_GPIO (18)
  39. #define LEDC_HS_CH0_CHANNEL LEDC_CHANNEL_0
  40. #define LEDC_HS_CH1_GPIO (19)
  41. #define LEDC_HS_CH1_CHANNEL LEDC_CHANNEL_1
  42. #endif
  43. #define LEDC_LS_TIMER LEDC_TIMER_1
  44. #define LEDC_LS_MODE LEDC_LOW_SPEED_MODE
  45. #if !CONFIG_IDF_TARGET_ESP32
  46. #define LEDC_LS_CH0_GPIO (18)
  47. #define LEDC_LS_CH0_CHANNEL LEDC_CHANNEL_0
  48. #define LEDC_LS_CH1_GPIO (19)
  49. #define LEDC_LS_CH1_CHANNEL LEDC_CHANNEL_1
  50. #endif
  51. #define LEDC_LS_CH2_GPIO (4)
  52. #define LEDC_LS_CH2_CHANNEL LEDC_CHANNEL_2
  53. #define LEDC_LS_CH3_GPIO (5)
  54. #define LEDC_LS_CH3_CHANNEL LEDC_CHANNEL_3
  55. #define LEDC_TEST_CH_NUM (4)
  56. #define LEDC_TEST_DUTY (4000)
  57. #define LEDC_TEST_FADE_TIME (3000)
  58. /*
  59. * This callback function will be called when fade operation has ended
  60. * Use callback only if you are aware it is being called inside an ISR
  61. * Otherwise, you can use a semaphore to unblock tasks
  62. */
  63. static bool cb_ledc_fade_end_event(const ledc_cb_param_t *param, void *user_arg)
  64. {
  65. portBASE_TYPE taskAwoken = pdFALSE;
  66. if (param->event == LEDC_FADE_END_EVT) {
  67. SemaphoreHandle_t counting_sem = (SemaphoreHandle_t) user_arg;
  68. xSemaphoreGiveFromISR(counting_sem, &taskAwoken);
  69. }
  70. return (taskAwoken == pdTRUE);
  71. }
  72. void app_main(void)
  73. {
  74. int ch;
  75. /*
  76. * Prepare and set configuration of timers
  77. * that will be used by LED Controller
  78. */
  79. ledc_timer_config_t ledc_timer = {
  80. .duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty
  81. .freq_hz = 5000, // frequency of PWM signal
  82. .speed_mode = LEDC_LS_MODE, // timer mode
  83. .timer_num = LEDC_LS_TIMER, // timer index
  84. .clk_cfg = LEDC_AUTO_CLK, // Auto select the source clock
  85. };
  86. // Set configuration of timer0 for high speed channels
  87. ledc_timer_config(&ledc_timer);
  88. #ifdef CONFIG_IDF_TARGET_ESP32
  89. // Prepare and set configuration of timer1 for low speed channels
  90. ledc_timer.speed_mode = LEDC_HS_MODE;
  91. ledc_timer.timer_num = LEDC_HS_TIMER;
  92. ledc_timer_config(&ledc_timer);
  93. #endif
  94. /*
  95. * Prepare individual configuration
  96. * for each channel of LED Controller
  97. * by selecting:
  98. * - controller's channel number
  99. * - output duty cycle, set initially to 0
  100. * - GPIO number where LED is connected to
  101. * - speed mode, either high or low
  102. * - timer servicing selected channel
  103. * Note: if different channels use one timer,
  104. * then frequency and bit_num of these channels
  105. * will be the same
  106. */
  107. ledc_channel_config_t ledc_channel[LEDC_TEST_CH_NUM] = {
  108. #if CONFIG_IDF_TARGET_ESP32
  109. {
  110. .channel = LEDC_HS_CH0_CHANNEL,
  111. .duty = 0,
  112. .gpio_num = LEDC_HS_CH0_GPIO,
  113. .speed_mode = LEDC_HS_MODE,
  114. .hpoint = 0,
  115. .timer_sel = LEDC_HS_TIMER,
  116. .flags.output_invert = 0
  117. },
  118. {
  119. .channel = LEDC_HS_CH1_CHANNEL,
  120. .duty = 0,
  121. .gpio_num = LEDC_HS_CH1_GPIO,
  122. .speed_mode = LEDC_HS_MODE,
  123. .hpoint = 0,
  124. .timer_sel = LEDC_HS_TIMER,
  125. .flags.output_invert = 0
  126. },
  127. #else
  128. {
  129. .channel = LEDC_LS_CH0_CHANNEL,
  130. .duty = 0,
  131. .gpio_num = LEDC_LS_CH0_GPIO,
  132. .speed_mode = LEDC_LS_MODE,
  133. .hpoint = 0,
  134. .timer_sel = LEDC_LS_TIMER,
  135. .flags.output_invert = 0
  136. },
  137. {
  138. .channel = LEDC_LS_CH1_CHANNEL,
  139. .duty = 0,
  140. .gpio_num = LEDC_LS_CH1_GPIO,
  141. .speed_mode = LEDC_LS_MODE,
  142. .hpoint = 0,
  143. .timer_sel = LEDC_LS_TIMER,
  144. .flags.output_invert = 0
  145. },
  146. #endif
  147. {
  148. .channel = LEDC_LS_CH2_CHANNEL,
  149. .duty = 0,
  150. .gpio_num = LEDC_LS_CH2_GPIO,
  151. .speed_mode = LEDC_LS_MODE,
  152. .hpoint = 0,
  153. .timer_sel = LEDC_LS_TIMER,
  154. .flags.output_invert = 1
  155. },
  156. {
  157. .channel = LEDC_LS_CH3_CHANNEL,
  158. .duty = 0,
  159. .gpio_num = LEDC_LS_CH3_GPIO,
  160. .speed_mode = LEDC_LS_MODE,
  161. .hpoint = 0,
  162. .timer_sel = LEDC_LS_TIMER,
  163. .flags.output_invert = 1
  164. },
  165. };
  166. // Set LED Controller with previously prepared configuration
  167. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  168. ledc_channel_config(&ledc_channel[ch]);
  169. }
  170. // Initialize fade service.
  171. ledc_fade_func_install(0);
  172. ledc_cbs_t callbacks = {
  173. .fade_cb = cb_ledc_fade_end_event
  174. };
  175. SemaphoreHandle_t counting_sem = xSemaphoreCreateCounting(LEDC_TEST_CH_NUM, 0);
  176. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  177. ledc_cb_register(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, &callbacks, (void *) counting_sem);
  178. }
  179. while (1) {
  180. printf("1. LEDC fade up to duty = %d\n", LEDC_TEST_DUTY);
  181. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  182. ledc_set_fade_with_time(ledc_channel[ch].speed_mode,
  183. ledc_channel[ch].channel, LEDC_TEST_DUTY, LEDC_TEST_FADE_TIME);
  184. ledc_fade_start(ledc_channel[ch].speed_mode,
  185. ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);
  186. }
  187. for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
  188. xSemaphoreTake(counting_sem, portMAX_DELAY);
  189. }
  190. printf("2. LEDC fade down to duty = 0\n");
  191. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  192. ledc_set_fade_with_time(ledc_channel[ch].speed_mode,
  193. ledc_channel[ch].channel, 0, LEDC_TEST_FADE_TIME);
  194. ledc_fade_start(ledc_channel[ch].speed_mode,
  195. ledc_channel[ch].channel, LEDC_FADE_NO_WAIT);
  196. }
  197. for (int i = 0; i < LEDC_TEST_CH_NUM; i++) {
  198. xSemaphoreTake(counting_sem, portMAX_DELAY);
  199. }
  200. printf("3. LEDC set duty = %d without fade\n", LEDC_TEST_DUTY);
  201. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  202. ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, LEDC_TEST_DUTY);
  203. ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
  204. }
  205. vTaskDelay(1000 / portTICK_PERIOD_MS);
  206. printf("4. LEDC set duty = 0 without fade\n");
  207. for (ch = 0; ch < LEDC_TEST_CH_NUM; ch++) {
  208. ledc_set_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel, 0);
  209. ledc_update_duty(ledc_channel[ch].speed_mode, ledc_channel[ch].channel);
  210. }
  211. vTaskDelay(1000 / portTICK_PERIOD_MS);
  212. }
  213. }