Вывожу WAV файл с SD карты, контроллер STM32F103VCT6. Использую DAC и DMA. Сначала сделал так:
Спойлер
Код: Выделить всё
void Init_Sound(){
RCC->APB1ENR |= RCC_APB1ENR_DACEN; // включить тактирование ЦАПа
DAC->CR |= DAC_CR_BOFF1; // отключить выходной буфер
DAC->CR |= DAC_CR_EN1; // включить канал №1
GPIOA->CRL &= ~GPIO_CRL_MODE4;
GPIOA->CRL &= ~GPIO_CRL_CNF4;
//Настроить третий канал ДМА для перемещения данных из буфера
//в промежуточный регистр данных первого канала ЦАПа:
RCC->AHBENR |= RCC_AHBENR_DMA2EN; //тактирование DMA
DMA2_Channel3->CPAR = (uint32_t)&DAC->DHR8R1; //указатель на регистр периферии
DMA2_Channel3->CMAR = (uint32_t)&DAC_Buff[0]; //указатель на начало буфера в памяти
DMA2_Channel3->CCR |= DMA_CCR3_DIR; //направление передачи - из памяти в периферию
DMA2_Channel3->CNDTR = 512; //размер буфера
DMA2_Channel3->CCR &= ~DMA_CCR3_PINC; //адрес периферии не инкрементируем
DMA2_Channel3->CCR |= DMA_CCR3_MINC; //адрес памяти инкрементируем
DMA2_Channel3->CCR &= ~DMA_CCR3_PSIZE; //размерность данных периферии - 8 бит.
DMA2_Channel3->CCR &= ~DMA_CCR3_MSIZE; //размерность данных памяти - 8 бит
DMA2_Channel3->CCR |= DMA_CCR3_CIRC; //включить циклический режим передачи данных
DMA2_Channel3->CCR |= DMA_CCR3_PL; //приоритет
DMA2_Channel3->CCR |= DMA_CCR3_EN; //разрешаем работу третьего канала DMA
NVIC_EnableIRQ(DMA2_Channel3_IRQn);
//Запуск передачи очередного значения через ДМА будет происходить от TIM6
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; //подаем тактирование TIM6
TIM6->PSC = 0; //Задаем частоту дискретизации 44100
TIM6->DIER |= TIM_DIER_UDE; //разрешить запрос DMA
}
void wave_playback(const char *FileName)
{
uint32_t samples;
f_open( &file, FileName, FA_READ ); //открыть файл FileName для чтения
f_lseek(&file, 0x1C); //переместить указатель на начало полезных данных
f_read (&file, &samples, 4, &cnt); //прочитать количество семплов
f_read (&file, &DAC_Buff[0], 512, &cnt); //загрузить буфер ЦАПа данными
TIM6->ARR = 72000000/samples;
TIM6->CR1 |= TIM_CR1_CEN;
/* воспроизведение */
while(1)
{
while(!(DMA2->ISR & DMA_ISR_HTIF3)) {} //ждем освобождение первой части буфера
f_read (&file, &DAC_Buff[0], 256, &cnt); //загрузить ее данными
DMA2->IFCR |= DMA_ISR_HTIF3; //сбросить флаг
if(cnt < 256)break; //если конец файла
while(!(DMA2->ISR & DMA_ISR_TCIF3)) {} //ждем освобождение второй части буфера
f_read (&file, &DAC_Buff[256], 256, &cnt); //загрузить ее данными
DMA2->IFCR |= DMA_ISR_TCIF3; //сбросить флаг
if(cnt < 256) break; //если конец файла
}
}Код: Выделить всё
DMA2_Channel3->CCR |= DMA_CCR3_HTIE;
DMA2_Channel3->CCR |= DMA_CCR3_TCIE;
NVIC_EnableIRQ(DMA2_Channel3_IRQn);
и саму функцию:
void DMA2_Channel3_IRQHandler(void){//какие-то действия}


