我的小爱好项目似乎有点麻烦。
[这个月,我尝试通过DMA从SD卡向DAC输出运行一个16bit 48kHz的波形文件。
但是...我得到的只是可怕的声音。我阅读了很多ST Electronics数据表,但没有解决问题的方法。
首先尝试使用HAL驱动程序,但只能使用阵列中的正弦波形。不是wave文件。
所以我切换到用于DMA,TIM6和DAC的低层驱动器。
这里是我的主要init来源
LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_1); // enable DMA for Channel1
LL_DAC_Enable(DAC1, LL_DAC_CHANNEL_1); //enable Channel on DAC
LL_DMA_ConfigAddresses(DMA1, LL_DMA_STREAM_5,(uint32_t) &DAC_Buff, LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED ), LL_DMA_DIRECTION_MEMORY_TO_PERIPH ); //Speicherbereich auf den die DMA Unit zugreift definieren
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, 2); // die beschreibung in UM1725 ist heir etwas dürftig ich hab einfach mal 16 für 2byte genommen
LL_DMA_EnableIT_HT(DMA1,LL_DMA_STREAM_5); // Halb Transfer Interrupt für Sream5 aktivieren
LL_DMA_EnableIT_TC(DMA1,LL_DMA_STREAM_5); // Complet Transfer Interrupt für Sream5 aktivieren
LL_DAC_EnableTrigger(DAC1, LL_DAC_CHANNEL_1); // ohne geht garnix, aber wenn an muss man __disable_irq machen
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5); //Stream5 DAC1 Starten
我读取文件的源工作正常
char wave_playback(const char *FileName)
{
FRESULT res;
FIL file;
UINT cnt;
uint32_t filesize;
res = f_open( &file, FileName, FA_READ ); //file oeffne
if(res) return 1;
filesize= f_size(&file);
res = f_lseek(&file,0x2c); // WAV head überspringen
// filesize=filesize-0x2c;
if(res) return 2;
f_read (&file,&DAC_Buff[0],512,&cnt); //beider 256 Buffer befüllen
//filesize=filesize-512;
if(res) return 3;
__disable_irq();
//TIM6->CR1 |= TIM_CR1_CEN;
LL_TIM_EnableCounter(TIM6); // Timer 6 der DMA triggert starten
while(1)
{
volatile ITStatus it_st;
it_st = RESET;
while(it_st == RESET) { //auf Flag für halben Transfer warten
it_st = LL_DMA_IsActiveFlag_HT5(DMA1);
//it_st = READ_BIT(DMA1->HISR ,DMA_HISR_HTIF5);
}
f_read (&file,&DAC_Buff[0],256,&cnt); //unteren buffer befüllen
LL_DMA_ClearFlag_HT5(DMA1); // half transfer flag (stream5) löschen
// DMA1->HISR |= DMA_HISR_HTIF5;
// filesize=filesize-256;
if(cnt<256)break; //wenn das ende des files erreicht while verlassen
it_st = RESET;
while(it_st == RESET) { ////auf Flag für kompletten Transfer warten
it_st = LL_DMA_IsActiveFlag_TC5(DMA1);
//it_st = READ_BIT(DMA1->HISR ,DMA_HISR_TCIF5);
}
f_read (&file,&DAC_Buff[256],256,&cnt); //oberen buffer befüllen
LL_DMA_ClearFlag_TC5(DMA1); //complet transfer flag (stream5) löschen
//DMA1->HISR |= DMA_HISR_TCIF5;
// filesize=filesize-256;
if(cnt<256)break; //wenn das ende des files erreicht while verlassen
}
//TIM6->CR1 &= ~TIM_CR1_CEN; // Roh Kommando Timer 6 der DMA triggert stoppen
LL_TIM_DisableCounter(TIM6); // Timer 6 der DMA triggert stoppen
f_close(&file); //file stream beenden
return 0; //bei wenn i.O. 0 zurueck geben
}
我检查了两次SD卡上的Wave文件(16bit 48kHz),但是声音很恐怖,我不明白为什么。
然后我使用HAL驱动程序再次尝试,但是没有任何效果,所以我切换回LL驱动程序
我拧了什么?有人知道吗?
感谢erik
可能您正在播放的数据中有字节或字节的字节序问题。尝试切换到8位模式:
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_5, LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED));
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_5, LL_DMA_MDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_5, LL_DMA_MDATAALIGN_BYTE);