这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » Renesas » 天籁齐舞★USBHost对USB从设备供应商ID和产品ID等信息的读取★

共34条 3/4 1 2 3 4 跳转至
助工
2012-12-04 23:06:20     打赏
21楼
【语音平台开发进程】:硬件架构图

经过前面的简单的程序测试,到后来的VS1053B库函数的编制,发现一个很棘手的问题,就是程序逻辑一样,确得到不同的结果,有时甚至是同样的程序,多运行几遍,便会得出不同的结果,由此,我推断可能是由于SPI在较高速度数据传输时,对连接线的长度有要求,而我在之前的SPI测试中使用的就是普通的杜邦线,可能杜邦线过长造成SPI通信误码现象的产生。
       为了减小主板MCU与VS1053B模块之间连接线的长度,本设计采用转接板的形式将两者的接口通过在转接板上“布线”而连接起来,具体的实物图如下图所示:
先来张系统总体架构图:


再来张去掉VS1053B模块的系统架构图:


这张是转接板背面的特写:


再来张稍加改造的主板:


最好再来张VS1053B模块图:


OK,接下来准备进行VS1053B库调试工作,希望能够得到满意的结果,谢谢!Good Luck!


助工
2012-12-04 23:09:37     打赏
22楼

还没呢,这不正调试着SPI呢,要上文件系统,估计要好好研究研究!哈哈,你琢磨出来了,到时参考你的啊!


助工
2012-12-06 14:16:57     打赏
23楼
是这样的,SAKURA开发板上提供的USB默认的功能为大容量存储器的功能,对于PC机来说,USB的大容量存储器的驱动是默认自带的、通用的,所以就像普通的U盘一样,安装好之后就可以自动安装,可以直接使用,不会提示用户去安装驱动程序。如果用户想扩展USB的功能用来做虚拟串口来用,则在需要的时候,可由用户来自行安装,安装好之后,到该用之时系统就会自动调用,“一次安装,终身使用”嘿嘿!,好了其它的不说了,直接说虚拟串口驱动的下载地址吧:
http://share.eepw.com.cn/share/download/id/79366
安装好后,下一步就是像普通驱动寻一样就可以使用了
如果还遇到了串口号冲突的问题,还可以参考campozeng的技术问题贴:
http://forum.eepw.com.cn/thread/223263/1
希望能够帮到你

共同学习,一起进步!

助工
2012-12-07 11:06:23     打赏
24楼

【语音平台开发进程】:SPI读操作最高速测试--1.5MHz
最近一直在进行SPI的调试工作,在调试的过程中不免有些单调,就在VS1053B库调试之余,想测一下我搭建的这款硬件系统的SPI到底能跑到多高的速度,这在SPI读写参数设置中也算是一个参考吧!
以下是我按照有快到慢的速度逐步对SPI进行测试的:
当SPI.setClockDivider(SPI_CLOCK_DIV4)时,即SPI的时钟速度为12MHz时SPI读操作失败!如下图所示:

当SPI.setClockDivider(SPI_CLOCK_DIV8)时,即SPI的时钟速度为6MHz时SPI读操作失败!如下图所示:

当SPI.setClockDivider(SPI_CLOCK_DIV16)时,即SPI的时钟速度为3MHz时SPI读操作部分成功!如下图所示:

当SPI.setClockDivider(SPI_CLOCK_DIV32)时,即SPI的时钟速度为1.5MHz时SPI读操作完全成功!如下图所示:

如以上图中所示,目前已将两个VS1053B库函数调通,这两个库函数分别为:
void VS_Init(void);
用于SPI的初始化;
unsigned int VS_RD_Reg(unsigned char address);
用于读取特定地址的寄存器的值。

OK,共同学习,一起进步!


助工
2012-12-10 11:34:31     打赏
25楼
【语音平台开发进程】:VS1053B芯片的SPI驱动程序编写完成
经过近一周的编写和调试,昨天,正式将VS1053B芯片的SPI驱动程序编写和调试完毕,在编写和调试的过程中也吸取了许多经验和教训,现总结如下:
1、首先,用最原始的方法在主函数里先将SPI对VS1053B芯片的简单控制实现。
2、在最原始的方法上对上述控制进行头文件的简单改写,采用边改写,边调试的方法,这一步目的不再于要实现多么强大的驱动功能,而在于将整个驱动的整体框架搭建起来,以便于在下一步中在向其中添加功能的同时,而又不破坏整个架构的完整性。
3、一步步按照
预先的规划逐步完善程序的功能,同样也是边编写边调试。
4、最后,整理出正个驱动程序,写出Demo主程序测试函数,以便于演示和测试。
下面将编写好的驱动程序贴于下面,以便于大家学习和提出宝贵的意见和建议:
VS1053B.h头文件程序:

