崩溃了,板子掉头了,返回去这么久都杳无音信,再不发点什么我的想法都发霉了。
算了,不等板子了,先发想法,板子回来再试验。
第一辑,好吊丝,好音乐。
听音乐,怎么弄?好多童鞋都推荐我使用I2S,只要连接到一个小芯片,一顿送数据,就搞定了,不错不错。
然后我翻看各种资料,终于被我发现了,……这句话!
“注:EEWORLD
不提供设计经费(包括元器件、PCB+打样等)支持!
”
好,本吊丝果断放弃该方案。
没有了I2S,用什么办法呢?于是乎问题回归其本源……真是巧呢,最近也一直有网友在研究声音问题,用单片机的PWM回放复杂的声音。
不不不,这太本源了,事实上,我们的429i有其利器,那就是DAC。这样的话,我们只需要一个喇叭和两根接线就OK了。神马?你说没有喇叭,那你太吊丝了,还听什么音乐,自己唱好了;或者你可以像我一样把肾卖掉买个iPhone,然后把上面的喇叭拆下来待用。
又于是,我们要了解声音的有关信息,主要是在数字世界的声音。
其实也很简单,声音嘛,每个1秒中采样有限个数据样本,每个数据样本有限个数据位数。
比较常见的,44KHz,16位采样率,就是说,每次用ADC采16位的数据作为一个样本,每秒钟采44000个样本。
所以要想听到声音,反过来咯。每次用DAC产生一个电压,每秒钟产生44000个。
太多了吧,我看我们这次还是先听点音质差的:8KHz,8位采样——我们的DAC最大支持到12位,至于频率嘛,我说了我现在没有板子,凭空想象的,8KHz设置频率,应该没问题,不行再想别的办法!
然后就是操作啦,
首先你应当有音乐的数据。还在同WinXP的孩纸们方便啦,使用录音机就可以很方便的搞出个上述指标的声音文件,然后找个16进制编辑器把其中的声音数据抓出来形成一个大型的数组——OK,这就是数据源啦。
接下来,我们到官网上找到429i评价板的官方例程,从中取出:DAC_SignalsGeneration
官方例程里产生了一堆波形,我作为一个好吊丝我不想看波形,我只想听音乐,于是乎拿里面的代码改吧。从正弦函数图像入手就可以了。
- const uint16_t Sine12bit[32] = {
- 2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
- 3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
- 599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
从源代码中我们可以看到正弦波形就是用数组来实现的,把数组里的内容顺序送给DAC,漂亮的波形就产生了。同样的,只要把我们的音乐数据顺序送给DAC,……莫名其妙的声音就能出来……前提是你已经
把喇叭串联在DAC输出口和地线之间了。木有板子,我现在主观认为产生的波形应该是莫名其妙的声音。因为DMA的设定,送给DAC的数据的频率,可能不是8KHz的,而且明显的,源程序送数是16位的,我们的声音是8位的。所以还有好多参数要调整正确啊。
接下来调整参数:
1.送数改为8位,原来16位的代码在此,看看里面有几个参数
狠明显的需要修改呢,没有实验就没有真知,所以我先不提供修改方案了。
- void DAC_Ch2_SineWaveConfig(void)
- {
- DMA_InitTypeDef DMA_InitStructure;
-
- /* DAC channel2 Configuration */
- DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
- DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
- DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
- DAC_Init(DAC_Channel_2, &DAC_InitStructure);
-
- /* DMA1_Stream5 channel7 configuration **************************************/
- DMA_DeInit(DMA1_Stream5);
- DMA_InitStructure.DMA_Channel = DMA_Channel_7;
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS;
- DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&Sine12bit;
- DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
- DMA_InitStructure.DMA_BufferSize = 32;
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
- DMA_InitStructure.DMA_Priority = DMA_Priority_High;
- DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
- DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
- DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
- DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
- DMA_Init(DMA1_Stream5, &DMA_InitStructure);
-
- /* Enable DMA1_Stream5 */
- DMA_Cmd(DMA1_Stream5, ENABLE);
-
- /* Enable DAC Channel2 */
- DAC_Cmd(DAC_Channel_2, ENABLE);
-
- /* Enable DMA for DAC Channel2 */
- DAC_DMACmd(DAC_Channel_2, ENABLE);
- }
起始不提供修改方案,更重要的一个原因就是,这个DMA可能无法设定成8KHz的频率来送数,这不符合DMA思想,这样做不科学……
十有八九,我们的第二个问题:
2.设定送数频率为8KHz,有可能需要使用一个定时器来做了,还是定时器比较王道啊,呵呵。
嗯嗯,这下思路清楚了,就坐等板子归来调试了。
意淫之中,板子已经开始演奏美妙的音乐了。……
——本辑结束——
片花:
……尼玛,你怎么把喇叭直接按在引脚上啦……而且空间不够啊,每次换个歌都得重新烧啊……我还想用屏幕看歌词啊有木有……音质好差啊,还有木有好办法啊,啊啊~……
本帖最后由 sjtitr 于 2014-1-10 15:44 编辑