00-03 52 49 46 46:RIFF的標志
04-07 24 90 01 00 :文件的長度
08-0B 57 41 56 45 :WAVE的標志
0C-0F 66 6D 74 20 :fmt的標志
10-13 10 00 00 00 :編碼的格式類別,10H代表PCM形式。
14-15 01 00 :字塊總數
16-17 01 00 : 通道數 1為單聲道,2為雙聲道
18-1B 80 3E 00 00 :采樣率:每秒采集二進制的位數。
1C-1F 00 7D 00 00 :每秒播放的字節數 = 通道數 x 每秒采集二進制的位數 x 采集數據的位數 / 8. 32000
20-21 02 00 :每個樣點的字節數
22-23 01 00 :每個樣點的數據位數
24-27 64 61 74 61 :data的標志
28-2b:00 90 01 00 文件長度
wav文件長度 3200KB
wav 的頻率為16000
一般WAV數據開始的第44字節開始就是wav數據了,把wav數據取出后直接送到DAC播放。
這里的WAV的dac數據是16bit的需要進行轉換成12bit
voice[i] = voice[i]+0x8000;//16bit dac 數據為補碼形式的,需要進行處理+0x8000
voice[i] = voice[i] >>num; //num 一般為4 右移4位剩下12bit dac數據
設置time定時器的頻率16K的采集率
arrValue = (uint16_t)(72000000/(16000-1));
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鍾使能
//定時器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arrValue ; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =0; //設置用來作為TIMx時鍾頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鍾分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據指定的參數初始化TIMx的時間基數單位
TIM_Cmd(TIM3, ENABLE); //使能TIMx
DAC 進行初始化:
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitType;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ); //使能PORTA通道時鍾
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE ); //使能DAC通道時鍾
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_4) ;//PA.4 輸出高
DAC_InitType.DAC_Trigger=DAC_Trigger_None; //不使用觸發功能 TEN1=0
DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形發生
DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值設置
DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1輸出緩存關閉 BOFF1=1
DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化DAC通道1
DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC1
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //DAC_Align_12b_R 12位右對齊數據格式設置DAC值
TIM3->DIER|=1<<8;//允許更新dma請求
TIM3->DIER|=1<<6;//允許觸發中斷
TIM3->DIER|=1<<0;//允許更新中斷
打開DAC DMA功能
DMA_Cmd(DMA1_Channel3, DISABLE ); //關閉USART1 TX DMA1 所指示的通道
DMA_SetCurrDataCounter(DMA1_Channel3,DMA1_MEM_LEN);//DMA通道的DMA緩存的大小
DMA_Cmd(DMA1_Channel3, ENABLE); //使能USART1 TX DMA1 所指示的通道
這樣就可以把WAV的dac數據通過DMA發送出去了
當一包的DMA數據發送完成后需要更新一包數據進行發送,通過定時器中斷設置標志位后,重新配置數據,
下次改用DMA的中斷試試看。
DMA_Cmd(DMA1_Channel3, DISABLE );
DAC_DMA_Config(DMA1_Channel3,(u32)&DAC->DHR12R1,(u32)DAC_SIN_BUF,DAC_SIN_SIZE);
DMA_SetCurrDataCounter(DMA1_Channel3,DMA1_MEM_LEN);//DMA通道的DMA緩存的大小
DMA_Cmd(DMA1_Channel3, ENABLE); //使能USART1 TX DMA1 所指示的通道
直到把數據發送完,簡單的播放wav數據就完成了。