-2

我正在尝试生成注释,例如 Do ,do 的频率是 523。我写了一些代码但是,我没有工作 Systick 8 mhz

void note1(void){ // Note Do    

    for (int i = 0; i < 523; i++){

        GPIOE->ODR = 0x4000;
        delay_ms(1);
        GPIOE->ODR = 0x0000;
        delay_ms(1);
    }
}

我们如何解决这个问题?

EasyMx Pro v7

我这样调用函数

void button_handler(void)
{
    note1();

    // Clear pending bit depending on which one is pending
    if (EXTI->PR & (1 << 0)){

        EXTI->PR = (1 << 0);
    }
    else if (EXTI->PR & (1 << 1)){

        EXTI->PR = (1 << 1);
    }       
}

523 次发送 1 和 0 和 delay_ms 1 = 1 ms

1000 = 1 秒

4

2 回答 2

2

在 STM32 上(我可以看到你有它)你有可以配置为 PWM 输出的定时器。因此,根据您需要的频率使用定时器、设置周期和预分频器值,并将通道上的占空比设置为 50%。

如果您需要 523Hz PWM 输出,则使用预分频器和周期值将定时器 PWM 设置为 523Hz:

timer_overflow_frequency = timer_input_clock / 
                           (prescaler_value + 1) / 
                           (period_value + 1) ;

然后,为您的输出通道设置定时器周期值的一半。

对于标准外围库,可以从这里使用教程: https ://stm32f4-discovery.net/2014/05/stm32f4-stm32f429-discovery-pwm-tutorial/

Cube 的 unwind 链接https://electronics.stackexchange.com/questions/179546/getting-pwm-to-work-on-stm32f4-using-sts-hal-libraries

于 2017-03-28T11:19:35.333 回答
0

你似乎有一个根本的误解。在您的代码note1()中,值 523 只会影响音符的持续时间,而不是它的频率。1ms 高,1ms 低重复 523 次,您将产生大约500Hz 的音调,持续大约1.43 秒。我说“大约”是因为除了时间延迟之外,循环中会有一些小的开销。

1ms 的时间延迟分辨率不足以以这种方式生成准确的音调。要以您的方式执行此操作,每个延迟需要为1/2f秒,因此对于 523Hz 大约为 956ms。循环迭代计数需要为ft,因此对于 0.25 秒,131 次迭代。

但是,如果button_handler()它看起来是一个中断处理程序,那么您真的不应该在中断处理程序中花费 1.46 秒!

无论如何,这是一种非常费力、CPU 密集型且不准确的生成特定频率的方法。您板上的 STM32 配备了具有直接 GPIO 输出的硬件定时器,可以在零软件开销的情况下准确生成您需要的频率。即使没有一个定时器映射到您需要使用的合适的 GPIO 输出,您仍然可以在1/2f处生成一个中断并在中断处理程序中切换引脚。无论哪种方式,都会让处理器在输出音调时可以自由地做有用的事情。

于 2017-03-28T20:04:22.427 回答