add piezo-buzzer controller using PWM

This commit is contained in:
King Kévin 2017-05-04 18:53:52 +02:00
parent d04212b8ff
commit 4bdc673561
1 changed files with 35 additions and 11 deletions

46
main.c
View File

@ -62,10 +62,16 @@ volatile uint8_t rtc_seconds = 0; /**< number of seconds passed incremented by t
#define STANDBY_TIMEOUT 30 /**< number of seconds after last shake before going down */
volatile uint16_t standby_timer = 0; /**< number of seconds since last wake-up/activity */
#define FRAME_TIMER 1 /**< timer to count frame time */
#define FRAME_TIMER 2 /**< timer to count frame time */
#define FRAME_RATE 25 /**< frame rate */
volatile uint8_t frame_count = 0; /**< number of frames passed */
#define BUZZER_TIMER 1 /**< timer to generate scene and take count */
#define BUZZER_1_PORT A /**< use timer 1 channel 1 (and it's negative) to driver buzzer */
#define BUZZER_1_PIN 7 /**< use timer 1 channel 1 (and it's negative) to driver buzzer */
#define BUZZER_2_PORT A /**< use timer 1 channel 1 (and it's negative) to driver buzzer */
#define BUZZER_2_PIN 8 /**< use timer 1 channel 1 (and it's negative) to driver buzzer */
#define MUX_EN_PORT B /**< port to enable multiplexer */
#define MUX_EN_PIN 9 /**< pin to enable multiplexer */
#define MUX_S0_PORT B /**< port to select multiplexer output */
@ -281,7 +287,7 @@ void main(void)
usart_setup(); // setup USART for user communication
cdcacm_setup(); // setup USB ACM (serial) for user communication
gpio_primary_remap(AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON,0); // disable JTAG (but leave SWD on) since we need most of the GPIOs
printf("welcome to the CuVoodoo clapperboard\n"); // print welcome message
printf("\nwelcome to the CuVoodoo clapperboard\n"); // print welcome message
#if !(DEBUG)
// show watchdog information
@ -394,6 +400,28 @@ void main(void)
timer_enable_counter(TIM(FRAME_TIMER)); // enable timer to start counting frames
printf("OK\n");
// setup PWM for piezo-buzzer
printf("setup piezo-buzzer timer: ");
rcc_periph_clock_enable(RCC_GPIO(BUZZER_1_PORT)); // enable clock for GPIO peripheral
rcc_periph_clock_enable(RCC_AFIO); // enable clock for alternate function (PWM)
gpio_primary_remap(AFIO_MAPR_SWJ_MASK, AFIO_MAPR_TIM1_REMAP_PARTIAL_REMAP); // remap TIM1_CH1N to PA7 instead of PB13
gpio_set_mode(GPIO(BUZZER_1_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO(BUZZER_1_PIN)); // set pin as output to have a PWM to driver piezo buzzer
rcc_periph_clock_enable(RCC_GPIO(BUZZER_2_PORT)); // enable clock for GPIO peripheral
gpio_set_mode(GPIO(BUZZER_2_PORT), GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO(BUZZER_2_PIN)); // set pin as output to have a PWM to driver piezo buzzer
rcc_periph_clock_enable(RCC_TIM(BUZZER_TIMER)); // enable clock for timer peripheral
timer_reset(TIM(BUZZER_TIMER)); // reset timer state
timer_set_mode(TIM(BUZZER_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up
timer_set_prescaler(TIM(BUZZER_TIMER), 0); // no prescaler to keep most precise timer (72MHz/2^16=1099<2kHz)
timer_set_period(TIM(BUZZER_TIMER), rcc_ahb_frequency/2000-1); // set the PWM frequency to 2kHz for piezo-buzzer
timer_set_oc_value(TIM(BUZZER_TIMER), TIM_OC1, rcc_ahb_frequency/2000/2-1); // duty cycle to 50% (also applies to TIM_OC1N)
// no preload is used, although the reference manual says to enable it
timer_set_oc_mode(TIM(BUZZER_TIMER), TIM_OC1, TIM_OCM_PWM1); // set timer to generate PWM (also applies to TIM_OC1N)
timer_enable_oc_output(TIM(BUZZER_TIMER), TIM_OC1); // enable output to generate PWM
timer_enable_oc_output(TIM(BUZZER_TIMER), TIM_OC1N); // enable output to generate PWM (complementary to be louder)
timer_enable_break_main_output(TIM(BUZZER_TIMER)); // enable master output
timer_generate_event(TIM(BUZZER_TIMER), TIM_EGR_UG); // generate update event to reload registers and reset counter
printf("OK\n");
// main loop
printf("command input: ready\n");
bool action = false; // if an action has been performed don't go to sleep
@ -431,15 +459,6 @@ void main(void)
}
}
}
while (button_flag) { // user pressed button
action = true; // action has been performed
printf("button pressed\n");
led_toggle(); // toggle LED
for (uint32_t i=0; i<1000000; i++) { // wait a bit to remove noise and double trigger
__asm__("nop");
}
button_flag = false; // reset flag
}
while (frame_flag) { // a frame has passed
frame_flag = false; // reset flag
action = true; // action has been performed
@ -465,6 +484,11 @@ void main(void)
rtc_tick_flag = false; // reset flag
action = true; // action has been performed
led_toggle(); // toggle LED (good to indicate if main function is stuck)
if (rtc_seconds%2) {
timer_enable_counter(TIM(BUZZER_TIMER)); // start buzzing
} else {
timer_disable_counter(TIM(BUZZER_TIMER)); // start buzzing
}
if (standby_timer>=STANDBY_TIMEOUT) { // standby timeout complete
// go into standby mode
printf("shutting down\n");