51单片机驱动VS1003(模拟spi/自带SPI)
来源:互联网 发布:javascript 清空数组 编辑:程序博客网 时间:2024/05/18 11:47
<pre name="code" class="cpp">
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">本文章使用STC单片机驱动VS1003,(STC自带SPI和模拟SPI)</span>
VS1003使用指南,中文数据手册,MP3格式说明戳http://download.csdn.net/detail/sparkstrike/7980637
单片机:STC12C5A60S2 晶振24MHZ
一.通信部分:
1.STC12C5A60S2自带SPI(VS1003的spi通信是高位先发送,需在SPCTL中设置)
//初始化spivoid init_spi(void){SPCTL = 0xdd;//忽略SS,设置主机,spi高位先发送SPSTAT = 0xc0;//清除状态寄存器SPDAT = 0;//初始化数据寄存器}void spi_write(unsigned char sendData){SPDAT = sendData;while((SPSTAT&0x80)==0);SPSTAT = 0xc0;//清除状态寄存器SPSTAT = 0;}
unsigned char bdata dat; //可位寻址的变量dat,用于优化SPIsbit dat7=dat^7; //取出每一个位sbit dat6=dat^6;sbit dat5=dat^5;sbit dat4=dat^4;sbit dat3=dat^3;sbit dat2=dat^2;sbit dat1=dat^1;sbit dat0=dat^0;sbit SI =P1^5;sbit SCLK =P1^7; sbit SI =P1^5;sbit SCLK =P1^7;void spi_write(unsigned char x){ dat=x; //将x赋值给可位寻址的变量dat SI=dat7; //从高位开始输出,从dat7一直到dat0 SCLK=0; //时钟的上升沿,位被写出 SCLK=1; SI=dat6; SCLK=0; SCLK=1; SI=dat5; SCLK=0; SCLK=1; SI=dat4; SCLK=0; SCLK=1; SI=dat3; SCLK=0; SCLK=1; SI=dat2; SCLK=0; SCLK=1; SI=dat1; SCLK=0; SCLK=1; SI=dat0; SCLK=0; SCLK=1;}
void SPI_W(unsigned char Data){unsigned char i;for(i = 0; i<8; i++){Data <<= 1;SCLK = 0;SI = CY;//CY位是单片机在作移位运算时溢出的一位SCLK = 1;};SI = 1;}
左移 <<
0100 1111 << 左移一位:1001 1110 CY=0 ;第一位跑到CY上,最后一位补0 ;
在keil c51中,内部函数库INTRINS.H中_crol_(m,n)表示将m循环左移n位:第一位的跑到最后一位上。
右移>>
1000 1111 >> 右移一位 0100 0111 CY=1 ;第一位补0,最后一位跑到CY上;
二.VS1003引脚定义
XRESET 低电平复位
DREQ 数据请求脚
XCS SCL命令写入片选
XDCS SDI(mp3数据)写入片选
SO 串行输出,在读操作时,数据在 SCK 的下降沿处从此脚移出,在写操作时为高阻态。
SI 串行输入,如果片选有效,SI 就在 SCLK的上升沿处采样。
SCLK 时钟
三.发送SCI命令
VS1003的DREQ 脚,在 VS1003 的 FIFO 在能够接受数据的时候输出高电平。此时,VS1003 可获取至少 32Byte 的 SDI数据或一个 SCI 命令。遵循这个标准,当 DREQ 变低时,发送器必须停止发送新的数据。
注意:在每次 SCI 操作后,DREQ 线被置 0。VS1003 靠此期间操作。不允许在 DREQ 变为 1 之前开始新的SCI/SDI 操作。
发送SCI命令的顺序:
首先等待DREQ脚为高电平,再将 XCS 片选拉低以选择芯片,再通过 SI 线发送8 位的读操作码( 0x02)和 8 位的地址。随即发送 16 位的数据字。 当最后一位被移入且最后的时钟已发送,必须将 XCS 拉高以完成写操作。
具体地址和数据字说明见资料/VS1003使用指南/P5
void wr_command(unsigned char addr,unsigned char hdat,unsigned char ldat ){ DREQ=1; while(!DREQ);//等待直到VS1003可以接受数据 XCS=0; //开SCI片选 spi_write(0x02);//发送读操作码 spi_write(addr);//地址 spi_write(hdat);//数据字高位 spi_write(ldat);//数据字地位 XCS=1;//关<span style="font-family: Arial, Helvetica, sans-serif;">SCI片选</span>}
四.初始化V是1003
一般初始化流程:
●硬复位,xReset = 0;
●延时,xDCS、xCS、xReset置1;
●等待DREQ为高;
●软件复位:SPI_MODE = 0x0804;
●等待DREQ为高(软件复位结束);
●设置VS1003的时钟:SCI_CLOCKF = 0x9800,3倍频;
●设置VS1003的采样率:SPI_AUDATA = 0xBB81,采样率48k,立体声;
●设置重音:SPI_BASS = 0x0055;
●设置音量:SCI_VOL = 0x2020;
●向vs1003发送4个字节无效数据,用以启动SPI发送。
void Mp3Reset(void){ XRESET=0; delay(100); XDCS=XCS=XRESET=1; wr_command(0x00,0x08,0x04); delay(10); DREQ=1; while(!DREQ); wr_command(0x03,0x98,0x00);<span style="white-space:pre"></span>//设置VS1003的时钟:SCI_CLOCKF = 0x9800,3倍频 delay(10); wr_command(0x05,0xbb,0x81);<span style="white-space:pre"></span>//设置VS1003的采样率:SPI_AUDATA = 0xBB81,采样率48k,立体声 delay(10); wr_command(0x02,0x00,0x55);<span style="white-space:pre"></span>//设置重音:SPI_BASS = 0x0055; delay(10); wr_command(0x0b,0x10,0x10); // 音量 delay(10); spi_write(0);//向vs1003发送4个字节无效数据,用以启动SPI发送 spi_write(0); spi_write(0); spi_write(0);}
五.向VS1003写入音频数据
注意:写音频数据时要开启SDI片选XDS
void send_dat(unsigned char dat) { DREQ=1; while(!DREQ); //VS1003的DREQ为高才能写入数据 spi_write(dat);//通过SPI向VS1003写入一个字节的音频数据}
六.完整程序
注:程序用音频数据music戳http://download.csdn.net/detail/sparkstrike/7980613
1.模拟spi:
/********vc1003程序(模拟SPI)*************************************************************************************/#include <STC12C5A60S2.H> //单片机头文件sbit led = P0^0;sbit XRESET =P0^7; sbit DREQ =P0^4;sbit XCS =P0^6;sbit XDCS =P0^5;sbit SO =P1^6;sbit SI =P1^5;sbit SCLK =P1^7;<pre name="code" class="cpp">unsigned char bdata dat; //可位寻址的变量dat,用于优化SPIsbit dat7=dat^7; //取出每一个位sbit dat6=dat^6;sbit dat5=dat^5;sbit dat4=dat^4;sbit dat3=dat^3;sbit dat2=dat^2;sbit dat1=dat^1;sbit dat0=dat^0;void delay(unsigned int time){while(time--);} void spi_write(unsigned char x){ dat=x; //将x赋值给可位寻址的变量dat SI=dat7; //从高位开始输出,从dat7一直到dat0 SCLK=0; //时钟的上升沿,位被写出 SCLK=1; SI=dat6; SCLK=0; SCLK=1; SI=dat5; SCLK=0; SCLK=1; SI=dat4; SCLK=0; SCLK=1; SI=dat3; SCLK=0; SCLK=1; SI=dat2; SCLK=0; SCLK=1; SI=dat1; SCLK=0; SCLK=1; SI=dat0; SCLK=0; SCLK=1;}void wr_command(unsigned char addr,unsigned char hdat,unsigned char ldat ){ DREQ=1; while(!DREQ); XCS=0; spi_write(0x02); spi_write(addr); spi_write(hdat); spi_write(ldat); XCS=1;}void Mp3Reset(void){ XRESET=0; delay(100); XDCS=XCS=XRESET=1; wr_command(0x00,0x08,0x04); delay(10); DREQ=1; while(!DREQ); wr_command(0x03,0x98,0x00); delay(10); wr_command(0x05,0xbb,0x81); delay(10); wr_command(0x02,0x00,0x55); delay(10); wr_command(0x0b,0x10,0x10); // 音量 delay(10); spi_write(0); spi_write(0); spi_write(0); spi_write(0);}void send_dat(unsigned char dat) { DREQ=1; while(!DREQ); //VS1003的DREQ为高才能写入数据 spi_write(dat);//通过SPI向VS1003写入一个字节的音频数据}void main(){unsigned int i;Mp3Reset();XDCS=0;for(i=0;i<15000;i++){send_dat(music[i]);}while(1);}
2.自带spi
#include <STC12C5A60S2.H> //单片机头文件//VS1003IOsbit XRESET =P0^7; sbit DREQ =P0^4;sbit XCS =P0^6;sbit XDCS =P0^5;void delay_ms(int i){int a,b;for(a=0;a<i;a++){for(b=0;b<600;b++);};}//******************vs1003操作*************************************************************************************************//初始化spivoid init_spi(void){SPCTL = 0xdd;//忽略SS,设置主机,spi高位先发送SPSTAT = 0xc0;//清除状态寄存器SPDAT = 0;//初始化数据寄存器}void spi_write(unsigned char sendData){SPDAT = sendData;while((SPSTAT&0x80)==0);SPSTAT = 0xc0;//清除状态寄存器SPSTAT = 0;}void delay(unsigned int time){while(time--);}void wr_command(unsigned char addr,unsigned char hdat,unsigned char ldat ){ DREQ=1; while(!DREQ); XCS=0; spi_write(0x02); spi_write(addr); spi_write(hdat); spi_write(ldat); XCS=1;}//vs1003初始化void Mp3Reset(void){ XRESET=0; delay(100); XDCS=XCS=XRESET=1; wr_command(0x00,0x08,0x04); delay(10); DREQ=1; while(!DREQ); wr_command(0x03,0x98,0x00); delay(10); wr_command(0x05,0xbb,0x81); delay(10); wr_command(0x02,0x00,0x55); delay(10); wr_command(0x0b,0x2e,0x2e); // 音量 delay(10); spi_write(0); spi_write(0); spi_write(0); spi_write(0);}//向VS1003写入一个字节的音频数据,写之前要打开XDCS片选,XDCS=0void send_dat(unsigned char dat) { DREQ=1; while(!DREQ);//VS1003的DREQ为高才能写入数据 spi_write(dat);//通过SPI向VS1003写入一个字节的音频数据}void main(){<pre name="code" class="csharp"><span style="white-space:pre"></span>unsigned int i;
<span style="white-space:pre"></span>init_spi();Mp3Reset();XDCS=0;for(i=0;i<15000;i++){<span></span>send_dat(music[i]);}while(1);<span style="font-family: Arial, Helvetica, sans-serif;"></span>}
附1:正弦测试
x调整正弦频率
void Sintest(unsigned char x){ wr_command(0x00,0x08,0x20); DREQ=1; while(!DREQ); XDCS=0;XCS=1; spi_write(0x53); spi_write(0xef); spi_write(0x6e); spi_write(x); spi_write(0); spi_write(0); spi_write(0); spi_write(0); delay(5000); spi_write(0x45); spi_write(0x78); spi_write(0x69); spi_write(0x74); spi_write(0); spi_write(0); spi_write(0); spi_write(0); delay(5000); XDCS=1;}
- 51单片机驱动VS1003(模拟spi/自带SPI)
- 单片机 模拟SPI程序
- 单片机模拟spi通信
- 51单片机 主从机模拟 spi通讯
- SPI的模拟驱动
- spi驱动--IO模拟
- 单片机spi驱动SD卡
- ((硬件spi+dma)+模拟spi)驱动LCD5110
- 51 软件模拟SPI驱动OLED
- Linux系统自带SPI接口驱动自测
- Linux系统自带SPI接口驱动自测
- linux自带spi驱动 ,可自己配置CS
- Linux系统自带SPI接口驱动自测
- 单片机项目:驱动VS1003模块(二)
- linux SPI驱动 - 模拟gpio
- STM8S1003 模拟SPI 驱动 SI4432
- STM8S1003 模拟SPI 驱动 SI4432
- MCS-51系列单片机模拟SPI总线的方法
- listview的某个item选中后,条目颜色不消失。(实现方法一)
- 笔试、面试重点总结:WIN32、MFC与Linux
- 李亚鹏离婚前写给王菲的信疯传 内容矛盾
- 生成dll文件以及python对DLL中函数的调用(参数类型以及返回值)
- zoj 2250 - Grandpa is Famous
- 51单片机驱动VS1003(模拟spi/自带SPI)
- PB程序设计-创建窗口实例
- Linux常用命令大全
- java bloclqueue
- 打印 Log
- 只为逼格?超薄便携式无线充电设备Deuce
- Hibernate关联关系映射之一对一关联关系
- error RC2108: expected numerical dialog constant
- cordova sqlite 手势密码