#ifndef __VS10XX_H__
#define __VS10XX_H__
#include <rxduino.h>


#define SPI_MODE 0x00
#define SPI_STATUS 0x01
#define SPI_BASS 0x02
#define SPI_CLOCKF 0x03
#define SPI_DECODE_TIME 0x04
#define SPI_AUDATA 0x05
#define SPI_WRAM 0x06
#define SPI_WRAMADDR 0x07
#define SPI_HDAT0 0x08
#define SPI_HDAT1 0x09

#define SPI_AIADDR 0x0a
#define SPI_VOL 0x0b
#define SPI_AICTRL0 0x0c
#define SPI_AICTRL1 0x0d
#define SPI_AICTRL2 0x0e
#define SPI_AICTRL3 0x0f


#define VS_DQ PIN_P23 //DREQ
#define VS_RST PIN_P22 //RST
#define VS_XCS PIN_PC4 //XCS--SPI_CS0--IO10
#define VS_XDCS PIN_PC1 //XDCS--SPI_CS2--IO23

unsigned int VS_RD_Reg(unsigned char address);
void VS_WR_Data(unsigned long data);
void VS_WR_Data_Test(unsigned long data);
void VS_WR_Cmd(unsigned char address,unsigned int data);
void VS_Init(void);
void VS_HD_Reset(void);
void VS_Soft_Reset(void);
void VS_Ram_Test(void);
void VS_Sine_Test(void);
void Set1053B(void);
unsigned int GetDecodeTime(void);
void ResetDecodeTime(void);
unsigned int GetHeadInfo(void);

#endif

VS1053B.cpp,作为VS1053B.h的功能实现函数库

#include "VS1053B.h"
#include <spi.h>
//#include <rxduino.h>

unsigned char VS1053Bram[5]={2,10,2,6,250};
unsigned long SPItemp;
const unsigned int bitrate[2][16]=
{
{0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}
};

unsigned int GetHeadInfo(void)
{
unsigned int HEAD0;
unsigned int HEAD1;
HEAD0=VS_RD_Reg(SPI_HDAT0);
HEAD1=VS_RD_Reg(SPI_HDAT1);
//printf("(H0,H1):%x,%x\n",HEAD0,HEAD1);
switch(HEAD1)
{
case 0x7665:return 0;//WAV格式
case 0X4D54:return 1;//MIDI格式
case 0X574D://WMA格式
{
HEAD1=HEAD0*2/25;
if((HEAD1%10)>5)return HEAD1/10+1;
else return HEAD1/10;
}
default://MP3格式
{
HEAD1>>=3;
HEAD1=HEAD1&0x03;
if(HEAD1==3)HEAD1=1;
else HEAD1=0;
return bitrate[HEAD1][HEAD0>>12];
}
}
}

void VS_WR_Cmd(unsigned char address,unsigned int data)
{
unsigned long WRCmdreg;
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
//SPI.setClockDivider(SPI_CLOCK_DIV64);
WRCmdreg=(0x02<<24)+(address<<16)+data;
SPItemp=SPI.transfer(WRCmdreg);

}

unsigned int VS_RD_Reg(unsigned char address)
{
unsigned long RDreg;
unsigned int RDregreturn;
while(digitalRead(VS_DQ)==0);

SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
RDreg=(0x03<<24)+(address<<16);
SPItemp=SPI.transfer(RDreg);
RDregreturn = (unsigned int) SPItemp;
return RDregreturn;
}

unsigned int GetDecodeTime(void)
{
return VS_RD_Reg(SPI_DECODE_TIME);
}

void ResetDecodeTime(void)
{
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
VS_WR_Cmd(SPI_DECODE_TIME,0x0000);
}

void VS_WR_Data(unsigned long data)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV64);
SPI.port=SPI_PORT_CS2_MARY2;
SPItemp=SPI.transfer(data);
}

void VS_WR_Data_Test(unsigned long data)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS2_MARY2;
SPItemp=SPI.transfer(data);
}

void VS_Sine_Test(void)
{
VS_HD_Reset();
VS_WR_Cmd(SPI_VOL,0X0505);
VS_WR_Cmd(SPI_MODE,0x0820);
while(VS_DQ== 0);
VS_WR_Data_Test(0x53ef6e2400000000);
delay(500);

VS_WR_Data_Test(0x4578697400000000);
delay(500);

VS_WR_Data_Test(0x53ef6e4400000000);
delay(500);

VS_WR_Data_Test(0x4578697400000000);
delay(500);
}

