Initial Release

This commit is contained in:
graham sanderson
2021-01-20 10:49:34 -06:00
commit 46078742c7
245 changed files with 21157 additions and 0 deletions

5
pwm/CMakeLists.txt Normal file
View File

@@ -0,0 +1,5 @@
if (NOT PICO_NO_HARDWARE)
add_subdirectory(hello_pwm)
add_subdirectory(led_fade)
add_subdirectory(measure_duty_cycle)
endif ()

View File

@@ -0,0 +1,12 @@
add_executable(hello_pwm
hello_pwm.c
)
# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(hello_pwm pico_stdlib hardware_pwm)
# create map/bin/hex file etc.
pico_add_extra_outputs(hello_pwm)
# add url via pico_set_program_url
example_auto_set_url(hello_pwm)

34
pwm/hello_pwm/hello_pwm.c Normal file
View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// Output PWM signals on pins 0 and 1
#include "pico/stdlib.h"
#include "hardware/pwm.h"
int main() {
///tag::setup_pwm[]
// Tell GPIO 0 and 1 they are allocated to the PWM
gpio_set_function(0, GPIO_FUNC_PWM);
gpio_set_function(1, GPIO_FUNC_PWM);
// Find out which PWM slice is connected to GPIO 0 (it's slice 0)
uint slice_num = pwm_gpio_to_slice_num(0);
// Set period of 4 cycles (0 to 3 inclusive)
pwm_set_wrap(slice_num, 3);
// Set channel A output high for one cycle before dropping
pwm_set_chan_level(slice_num, PWM_CHAN_A, 1);
// Set initial B output high for three cycles before dropping
pwm_set_chan_level(slice_num, PWM_CHAN_B, 3);
// Set the PWM running
pwm_set_enabled(slice_num, true);
///end::setup_pwm[]
// Note we could also use pwm_set_gpio_level(gpio, x) which looks up the
// correct slice and channel for a given GPIO.
}

View File

@@ -0,0 +1,12 @@
add_executable(pwm_led_fade
pwm_led_fade.c
)
# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(pwm_led_fade pico_stdlib hardware_pwm)
# create map/bin/hex file etc.
pico_add_extra_outputs(pwm_led_fade)
# add url via pico_set_program_url
example_auto_set_url(pwm_led_fade)

View File

@@ -0,0 +1,65 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// Fade an LED between low and high brightness. An interrupt handler updates
// the PWM slice's output level each time the counter wraps.
#include "pico/stdlib.h"
#include <stdio.h>
#include "pico/time.h"
#include "hardware/irq.h"
#include "hardware/pwm.h"
void on_pwm_wrap() {
static int fade = 0;
static bool going_up = true;
// Clear the interrupt flag that brought us here
pwm_clear_irq(pwm_gpio_to_slice_num(PICO_DEFAULT_LED_PIN));
if (going_up) {
++fade;
if (fade > 255) {
fade = 255;
going_up = false;
}
} else {
--fade;
if (fade < 0) {
fade = 0;
going_up = true;
}
}
// Square the fade value to make the LED's brightness appear more linear
// Note this range matches with the wrap value
pwm_set_gpio_level(PICO_DEFAULT_LED_PIN, fade * fade);
}
int main() {
// Tell the LED pin that the PWM is in charge of its value.
gpio_set_function(PICO_DEFAULT_LED_PIN, GPIO_FUNC_PWM);
// Figure out which slice we just connected to the LED pin
uint slice_num = pwm_gpio_to_slice_num(PICO_DEFAULT_LED_PIN);
// Mask our slice's IRQ output into the PWM block's single interrupt line,
// and register our interrupt handler
pwm_clear_irq(slice_num);
pwm_set_irq_enabled(slice_num, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap);
irq_set_enabled(PWM_IRQ_WRAP, true);
// Get some sensible defaults for the slice configuration. By default, the
// counter is allowed to wrap over its maximum range (0 to 2**16-1)
pwm_config config = pwm_get_default_config();
// Set divider, reduces counter clock to sysclock/this value
pwm_config_set_clkdiv(&config, 4.f);
// Load the configuration into our PWM slice, and set it running.
pwm_init(slice_num, &config, true);
// Everything after this point happens in the PWM interrupt handler, so we
// can twiddle our thumbs
while (1)
tight_loop_contents();
}

View File

@@ -0,0 +1,12 @@
add_executable(pwm_measure_duty_cycle
measure_duty_cycle.c
)
# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(pwm_measure_duty_cycle pico_stdlib hardware_pwm)
# create map/bin/hex file etc.
pico_add_extra_outputs(pwm_measure_duty_cycle)
# add url via pico_set_program_url
example_auto_set_url(pwm_measure_duty_cycle)

View File

@@ -0,0 +1,72 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
// This example drives a PWM output at a range of duty cycles, and uses
// another PWM slice in input mode to measure the duty cycle. You'll need to
// connect these two pins with a jumper wire:
const uint OUTPUT_PIN = 2;
const uint MEASURE_PIN = 5;
float measure_duty_cycle(uint gpio) {
// Only the PWM B pins can be used as inputs.
assert(pwm_gpio_to_channel(gpio) == PWM_CHAN_B);
uint slice_num = pwm_gpio_to_slice_num(gpio);
// Count once for every 100 cycles the PWM B input is high
pwm_config cfg = pwm_get_default_config();
pwm_config_set_clkdiv_mode(&cfg, PWM_DIV_B_HIGH);
pwm_config_set_clkdiv(&cfg, 100);
pwm_init(slice_num, &cfg, false);
gpio_set_function(gpio, GPIO_FUNC_PWM);
pwm_set_enabled(slice_num, true);
sleep_ms(10);
pwm_set_enabled(slice_num, false);
float counting_rate = clock_get_hz(clk_sys) / 100;
float max_possible_count = counting_rate * 0.01;
return pwm_get_counter(slice_num) / max_possible_count;
}
const float test_duty_cycles[] = {
0.f,
0.1f,
0.5f,
0.9f,
1.f
};
int main() {
stdio_init_all();
printf("\nPWM duty cycle measurement example\n");
// Configure PWM slice and set it running
const uint count_top = 1000;
pwm_config cfg = pwm_get_default_config();
pwm_config_set_wrap(&cfg, count_top);
pwm_init(pwm_gpio_to_slice_num(OUTPUT_PIN), &cfg, true);
// Note we aren't touching the other pin yet -- PWM pins are outputs by
// default, but change to inputs once the divider mode is changed from
// free-running. It's not wise to connect two outputs directly together!
gpio_set_function(OUTPUT_PIN, GPIO_FUNC_PWM);
// For each of our test duty cycles, drive the output pin at that level,
// and read back the actual output duty cycle using the other pin. The two
// values should be very close!
for (int i = 0; i < count_of(test_duty_cycles); ++i) {
float output_duty_cycle = test_duty_cycles[i];
pwm_set_gpio_level(OUTPUT_PIN, output_duty_cycle * (count_top + 1));
float measured_duty_cycle = measure_duty_cycle(MEASURE_PIN);
printf("Output duty cycle = %.1f%%, measured input duty cycle = %.1f%%\n",
output_duty_cycle * 100.f, measured_duty_cycle * 100.f);
}
}