0

最近買ったピエゾブザーをラズベリーパイピコで使ってみました。pwmを使用して周波数を生成するために、このコードを(ドキュメントに基づいて)作成しました。

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"

typedef uint16_t u16;
typedef uint32_t u32;

void play_tone(u32 freq);
void stop_playing();

const u16 BUZZER = 0;

int main() 
{
    stdio_init_all();

    gpio_init(BUZZER);
    gpio_set_function(BUZZER, GPIO_FUNC_PWM);
    
    while (1) 
    {
            play_tone(3000);
            sleep_ms(200);
            stop_playing();
            sleep_ms(200);
        
            play_tone(4000);
            sleep_ms(800);
            stop_playing();
        
            sleep_ms(8000);
    }
    return 0;
}

void play_tone(u32 freq) 
{
    //get slice number
    uint slice_num = pwm_gpio_to_slice_num(BUZZER);
    //set divider
    u32 f_sys = clock_get_hz(clk_sys);
    float divider = f_sys / 1000000UL;
    pwm_set_clkdiv (slice_num, divider);
    //set number of cycles
    u32 numberOfCycles = 1000000UL/freq -1;
    pwm_set_wrap(slice_num, numberOfCycles);
    // Set output high for half of cycles
    pwm_set_chan_level(slice_num, 0, (numberOfCycles+1)/2-1);
    
    // Set the PWM running
    pwm_set_enabled(slice_num, true);
}

void stop_playing()
{
    uint slice_num = pwm_gpio_to_slice_num(BUZZER);
    pwm_set_enabled(slice_num, false);
}

トーンの再生を開始する機能と停止する機能の 2 つがあります。また、2 つのトーンを再生して 8 秒間待機する単純なループもあります。

しかし、それは私が期待するようには機能しません。再生を停止する代わりに、ランダムな高周波数の再生を開始することがあります。私もledで試してみましたが、stop_playingを呼び出すと、ランダムな明るさで輝き始めることもあります。また、いくつかの異なる gpios を試しました。

私のピコは毎回同じコードであっても、サイクルごとに異なる動作をするため、私は本当に混乱しています。pico が破損していますか、それとも pwm について誤解していますか?

必要であれば動画もお送りします。

4

0 に答える 0