Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Raspberry Pi Pico PWM example
- Scott Beasley (2021) No Copyright.
- Code used by Damien P. George Copyright (c) 2020
- From the RPI Pico MicroPython project. See below for copyright info.
- https://github.com/raspberrypi/micropython/blob/pico/ports/rp2/machine_pwm.c
- */
- #include "pico/stdlib.h"
- #include <stdio.h>
- #include "pico/time.h"
- #include "hardware/pwm.h"
- #include "hardware/clocks.h"
- #define LED_PIN 25
- #define PWM_PIN 16
- #define DUTY_50_PCT 32767
- // Maximum "top" is set at 65534 to be able to achieve 100% duty with 65535.
- #define TOP_MAX 65534
- int set_pwm_freq (uint slice, int freq, uint32_t *div, uint32_t *top);
- int set_pwm_duty (uint slice, uint channel, uint32_t top, uint32_t duty);
- int main (void)
- {
- uint32_t div = 0, top = 0;
- uint slice_num, channel;
- // Use the LED for error notifications
- gpio_init (LED_PIN);
- gpio_set_dir (LED_PIN, GPIO_OUT);
- slice_num = pwm_gpio_to_slice_num (PWM_PIN);
- channel = pwm_gpio_to_channel (PWM_PIN);
- gpio_set_function (PWM_PIN, GPIO_FUNC_PWM);
- // Set up a 2khz freq PWM
- if (set_pwm_freq (slice_num, (int)2000, &div, &top) != 0) {
- gpio_put (LED_PIN, 1);
- } else {
- gpio_put (LED_PIN, 0);
- }
- // Set the PWM counter wrap value to reset on
- pwm_set_wrap (slice_num, top);
- while (1) {
- tight_loop_contents ( );
- set_pwm_duty (slice_num, channel, top, (uint32_t)DUTY_50_PCT);
- sleep_ms(2000);
- set_pwm_duty (slice_num, channel, top, (uint32_t)DUTY_50_PCT / 2);
- sleep_ms(2000);
- set_pwm_duty (slice_num, channel, top, (uint32_t)DUTY_50_PCT / 4);
- sleep_ms(2000);
- set_pwm_duty (slice_num, channel, top, (uint32_t)DUTY_50_PCT / 6);
- sleep_ms(2000);
- }
- }
- //
- // These functions work ok up to 10khz, but get off values after
- // 11k and above. It could be type/casting issues, but I have not
- // investigated any further yey. I plan to test the Micropython
- // functions and see if they display the same issues.
- //
- /*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2020 Damien P. George
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- // Code used from https://github.com/raspberrypi/micropython/blob/pico/ports/rp2/machine_pwm.c
- // Function - machine_pwm_freq
- // Shaped for my needs (Scott Beasley) No Copyright.
- // MIT License (MIT) Damien P. George Copyright (c) 2020
- int set_pwm_freq (uint slice, int freq, uint32_t *div, uint32_t *top)
- {
- // Set the frequency, making "top" as large as possible for maximum resolution.
- *div = (uint32_t)(16 * clock_get_hz (clk_sys) / (uint32_t)freq);
- *top = 1;
- for (;;) {
- // Try a few small prime factors to get close to the desired frequency.
- if (*div >= 16 * 5 && *div % 5 == 0 && *top * 5 <= TOP_MAX) {
- *div /= 5;
- *top *= 5;
- } else if (*div >= 16 * 3 && *div % 3 == 0 && *top * 3 <= TOP_MAX) {
- *div /= 3;
- *top *= 3;
- } else if (*div >= 16 * 2 && *top * 2 <= TOP_MAX) {
- *div /= 2;
- *top *= 2;
- } else {
- break;
- }
- }
- if (*div < 16) {
- *div = 0;
- *top = 0;
- return -1; // freq too large
- } else if (*div >= 256 * 16) {
- *div = 0;
- *top = 0;
- return -2; // freq too small
- }
- return 0;
- }
- // Code used from https://github.com/raspberrypi/micropython/blob/pico/ports/rp2/machine_pwm.c
- // Function - machine_pwm_duty_u16
- // Shaped for my needs (Scott Beasley) No Copyright.
- // MIT License (MIT) Damien P. George Copyright (c) 2020
- int set_pwm_duty (uint slice, uint channel, uint32_t top, uint32_t duty)
- {
- // Set duty cycle.
- uint32_t cc = duty * (top + 1) / 65535;
- pwm_set_chan_level (slice, channel, cc);
- pwm_set_enabled (slice, true);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement