mirror of
https://github.com/DashyFox/StackSport.git
synced 2025-06-28 13:19:41 +00:00
sound fine
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
#include "stm32f103xb.h"
|
||||
#include "SimpleTimer.h"
|
||||
|
||||
static uint32_t bpm = 120; // Default BPM
|
||||
uint32_t bpm = 120; // Default BPM
|
||||
static uint32_t note_end_time_ch[4] = {0, 0, 0, 0}; // End times for each channel (1-4)
|
||||
static Melody_t melodies[4]; // Array of melodies for each channel
|
||||
|
||||
@ -19,32 +19,34 @@ static Melody_t melodies[4]; // Array of melodies for each channel
|
||||
|
||||
// Initialize the sound system
|
||||
void sound_init(void) {
|
||||
// Enable timer clock
|
||||
RCC->APB1ENR |= SOUND_TIMER_RCC;
|
||||
// Dont need, conflict with uart
|
||||
|
||||
// Configure GPIO pins for timer output (assuming GPIOB pins for TIM4 CH3 and CH4)
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
|
||||
// Configure only channels 3 and 4
|
||||
// Channel 3
|
||||
GPIOB->CRH &= ~(0xF << (3 * 4)); // Clear configuration for PB10 (TIM4_CH3)
|
||||
GPIOB->CRH |= (0xB << (3 * 4)); // Set to alternate function push-pull
|
||||
|
||||
// Channel 4
|
||||
GPIOB->CRH &= ~(0xF << (4 * 4)); // Clear configuration for PB11 (TIM4_CH4)
|
||||
GPIOB->CRH |= (0xB << (4 * 4)); // Set to alternate function push-pull
|
||||
|
||||
// Initialize the timer for PWM output
|
||||
SOUND_TIMER->PSC = 0;
|
||||
SOUND_TIMER->ARR = 0xFFFF;
|
||||
|
||||
// Configure only channels 3 and 4 for PWM output
|
||||
SOUND_TIMER->CCMR2 &= ~(TIM_CCMR2_OC3M | TIM_CCMR2_OC4M); // Clear channel 3 and 4 mode
|
||||
SOUND_TIMER->CCMR2 |= (6 << TIM_CCMR2_OC3M_Pos); // Set channel 3 to PWM mode 1
|
||||
SOUND_TIMER->CCER |= (TIM_CCER_CC3E | TIM_CCER_CC4E); // Enable output for channels 3 and 4
|
||||
|
||||
SOUND_TIMER->EGR = TIM_EGR_UG; // Update the timer
|
||||
SOUND_TIMER->CR1 |= TIM_CR1_CEN; // Enable the timer
|
||||
// // Enable timer clock
|
||||
// RCC->APB1ENR |= SOUND_TIMER_RCC;
|
||||
//
|
||||
// // Configure GPIO pins for timer output (assuming GPIOB pins for TIM4 CH3 and CH4)
|
||||
// RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
|
||||
//
|
||||
// // Configure only channels 3 and 4
|
||||
// // Channel 3
|
||||
// GPIOB->CRH &= ~(0xF << (3 * 4)); // Clear configuration for PB10 (TIM4_CH3)
|
||||
// GPIOB->CRH |= (0xB << (3 * 4)); // Set to alternate function push-pull
|
||||
//
|
||||
// // Channel 4
|
||||
// GPIOB->CRH &= ~(0xF << (4 * 4)); // Clear configuration for PB11 (TIM4_CH4)
|
||||
// GPIOB->CRH |= (0xB << (4 * 4)); // Set to alternate function push-pull
|
||||
//
|
||||
// // Initialize the timer for PWM output
|
||||
// SOUND_TIMER->PSC = 0;
|
||||
// SOUND_TIMER->ARR = 0xFFFF;
|
||||
//
|
||||
// // Configure only channels 3 and 4 for PWM output
|
||||
// SOUND_TIMER->CCMR2 &= ~(TIM_CCMR2_OC3M | TIM_CCMR2_OC4M); // Clear channel 3 and 4 mode
|
||||
// SOUND_TIMER->CCMR2 |= (6 << TIM_CCMR2_OC3M_Pos); // Set channel 3 to PWM mode 1
|
||||
// SOUND_TIMER->CCER |= (TIM_CCER_CC3E | TIM_CCER_CC4E); // Enable output for channels 3 and 4
|
||||
//
|
||||
// SOUND_TIMER->EGR = TIM_EGR_UG; // Update the timer
|
||||
// SOUND_TIMER->CR1 |= TIM_CR1_CEN; // Enable the timer
|
||||
}
|
||||
|
||||
|
||||
@ -62,10 +64,17 @@ void sound_play_note(Note_t note, uint8_t channel) {
|
||||
uint32_t *ccer = &SOUND_TIMER->CCER;
|
||||
uint32_t enable_cc = TIM_CCER_CC1E << ((channel - 1) * 4);
|
||||
|
||||
uint32_t duration = (note.duration == T0) ? 0 : (60000 * 4 / (bpm * note.duration));
|
||||
|
||||
if (note.frequency == 0) {
|
||||
*ccer &= ~enable_cc;
|
||||
note_end_time_ch[channel - 1] = millis() + note.duration;
|
||||
note_end_time_ch[channel - 1] = millis() + duration;
|
||||
} else {
|
||||
// Если текущая нота отличается от новой, отключите старую
|
||||
if (*ccer & enable_cc) {
|
||||
*ccer &= ~enable_cc; // Отключить старую ноту
|
||||
}
|
||||
|
||||
uint32_t timer_clock = SystemCoreClock / 2;
|
||||
uint32_t prescaler = (timer_clock / (note.frequency * 65536)) + 1;
|
||||
uint32_t arr = (timer_clock / (prescaler * note.frequency)) - 1;
|
||||
@ -82,22 +91,30 @@ void sound_play_note(Note_t note, uint8_t channel) {
|
||||
SOUND_TIMER->EGR = TIM_EGR_UG;
|
||||
SOUND_TIMER->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
note_end_time_ch[channel - 1] = (note.duration == 0) ? 0 : millis() + note.duration;
|
||||
note_end_time_ch[channel - 1] = (duration == 0) ? 0 : millis() + duration;
|
||||
}
|
||||
}
|
||||
|
||||
static void play_next_note(uint8_t channel);
|
||||
// Play a melody on a specific channel with repeat count
|
||||
void sound_play_melody(Note_t* melody, uint32_t size, uint8_t channel, uint32_t repeat_count) {
|
||||
if (channel < 1 || channel > 4 || melody == NULL || size == 0) return;
|
||||
|
||||
uint8_t ch_idx = channel - 1;
|
||||
|
||||
// Если уже есть мелодия, которую нужно перебить
|
||||
if (melodies[ch_idx].notes != NULL) {
|
||||
// Остановите текущую мелодию
|
||||
SOUND_TIMER->CCER &= ~(TIM_CCER_CC1E << (ch_idx * 4)); // Отключить выход
|
||||
melodies[ch_idx].notes = NULL; // Удалить текущую мелодию
|
||||
}
|
||||
|
||||
melodies[ch_idx].notes = melody;
|
||||
melodies[ch_idx].size = size;
|
||||
melodies[ch_idx].current_note = 0;
|
||||
melodies[ch_idx].repeat_count = repeat_count;
|
||||
melodies[ch_idx].repeat_left = repeat_count;
|
||||
|
||||
sound_play_note(melody[0], channel); // Play the first note
|
||||
play_next_note(channel);
|
||||
// sound_play_note(melody[0], channel); // Play the first note
|
||||
}
|
||||
|
||||
// Function to play the next note in the melody for a specific channel
|
||||
@ -135,8 +152,9 @@ void sound_tick(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create a note
|
||||
Note_t sound_create_note(MusicalNote_t note, NoteDuration_t duration, uint8_t duty_cycle) {
|
||||
uint32_t note_duration = (duration == T0) ? 0 : (60000 * 4 / (bpm * duration));
|
||||
return (Note_t){ .frequency = note, .duration = note_duration, .duty_cycle = duty_cycle };
|
||||
return (Note_t){ .frequency = note, .duration = duration, .duty_cycle = duty_cycle };
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user