void VS_Ram_Test(void)
{
unsigned int regvalue;
VS_HD_Reset();
VS_WR_Cmd(SPI_MODE,0x0820);
while (VS_DQ==0); // 等待DREQ为高
VS_WR_Data_Test(0x4dea6d5400000000);
delay(500);
regvalue=VS_RD_Reg(SPI_HDAT0);
Serial.println(regvalue, BIN); //output the result in HEX
delay(500);
regvalue=VS_RD_Reg(SPI_MODE);
Serial.println(regvalue, BIN); //output the result in HEX

}

void VS_Init(void)
{
pinMode(VS_XCS,OUTPUT);
pinMode(VS_RST,OUTPUT);
pinMode(VS_DQ,INPUT);
digitalWrite(VS_RST,0);
delay(500);
digitalWrite(VS_RST,1);
delay(500);
SPI.begin();

//Serial.begin(9600); //set baudrate 9600bps
SPI.port=SPI_PORT_CS0_DUINO;
SPI.setBitOrder(MSBFIRST);
SPI.setBitLength(32);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.setDataMode(SPI_MODE0);
}

void VS_Soft_Reset(void)
{
while(digitalRead(VS_DQ)==0);
SPI.setClockDivider(SPI_CLOCK_DIV128);
SPI.port=SPI_PORT_CS0_DUINO;
VS_WR_Cmd(SPI_MODE,0X0804);
delay(3);
while(digitalRead(VS_DQ)==0);
VS_WR_Cmd(SPI_CLOCKF,0x7800);
VS_WR_Cmd(SPI_AUDATA,0xBB81);

}

void VS_HD_Reset(void)
{
digitalWrite(2,0);
delay(2000);
digitalWrite(VS_XDCS,1);
digitalWrite(VS_XCS,1);
digitalWrite(VS_RST,1);
}

void Set1053B(void)
{
unsigned char t;
unsigned int bass=0;
unsigned int volt=0;
unsigned char vset=0;
vset=255-VS1053Bram[4];
volt=vset;
volt<<=8;
volt+=vset;
//0,henh.1,hfreq.2,lenh.3,lfreq
for(t=0;t<4;t++)
{
bass<<=4;
bass+=VS1053Bram[t];
}
VS_WR_Cmd(SPI_BASS,bass);//BASS
//delay(50);
VS_WR_Cmd(SPI_VOL,volt);
}

 


助工
2012-12-10 11:36:47     打赏
26楼

gr_sketch.cpp,主函数,Demo示例程序,测试功能用

#include "VS1053B.h"
//#include <spi.h>

unsigned int res;

void setup()
{
pinMode(PIN_LED0,OUTPUT);
VS_Init();
Serial.begin(9600); //set baudrate 9600bps
}

void loop()
{
digitalWrite(PIN_LED0,1); //set led0 on
while(!Serial.available()); //wait command from upper computer
char c=Serial.read();
if(c=='r') //if receive command 'r'
{
VS_HD_Reset();
VS_Soft_Reset();
Set1053B();
res= VS_RD_Reg(SPI_MODE);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_STATUS);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_BASS);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_CLOCKF);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_DECODE_TIME);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AUDATA);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_WRAM);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_WRAMADDR);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_HDAT0);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_HDAT1);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AIADDR);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_VOL);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AICTRL0);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AICTRL1);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AICTRL2);
Serial.println(res, BIN); //output the result in BIN
delay(500);
res= VS_RD_Reg(SPI_AICTRL3);
Serial.println(res, BIN); //output the result in BIN
delay(500);
VS_Sine_Test();
VS_Ram_Test();

}
else if(c=='t')
{
VS_HD_Reset();
}

else
{
Serial.println("Please send the right SPI command!");
}
digitalWrite(PIN_LED0,0); //turn off the led0
}


助工
2012-12-13 15:34:21     打赏
27楼

最近,实习公司那边要我们实习生参加年会节目表演,业余时间就要用来练习交谊舞,这不忙里偷闲,整理出一篇文档:“Ardiuno开发板上的mini-SD卡读写
文中首先介绍了SAKURA开发板上的mini-SD卡读写所用的库函数;其次,介绍了对SD卡进行操作所必须的一些库函数:例如:begin open read write close等;最后,給出一个对SD卡读写的例子。
文档下载链接:

http://share.eepw.com.cn/share/download/id/83421

由于文档较大,就不直接贴在帖子里,帖子留着让大家给我指点迷津,相互交流之用吧!


助工
2012-12-19 15:20:12     打赏
28楼
【语音平台开发进程】:MP3音乐文件解析
对于准备播放MP3格式的音乐来说,解析MP3格式的声音文件是必须的,在参考了“MP3文件解析”一文后得知了传说中的MP3文件的帧头格式:
帧头长4字节,对于固定位率的MP3文件,所有帧的帧头格式一样其数据结构如下: 

          
为了更详细地说明MP3文件的格式,如下是在VC++中打开一个名为test.mp3文件,其内容如下:
000000 FF FB 52 8C 00 00 01 49 09 C5 05 24 60 00 2A C1
000010 19 40 A6 00 00 05 96 41 34 18 20 80 08 26 48 29
000020 83 04 00 01 61 41 40 50 10 04 00 C1 21 41 50 64 
……
0000D0 FE FF FB 52 8C 11 80 01 EE 90 65 6E 08 20 02 30 
0000E0 32 0C CD C0 04 00 46 16 41 89 B8 01 00 08 36 48
0000F0  33 B7 00 00 01 02 FF FF FF F4 E1 2F FF FF FF FF
……
0001A0 DF FF FF FB 52 8C 12 00 01 FE 90 58 6E 09 A0 02
0001B0 33 B0 CA 85 E1 50 01 45 F6 19 61 BC 26 80 28 7C
0001C0 05 AC B4 20 28 94 FF FF FF FF FF FF FF FF FF FF
……
001390 7F FF FF FF FD 4E 00 54 41 47 54 45 53 54 00 00
0013A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
……
0013F0 00 00 00 00 04 19 14 03 00 00 00 00 00 00 00 00
001400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
001410 00 00 00 00 00 00 4E
该文件长度1416H(5.142K),帧头为:FF FB 52 8C,转换成二进制为:
11111111 11111011
01010010 10001100  
对照MP3帧头帧格式可知,test.mp3帧头信息见下表: 



第1397H开始的三个字节是54 41 47,存放的是字符“TAG”,表示此文件有ID3 V1.0信息。
139AH开始的30个字节存放歌名,前4个非00字节是54 45 53 54,表示“TEST”;
13F4H开始的4个字节是04 19 14 03,存放年份“04/25/2003”;
最后1个字节是4E,表示音乐类别,代号为78,即“Rock&Roll”;
其它字节均为00,未存储信息。

在了解了mp3文件的格式之后,将逐步在SAKURA开发板上实现对mini-SD卡上的mp3文件数据的读取。。。

助工
2012-12-25 09:41:55     打赏
29楼

是通过板子上的USB接口虚拟的串口,具体的设置方式可参考如下链接:
http://forum.eepw.com.cn/thread/222049/2#15


助工
2012-12-25 10:15:20     打赏
30楼
【语音平台开发进程】:mp3文件的实测解析
为了能够更好地理解mp3音频文件的工作机理,特通过一个短小的test.mp3文件,通过SPI模式的mini-SD读写库函数来读取其上存储的test.mp3文件,然后将文件以16进制代码的形式在串口调试助手上显示出来。下图是通过其以文本文件的形式将16进制数据存储为文件的截图:

看到这漫无边际的数字串,相信大家和我一样也都小晕了,不过文件和协议就是这个样子的,在你不了解之前看似是杂乱无章,当真正了解其文件或协议格式之后,就很容易理解其中的含义了。为了使对mp3文件感兴趣的E友们能够很快理解其中的含义,我对其中的关键的部分作了必要的解析:

测试文件名:test.mp3

文件大小:5.23KB

比特率:48kbps

mp3播放时长:1 S

通过实测:

5461-27=5434 Byte=5.31KB

mp3文件返回的数据头为:

49 44 33 04

 I  D  3  EOT(传输结束)

此语句标识之后一些片段为ID3V2信息,其中包含了作者,作曲,专辑等信息,长度不固定,扩展了mp3文件最后的ID3V1的信息量。

接下来为ID3V2信息的内容:

00 00 00 00 00 17 54 53 53 45 00 00 00 0D 00 00 03 4C 61 76 66 35 32 2E 37 37 2E 30 00

            TB T  S  S  E        ER     ETX L  a  v  f 5  2  .  7 7  .  0

00:nul(无字符串)

TB:信息组传输结束

ER:回车键

ETX:正文结束

Lavf52.77.0为mp3编码方式的编码方案

整体翻译下来为:

“TSSE: Lavf52.77.0”(其中不包括双引号)

接下来为帧数据,每个帧数据都有一个帧头,帧头大小为4个字节,如下所示:

FF FB 30 64

FF:同步字节,所有位均为1,同步字节总共为11位,即

1111 1111 111A ABBC

1111 1111 1111 1011

AA:版本信息,11-MPEG 1

BB:层信息,01-Layer 3

C:CRC校验信息,1-不校验

30: 0011 0000

   DDDD EEFG

DDDD:位率,对于V1L3,0011-48kbps(与在电脑中显示的位率相同)

EE:采样率,对于MPEG-1,00-44.1kHz

F:帧长调节,用来调整文件头长度,0-无需调整,

G:保留字,没有使用

64: 0110 0100

   HHII JKLL

HH:声道模式,01-Joint Stereo(联合立体声,即在编码时考虑双声道的相关性进行编码)

II:声道的扩充模式,当声道模式为01时才使用,10-强度立体声关,MS立体声开

J:版权,文件是否合法,0-不合法

K:原版标志,是否原版,1-原版

LL:强调方式,用于声音经降噪压缩后再补偿的分类,00-未定义

接下来就是每一帧的帧内容了,如下所示:

00 0F F0 00 00 69 00 00 00 08 00 00 0D 20 00 00 01 00 00 01 A4 00 00 00 20 00 00 34 80 00 00 04 00 00 C0 00 00 00 18 0E 03 00 00 00 00 0F FD 2F FF FF FF BA 94 21 FF 84 87 98 59 FF 40 00 00 00 40 04 08 00 00 07 FF F3 1F FF 77 E8 DE 0E 0C EC C5 7C 6E FE 7F FF FE A7 17 F3 BF 0E 28 21 CF FF E7 19 FF FF E7 10 FE A7 E7 1C 0F DF E6 7F A0 5F FC 92 9E FF 7F 12 88 0E 39 FF FE 78 C0 F0 7A 34 78 03 2D 37 BB DF 91 2E F7 7A 2B DF D5 41 CA B3 48 CD D5 FD 94 41 CB AD

细数之下,发现总共为152字节,再加上帧头文件的4个字节总共=156字节=156x8bit=1248bit,大家是否还记得,解析获得本test.mp3文件的比特率为48kbps(注意:这里的k=1000),所以每帧的播放时间=1248/(48*1000)*1000=26ms,这也就是mp3文件协议里对每帧数据播放时间的要求。当然,有的帧文件的大小稍多一个或两个字节即153字节或154字节,这是通过帧文件中的F:帧长调节,用来调整帧文件的长度,也就是当帧头的第3个字节为30(16进制)时帧长为正常值152,当其为32时说明帧的长度增加,此时就告知mp3解码器该帧文件正常结束后还有1到2字节的帧内容需要传输。

如下为各帧帧头的第三字节,帧内容的长度和帧内容:

30 152

00 0F F0 00 00 69 00 00 00 08 00 00 0D 20 00 00 01 00 00 01 A4 00 00 00 20 00 00 34 80 00 00 04 00 00 C0 00 00 00 18 0E 03 00 00 00 00 0F FD 2F FF FF FF BA 94 21 FF 84 87 98 59 FF 40 00 00 00 40 04 08 00 00 07 FF F3 1F FF 77 E8 DE 0E 0C EC C5 7C 6E FE 7F FF FE A7 17 F3 BF 0E 28 21 CF FF E7 19 FF FF E7 10 FE A7 E7 1C 0F DF E6 7F A0 5F FC 92 9E FF 7F 12 88 0E 39 FF FE 78 C0 F0 7A 34 78 03 2D 37 BB DF 91 2E F7 7A 2B DF D5 41 CA B3 48 CD D5 FD 94 41 CB AD

32 154

3C 0F F0 00 00 69 00 00 00 08 00 00 0D 20 00 00 01 00 00 01 A4 00 00 00 20 00 00 34 80 00 00 04 E1 7C 80 3E B4 00 33 79 0B DD E7 B6 7D 53 B9 0E 8D F4 38 98 39 5A 78 31 B8 2F 40 64 5D 6F BE 40 BA 1A C7 75 CD 2B 16 9A 22 B2 C2 D4 32 EB 79 04 A8 F7 48 9D 86 0D 0A C5 6D AC 4F 5C A6 8D 94 9D 66 DC 08 3F 1B AF F4 C4 D0 21 C5 97 C2 D8 08 55 8D 34 47 F9 E4 77 26 15 62 8B 91 88 EC 19 2B 32 2E 30 58 2E 94 9D 72 09 25 49 7E 1C 8A 71 5C 91 0C 92 5A E0 EF 1F 78 D1 59 19


共34条 3/4 1 2 3 4 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]