暴走的指压师

为何中年妇女对14岁正太不理不睬?28岁大妈是如何保持14岁身材与脸颊?三无蓝毛究竟身在何处?为何少年抛弃妹子去寻找基友的菊花,大妈抛弃正太去和眼镜妹百合? 一切的一切,请看《Q ヱヴァンゲリヲン新劇場版:Q 》
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

pic32 + Vs1003 正弦测试通过

Posted on 2011-03-08 13:29  晓彻  阅读(2060)  评论(0编辑  收藏  举报

从昨天下午一直弄到早上,耳机里面终于传来的久违的调子。正弦测试通过了。

vs1003芯片集成得相当好,据说支持双通道,不过要高保真音效的话还要其他芯片支持。

首先,检查硬件和接线是必须的。接线最好一个一个的测试联通性,能够测出高低电平的就先测高低电平。

开始的调试时候,连gpio都有问题,和爽哥一起调了几个小时,被一顿数落。神马PORTxSET和PORTxCLR寄存器都没搞清楚就一下子正弦测试。。。囧

之后需要检查spi收发数据是否正常,由于没有示波器(我只好说SoftwareAcademy太小气...),便使用这个spi驱动Pmodcls LCD模块,lcd正常显示字符,spi也就可以用了。

gpio接口io和spi没有问题后,开始读寄存器。后来发现至少有两点没有注意:一是spi的速率和模式控制,datasheet要求时钟在SCLK/6以下,模式肯定暂时只能用8位传输。第二、关于Mode和Status寄存器的值。这个Status寄存器会在100ms后自动变为0x30,这也就是为什么一直测到的是30的原因。

接下来写寄存器。没有读写寄存器的测试,给VS1003发送命令和数据无从谈起。

一切完毕后,可以进行正弦测试了。

开始时,一点声音都没有,没辙。www上搜了一下,发现VOL音量寄存器的设置太小,而且每次正弦测试的间隔太小以至于无法听出声音来。

现在做音频播放器的门槛越来越低了,好多电子友都自己动手制作。我运气还不错,仅用了一天时间,而且寄送过来的芯片也没bug。总的说来从硬件到软件的测试过程是:连线-->GPIO-->SPI--->Read Registers--->Write Registers-->Sine Test

下面贴一下初始化和读写寄存器的代码:

1 #include "vs1003.h"
2 #include "player.h"
3 #include "spi.h"
4 //-----------------------------------------------------------------
5 // transport driver for vs1003 on PIC32
6 // xiaoyang yi
7 //-----------------------------------------------------------------
8 #define VS1003_DEBUG 1
9
10 //VS1003 config data [0,henh.1,hfreq.2,lenh.3,lfreq 5,volumn]
11 int8u_t vs1003ram[5]={0,0,0,0,250};
12
13 void delay_ms(unsigned int num)
14 {
15 unsigned int i = num * 1024;
16 while( (i--) > 0 ){
17 ;
18 }
19 }
20 //
21 // 保存VS1003的设置
22 // EEPROM地址:486~490 共五个
23 //
24 void Save_VS_Set(void)
25 {
26 int8u_t t;
27 for(t=0;t<5;t++)
28 ;//save data to pic32
29 //FM24C16_WriteOneByte(488+t,vs1003ram[t]);//vs1003ram保存
30 }
31
32 //
33 // 读取VS1003的设置
34 // EEPROM地址:486~490 共五个
35 //
36 void Read_VS_Set(void)
37 {
38 int8u_t t;
39 for(t=0;t<5;t++)
40 ;
41 //vs1003ram[t]=FM24C16_ReadOneByte(488+t);//vs1003ram调用
42 //
43 }
44
45 //------------------------------------------------------------------------------
46 // write cmd to vs1003
47 // address,data
48 //------------------------------------------------------------------------------
49 // write cmd as following:
50 // 1.等待DREQ为高(当DREQ为低时,说明芯片还没有就绪)
51 // 2.将XCS(命令片选)拉低
52 // 3.写入0x02
53 // 4.写入寄存器地址
54 // 5.分别写入数据的高字节与低字节
55 // 6.将XCS置高
56 //------------------------------------------------------------------------------
57 void Vs1003_CMD_Write(int8u_t address,int16u_t data)
58 {
59 unsigned char high = data >> 8;
60 unsigned char low = data;
61 printf("Write_cmd:%2x,%2x\n",high, low);
62
63 //wait for free
64 while((PORTE & MP3_DREQ ) == 0)
65 ;
66 //MP3_DCS_DES(); //MP3_DATA_CS=1;
67
68 MP3_CCS_DES();
69 delay_ms(1);
70 MP3_CCS_SEL(); //MP3_CMD_CS=0;pull down XCS
71
72 spi2_8TxRx(VS_WRITE_COMMAND);//send write command
73 spi2_8TxRx(address); //send addr
74 //spi2_16TxRx(data);
75 spi2_8TxRx(high); //8bits high of data
76 spi2_8TxRx(low); //8bits low of data
77
78 MP3_CCS_DES(); //MP3_CMD_CS=1;
79 }
80
81 int16u_t Vs1003_CMD_Read(int8u_t address)
82 {
83 int16u_t data;
84
85 //wait for free
86 while((PORTE & MP3_DREQ ) == 0)
87 ;
88 //pull down XCS
89 MP3_CCS_SEL();
90
91 //send cmd:VS_READ_COMMAND
92 spi2_8TxRx(VS_READ_COMMAND);
93 //senb addr
94 spi2_8TxRx(address);
95
96 //get the uint16 data
97 data = spi2_8TxRx(0X00);
98 data <<= 8;
99 data += spi2_8TxRx(0X00);
100
101 MP3_CCS_DES();
102 return data;
103 }
104 //------------------------------------------------------------------------------
105 // configure vs1003
106 // address,data
107 //------------------------------------------------------------------------------
108 // 1.硬件复位:接XRESET拉低
109 // 2.延时,将XDCS、XCS、XRESET置高
110 // 3.向MODE中写入0X0804
111 // 4.等待DREQ为高
112 // 5.设置VS1003的时钟:SCI_CLOCKF=0x9800,3倍频
113 // 6.设置VS1003的采样率:SPI_AUDATA=0xbb81,采样率48k,立体声
114 // 7.设置重音:SPI_BASS=0x0055
115 // 8.设置音量:SCI_VOL=0x2020
116 // 9.这一步被很多人忽视,向VS1003发送4个字节的无效数据,用以启动SPI发送
117 //---------------------------------------------------------------------------
118 void Vs1003_Init(void)
119 {
120 char i = 0;
121 int16u_t data = 0x0;
122
123 SPI2_SELECT();
124 TRISECLR |= (1 << 0)|(1 << 1)|(0 << 2)|(1 << 3);//set pins
125
126 MP3_RST_SET(0);
127 delay_ms(100);
128
129 MP3_CCS_DES(); //set cs pin high/low
130 MP3_RST_SET(1); //reset
131 MP3_DCS_DES(); //xcs = 0;
132
133
134 #if VS1003_DEBUG
135 Vs1003_CMD_Write(SPI_MODE,0xeeee);
136 printf("vs1003 init:begin\n");
137 data = Vs1003_CMD_Read(SPI_MODE);
138 printf("Read REGS, SPI_MODE=%x\nWrite SPI_MODE...\n",data);
139 Vs1003_CMD_Write(SPI_MODE,0x0804);
140 data = Vs1003_CMD_Read(SPI_MODE);
141 printf("Read REGS agin, SPI_MODE=%x\n",data);
142 #endif
143
144 Vs1003_CMD_Write(SPI_MODE,0x0804);
145 //wait for DREQ==1
146 while( (PORTE & MP3_DREQ ) == 0 )
147 ;
148
149 //step 6-9
150 Vs1003_CMD_Write(SPI_CLOCKF,0x9800);
151 delay_ms(1);
152 Vs1003_CMD_Write(SPI_AUDATA,0XBB81);
153 delay_ms(1);
154 Vs1003_CMD_Write(SPI_BASS,0x0055);
155 delay_ms(1);
156 Vs1003_CMD_Write(SPI_VOL,0x2020);
157 delay_ms(1);
158
159 //向vs1003发送4个字节无效数据,用以启动SPI发送
160 MP3_DCS_SEL();//选中数据传输
161 spi2_8TxRx(0XFF);
162 spi2_8TxRx(0XFF);
163 spi2_8TxRx(0XFF);
164 spi2_8TxRx(0XFF);
165 MP3_DCS_DES();//取消数据传输
166 delay_ms(200);
167 #if VS1003_DEBUG
168 printf("vs1003 init:init over\n");
169 #endif
170 }
171
172 //-------------------------------------------------------------------------
173 //正弦测试
174 // 1.进入VS1003的测试模式:SPI_MODE=0X0820
175 // 2.等待DREQ为高
176 // 3.将XDCS接低,而XCS要置高,选择VS1003的数据接口
177 // 4.向VS1003发送正弦测试命令:0X53 0XEF 0X6E 0X30 0X00 0X00 0X00 0X00
178 // 其中0X30为频率,用户可以修改为其它值
179 // 5.延时一段时间
180 // 6.退出正弦测试,发送命令:0X45 0X78 0X69 0X74 0X00 0X00 0X00 0X00
181 // 7.延时一段时间
182 // 8.循环以上流程
183 //-------------------------------------------------------------------------
184 void Vs1003_Sine_Test(unsigned char x)
185 {
186 #if VS1003_DEBUG
187 int16u_t data = 0x0;;
188 printf("Vs1003_Sine_Test:begin\nGet in SinTest Mode\n");
189 #endif
190 Vs1003_CMD_Write(SPI_MODE,0x0820);//进入vs1003的测试模式
191
192 #if VS1003_DEBUG
193 data = Vs1003_CMD_Read(SPI_MODE);
194 printf("Read REGS-SIN, SPI_MODE=%x\n",data);
195 #endif
196 while ((PORTE & MP3_DREQ ) == 0)
197 ;//等待DREQ为高
198
199 //向vs1003发送正弦测试命令:0x53 0xef 0x6e n 0x00 0x00 0x00 0x00
200 //其中n = 0x24, 设定vs1003所产生的正弦波的频率值,具体计算方法见vs1003的datasheet
201 SPI2_SELECT();
202 MP3_CCS_DES();
203 MP3_DCS_SEL();//选中数据传输
204
205 spi2_8TxRx(0x53);
206 spi2_8TxRx(0xef);
207 spi2_8TxRx(0x6e);
208 spi2_8TxRx(x);
209 spi2_8TxRx(0x00);
210 spi2_8TxRx(0x00);
211 spi2_8TxRx(0x00);
212 spi2_8TxRx(0x00);
213 delay_ms(100);
214
215 spi2_8TxRx(0x45);
216 spi2_8TxRx(0x78);
217 spi2_8TxRx(0x69);
218 spi2_8TxRx(0x74);
219 spi2_8TxRx(0x00);
220 spi2_8TxRx(0x00);
221 spi2_8TxRx(0x00);
222 spi2_8TxRx(0x00);
223 MP3_DCS_DES();
224
225 #if VS1003_DEBUG
226 printf("Vs1003_Sine_Test:end\n");
227 #endif
228 }
229
230 //用于测试vs1003的各个模块
231 void Vs1003_Test()
232 {
233 int i = 0;
234 int16u_t data;
235 spi2_init();
236 Vs1003_Init();
237 /*
238 给音量控制寄存器SCI_VOL循环写入最高值和最低值,正常情况下能从耳机听到滴滴
239 的声音,具体步骤如下:
240 ●拉低xCS;
241 ●设置音量最高:SCI_VOL = 0x0000;
242 ●拉高xCS;
243 ●等待500ms,这个时间控制在0.5到1s之间,太大太小可能都无法听到;
244 ●拉低xCS;
245 ●设置音量最低:SCI_VOL = 0xFFFF;
246 ●等待500ms,道理同上;
247 ●拉高xCS;
248 ●循环,否则以上步骤无法识别。
249 */
250
251 do{
252 data = 0x0;
253 printf("Test Start,Reg Vol data=%d\n",data);
254 Vs1003_CMD_Write(SPI_VOL,0x2020);
255 data = Vs1003_CMD_Read(SPI_VOL);
256 printf("Test end, Reg VOL data=%x\n",data);
257 delay_ms(1000);
258 }while(0);
259
260 while(1){
261 for(i = 0;i < 15;i++)
262 {
263 Vs1003_Sine_Test(i); //使正弦波的频率依次增加,适当延时,这样在耳机中就能听到音调越来越高的声音
264 }
265 for(i = 15; i > 0; i++)
266 {
267 Vs1003_Sine_Test(i);
268 }
269 }
270 }