Имеется контроллер STM32F407ZET6. Вместе с ним на плате USB флешка, UART и ЦАП.
При выключенной оптимизации код работает без проблем.
Код
Обработчик прерываний
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_DAC_IRQHandler(&hdac);
HAL_TIM_IRQHandler(&htim6);//Сброс флагов
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_L, L_Buffer[AudioPoint]);//Выводим в ЦАП
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_L, R_Buffer[AudioPoint]);
print("D %d %d\n\r",2,i,AudioPoint);//Дебаг.
AudioPoint++;//Освобождаем ячейку
if(AudioPoint >= BUFFERSIZE) AudioPoint = 0;
/* USER CODE END TIM6_DAC_IRQn 1 */
}
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_DAC_IRQHandler(&hdac);
HAL_TIM_IRQHandler(&htim6);//Сброс флагов
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_L, L_Buffer[AudioPoint]);//Выводим в ЦАП
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_L, R_Buffer[AudioPoint]);
print("D %d %d\n\r",2,i,AudioPoint);//Дебаг.
AudioPoint++;//Освобождаем ячейку
if(AudioPoint >= BUFFERSIZE) AudioPoint = 0;
/* USER CODE END TIM6_DAC_IRQn 1 */
}
CODE
Основная программа
BUFFERSIZE = 128; //Количество сэмплов в буффере
AudioPoint = BUFFERSIZE;
uint8_t Bytes = FileBuff[32];//Байт на сэмпл WAVE
length = BUFFERSIZE*Bytes;//Длинна блока
uint8_t ftime = 1;//В первый раз(антибаг)
while(f_eof(&File))//Пока файл не кончился
{
if(File.Size-File.CurrentByte < length) length = File.Size-File.CurrentByte;//Антибаг
if(f_read(&File, FileBuff, length)) { print("File read error!",0); goto error; }//Чтение
print("R\n\r",0);//Дебаг
i = 0;//Обнуляем указатель
while(i<BUFFERSIZE)//Пока буффер из носителя не будет полностью считан
{
//////////////////////////////////////////////////////////////////////////////
if(i != AudioPoint)//Вот тут вот какая-то херня. Если ячейка буффера ЦАПа освободилась, записываем в неё новое значение
{
L_Buffer[i] = FileBuff[(i*Bytes)+1]<<8;//Заполняем ячейку буффера "звук"
L_Buffer[i] += FileBuff[(i*Bytes)];
L_Buffer[i] ^= 0x8000;
R_Buffer[i] = FileBuff[(i*Bytes)+3]<<8;
R_Buffer[i] += FileBuff[(i*Bytes)+2];
R_Buffer[i] ^= 0x8000;
print("F %d %d\n\r",2,i,AudioPoint);//Дебаг
i += 1;//Добавляем единичку
}
//////////////////////////////////////////////////////////////////////////////
}
if(ftime) { AudioPoint = 0; HAL_TIM_Base_Start_IT(&htim6); ftime = 0; }//В первый проход запускаем таймер
}
ftime = 1;
HAL_TIM_Base_Stop_IT(&htim6);//Файл закончился, останавливаем таймер
print("Done! Thanks!\n\r", 0);//Благодарность
error:
while(1);//Программа закончена
BUFFERSIZE = 128; //Количество сэмплов в буффере
AudioPoint = BUFFERSIZE;
uint8_t Bytes = FileBuff[32];//Байт на сэмпл WAVE
length = BUFFERSIZE*Bytes;//Длинна блока
uint8_t ftime = 1;//В первый раз(антибаг)
while(f_eof(&File))//Пока файл не кончился
{
if(File.Size-File.CurrentByte < length) length = File.Size-File.CurrentByte;//Антибаг
if(f_read(&File, FileBuff, length)) { print("File read error!",0); goto error; }//Чтение
print("R\n\r",0);//Дебаг
i = 0;//Обнуляем указатель
while(i<BUFFERSIZE)//Пока буффер из носителя не будет полностью считан
{
//////////////////////////////////////////////////////////////////////////////
if(i != AudioPoint)//Вот тут вот какая-то херня. Если ячейка буффера ЦАПа освободилась, записываем в неё новое значение
{
L_Buffer[i] = FileBuff[(i*Bytes)+1]<<8;//Заполняем ячейку буффера "звук"
L_Buffer[i] += FileBuff[(i*Bytes)];
L_Buffer[i] ^= 0x8000;
R_Buffer[i] = FileBuff[(i*Bytes)+3]<<8;
R_Buffer[i] += FileBuff[(i*Bytes)+2];
R_Buffer[i] ^= 0x8000;
print("F %d %d\n\r",2,i,AudioPoint);//Дебаг
i += 1;//Добавляем единичку
}
//////////////////////////////////////////////////////////////////////////////
}
if(ftime) { AudioPoint = 0; HAL_TIM_Base_Start_IT(&htim6); ftime = 0; }//В первый проход запускаем таймер
}
ftime = 1;
HAL_TIM_Base_Stop_IT(&htim6);//Файл закончился, останавливаем таймер
print("Done! Thanks!\n\r", 0);//Благодарность
error:
while(1);//Программа закончена
Происходит чтение WAV файла в свободные ячейки буффера. Проблема в том, что в основном коде (где выделено) не срабатывает "if" с включенной оптимизацией.
Код
Вывод с UART при включенной оптимизацией. Не работает!
Opening "A:\EnterSandman.wav"
R
F 0 128
F 1 128
F 2 128
Заполнение буффера
F 126 128
F 127 128
D 128 0
R
F 0 1
D 1 1
D 1 2
D 1 3
И так далее
Opening "A:\EnterSandman.wav"
R
F 0 128
F 1 128
F 2 128
Заполнение буффера
F 126 128
F 127 128
D 128 0
R
F 0 1
D 1 1
D 1 2
D 1 3
И так далее
CODE
Вывод с UART при отключенной оптимизации. Работает!
Opening "A:\EnterSandman.wav"
R
F 0 128
F 1 128
F 2 128
F 3 128
F 4 128
F 5 128
F 6 128
Заполнение буффера
F 124 128
F 125 128
F 126 128
F 127 128
D 128 0
R
F 0 1
D 1 1
F 1 2
D 2 2
F 2 3
D 3 3
F 3 4
D 4 4
F 4 5
D 5 5
F 5 6
D 6 6
F 6 7
D 7 7
И так далее
Opening "A:\EnterSandman.wav"
R
F 0 128
F 1 128
F 2 128
F 3 128
F 4 128
F 5 128
F 6 128
Заполнение буффера
F 124 128
F 125 128
F 126 128
F 127 128
D 128 0
R
F 0 1
D 1 1
F 1 2
D 2 2
F 2 3
D 3 3
F 3 4
D 4 4
F 4 5
D 5 5
F 5 6
D 6 6
F 6 7
D 7 7
И так далее
!Скорость ЦАПа была занижена до 5 Гц чтобы данные для отладки не искажались.
И есть ещё проблема. Дело в том, что с выключенной оптимизацией во время воспроизведения файла звук прерывается... Приоритет у TIM6 стоит 0, у USB флешки, с которой происходит чтение, вообще 5. Использую библиотеку HAL для обслуживания флешки. Чтение идёт по одному кластеру размером в 32 килобайта. Звук прерывается как раз во время чтения с флешки. Запись прикрепил. Думаю, оригинал все знают.
Вот как выглядит дорожка


Запись звука тут https://vk.com/maks_naumchuk?w=wall65222672_7202
Или тут http://rghost.ru/8MMx5y4Gt
Помогите решить хотя-бы одну проблему
Использую CooCox CoIDE и ARM-GCC компилятор.
P.S. почему у меня не получилось ничего убрать под спойлер?..