初级会员

- 积分
- 90
- 金钱
- 90
- 注册时间
- 2016-6-1
- 在线时间
- 27 小时
|
发表于 2016-6-7 09:35:29
|
显示全部楼层
龙哥,能帮我看看这一段代码吗?我是直接从数组里调用音频数据的,不是从外部的存储器件上调用的:
#include "sys.h"
#include "delay.h"
#include "stm32l1xx_gpio.h"
#include "stm32l1xx_rcc.h"
#define SAMPLE_RATE_8000 8000
#define SAMPLE_RATE_11025 11025
#define SAMPLE_RATE_16000 16000
#define SAMPLE_RATE_22050 22050
#define SAMPLE_RATE_44100 44100
#define SAMPLE_RATE_48000 48000
#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)//zhuyi
#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)//zhuyi
void RCC_Init(void);
void RCC_Configuration(void);
void GPIOA_Configuration(void);
void TIM6_Configuration(void);
void DAC1_Configuration(void);
void SystemInit(void);
void DMA2_Configuration(void); //PA->DAC??3
void NVIC_Configuration(void);
uint32_t wavecount;
#define WAVELENGTH 64044
const uint8_t wavedata[64044]={
xxxxxxxxxxxxxxxxxxxx
};
u16 GetARRValue(u16 sample)
{
u16 arrValue;
/* 更新OCA值以符合.WAV文件采样率 */
switch (sample)
{
case SAMPLE_RATE_8000 :
arrValue = (uint16_t)(72000000/8000);
break; /* 8KHz = 2x36MHz / 9000 */
case SAMPLE_RATE_11025:
arrValue = (uint16_t)(72000000/11025);
break; /* 11.025KHz = 2x36MHz / 6531 */
case SAMPLE_RATE_16000:
arrValue = (uint16_t)(72000000/16000);
break; /* 16KHz = 2x36MHz / 4500 */
case SAMPLE_RATE_22050:
arrValue = (uint16_t)(72000000/22050);
break; /* 22.05KHz = 2x36MHz / 2365 */
case SAMPLE_RATE_44100:
arrValue = (uint16_t)(72000000/44100);
break; /* 44.1KHz = 2x36MHz / 1633 */
case SAMPLE_RATE_48000:
arrValue = (uint16_t)(72000000/48000);
break; /* 48KHz = 2x36MHz / 1500 */
default:
arrValue = 0;
break;
}
return arrValue;
}
void TIM6_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //????
//???TIM2???
TIM_TimeBaseStructure.TIM_Period = arr; //???????????????????????????
TIM_TimeBaseStructure.TIM_Prescaler =psc; //??????TIMx???????????
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //??????:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM??????
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //??????????TIMx???????
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE ); //?????TIM2??,??????
//?????NVIC??
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //TIM2??
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //?????0?
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //????3?
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ?????
NVIC_Init(&NVIC_InitStructure); //???NVIC???
// TIM_Cmd(TIM6, ENABLE); //??TIMx
}
void DACInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
DAC_InitTypeDef DAC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能PORTA通道时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); //使能DAC通道时钟
/***********************************************************************************
问:PA4为什么要设置为模拟输入?
答:STM32F103ZET6 的 DAC 通道 1 在 PA4 上,所以,我们先要使能 PORTA 的时钟, 然后设
置 PA4 为模拟输入。 DAC 本身是输出,但是为什么端口要设置为模拟输入模式呢?因为一但
使能 DACx 通道之后,相应的 GPIO 引脚( PA4 或者 PA5)会自动与 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 输出高
TIM6_Int_Init(8999,0);
DAC_DeInit();
// DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
DAC_InitStructure.DAC_Trigger = DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bits8_0;
DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1, &DAC_InitStructure);
DAC_Cmd(DAC_Channel_1, ENABLE);
TIM_Cmd(TIM6, ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
}
/*DMA通道3中断-------------------------*/
void DMAChannel3_IRQHandler(void)
{
if(DMA_GetFlagStatus(DMA2_IT_GL3)!=RESET)
{
DMA_ClearFlag(DMA2_IT_TC3);
DMA_Cmd(DMA2_Channel3, ENABLE);
DMA2_Channel3->CNDTR = 32;
DMA_Cmd(DMA2_Channel3, ENABLE);
}
}
/*RCC_Configuration---------------------------------*/
void RCC_Configuration(void)
{
/*开启相关通道的时钟使能*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
}
/*DMA2_Channle配置----------------------------------*/
void DMA2_Configuration(void)
{
rw_DMA2_CCR3&=0xffff8000;//寄存器清0
rw_DMA2_CPAR3=0x40007410;
rw_DMA2_CMAR3=(u32)&wavedata;
rw_DMA2_CNDTR3=37040;
rw_DMA2_CCR3|=(0<<14);//启动非存储器到存储器模式
rw_DMA2_CCR3|=(0x03<<12);//设置通道优先级为高
rw_DMA2_CCR3|=(0x00<<10);//设置存储数据宽度为8位
rw_DMA2_CCR3|=(0x00<<8);//设置外设数据宽度为8位
rw_DMA2_CCR3|=(1<<7);//启动存储器增量模式
rw_DMA2_CCR3|=(0<<6);//关闭外存储器增量模式
rw_DMA2_CCR3|=(1<<5);//开启循环模式
rw_DMA2_CCR3|=(1<<4);//从存储器读
rw_DMA2_CCR3|=(0<<1);//关闭传输完成中断
// rw_DMA2_CCR3|=(1<<0);//开启通道
// rw_DAC_CR|=(1<<12);//开启DAC->DMA通道
}
int main(void)
{
delay_init(); //延时函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); //串口初始化为9600
DACInit();
while(1)
{
};
}
void TIM6_IRQHandler(void)
{
u16 tmpCap;
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
{
if( wavecount < 48474)
{
tmpCap = wavedata1[wavecount];
wavecount++;
/* Set DAC Channel1 DHR register */
DAC_SetChannel1Data(DAC_Align_8b_R,tmpCap);
}
else
{
// 完成传输,关闭中断
wavecount = 0;
// TIM_ITConfig(TIM6, TIM_IT_Update, DISABLE);
// TIM_Cmd(TIM6, DISABLE);
// // 需要关闭DAC,不然在没有声音的时候会有杂音
// DAC_Cmd(DAC_Channel_1, DISABLE);
}
}
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
} |
|