为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > 基于MSP430F5529的MP3

基于MSP430F5529的MP3

2017-10-16 50页 doc 212KB 67阅读

用户头像

is_977556

暂无简介

举报
基于MSP430F5529的MP3基于MSP430F5529的MP3 2015年长江大学电子设计竞赛 基于MSP430F5529的MP3设计 2015年5月6日 摘 要 本系统主要由MSP430F5529单片机和VS1003音频解码芯片组成,MCU通过SPI串行协议读取SD卡的音频文件,将音频文件发送给VS1003音频解码,解码后的音频信号经功率放大器放大后驱动电声转换器件发出声响,系统另外 配备有由键盘和LCD组成的人机交互功能,整个系统简洁、功能完善。 。 I 目 录 1系统方案 ...............................
基于MSP430F5529的MP3
基于MSP430F5529的MP3 2015年长江大学电子竞赛 基于MSP430F5529的MP3设计 2015年5月6日 摘 要 本系统主要由MSP430F5529单片机和VS1003音频解码芯片组成,MCU通过SPI串行协议读取SD卡的音频文件,将音频文件发送给VS1003音频解码,解码后的音频信号经功率放大器放大后驱动电声转换器件发出声响,系统另外 配备有由键盘和LCD组成的人机交互功能,整个系统简洁、功能完善。 。 I 目 录 1系统 ....................................................................................................................... 1 1.1主控的论证与选择 ............................................................................................... 1 1.2 音频解码的论证与选择 ....................................................................................... 1 1.3 控制系统的论证与选择 ......................................................... 错误~未定义书签。 2系统理论分析与计算 ..................................................................................................... 1 2.1 XXXX的分析 ..................................................................... 错误~未定义书签。 2.1.1 XXX ............................................................................ 错误~未定义书签。 2.1.2 XXX ............................................................................ 错误~未定义书签。 2.1.3 XXX ............................................................................ 错误~未定义书签。 2.2 XXXX的计算 ........................................................................ 错误~未定义书签。 2.2.1 XXX ............................................................................ 错误~未定义书签。 2.2.2 XXX ............................................................................ 错误~未定义书签。 2.2.3 XXX ............................................................................ 错误~未定义书签。 2.3 XXXX的计算 ........................................................................ 错误~未定义书签。 2.3.1 XXX ............................................................................ 错误~未定义书签。 2.3.2 XXX ............................................................................ 错误~未定义书签。 2.3.3 XXX ............................................................................ 错误~未定义书签。 3电路与程序设计 ............................................................................................................ 1 1电路的设计 .......................................................................................................... 1 3. 3.1.1系统总体框图............................................................................................. 1 3.1.2 SD卡子系统框图与电路原理图 .................................................................. 2 3.1.3音频放大子系统框图与电路原理图 ............................................................. 2 3.1.4电源........................................................................................................... 3 3.2程序的设计 .......................................................................................................... 3 3.2.1程序功能描述与设计思路 ........................................................................... 3 3.2.2程序................................................................................................ 3 4测试方案与测试结果 ..................................................................................................... 3 4.1测试方案 ............................................................................................................. 3 4.2 测试条件与仪器 .................................................................... 错误~未定义书签。 4.3 测试结果及分析 .................................................................................................. 4 4.3.1测试结果(数据) ............................................................ 错误~未定义书签。 4.3.2测试分析与结论 ......................................................................................... 4 附录1:电路原理图 ......................................................................................................... 5 附录2:源程序 ................................................................................................................ 6 II 基于MSP430F5529的MP3 【熊平波组】 1系统方案 本系统主要由MSP430F5529模块、VS1003模块、SD卡模块、电源模块组成,下面分别论证这几个模块的选择。 1.1 主控芯片的论证与选择 方案一:51单片机。 51单片机出现年代较早,所以各种资料也非常的多,实现起来比较简单,达不到学习锻炼的目的,所以只以他作为一个参考。 方案二:STM32单片机 STM32单片机虽然是近几年推出的单片机,但它以强大的性能,低廉的价格很快的占领了市场,目前这方面的资料也是非常的多,并且个人对这一型号的处理器不是很了解,所以也放弃选用。 方案三:MSP430单片机 MSP430是TI公司现在主推的单片机型号,也是历年电子设计大赛所大量选用的处理器型号,它具有极低功耗,超强模拟外设。 综合以上三种方案,选择方案三。 1.2音频解码的论证与选择 方案一:AD+滤波器 。 由单片机直接将SD卡里面WAV格式的音频文件传送到AD转换器,进行音频输出,优点是操作简单,成本低,缺点是音质较差 方案二:VS1003音频解码芯片。 VS1003是由芬兰 VLSI 公司出品的一款单芯片的MP3/WMA音频解码芯片,其 拥有一个高性能低功耗的 DSP 处理器核VS_DSP,5K的指令 RAM,0.5K的数据 RAM,串行的控制和数据输入接口,4 个通用 IO 口,一个 UART 口,同时片内带有一个 可变采样率的 ADC、一个立体声 DAC 以及音频耳机放大器。性能优良,操作简单 综合以上二种方案,选择方案二。 2系统理论分析与计算 3电路与程序设计 3.1电路的设计 3.1.1系统总体框图 系统总体框图如图1所示 1 Nokia511液晶 VS1003 音频放大 MSP430F5529 SD卡 键盘+红外 图1 系统总体框图 3.1.2 SD卡子系统电路原理图 2、SD卡子系统电路 图2 SD卡子系统电路 3.1.3 音频放大子系统框图与电路原理图 2、音频放大子系统电路 2 图3 音频放大子系统电路 3.1.4电源 电源由变压部分、滤波部分、稳压部分组成。为整个系统提供5V或者12V电压,确保电路的正常稳定工作。这部分电路比较简单,都采用三端稳压管实现,故不作详述。 3.2程序的设计 3.2.1程序功能描述与设计思路 1、程序功能描述 根据题目要求软件部分主要实现键盘的设置和显示。 1)键盘实现功能:设置音量、对比度、选歌。 2)显示部分:歌曲、演唱者、频谱、码率、时长、音量。 2、程序设计思路 3.2.2程序流程图 1、主程序流程图 4测试方案与测试结果 4.1测试方案 1、硬件测试 2、软件仿真测试 3 3、硬件软件联调 4.3 测试结果及分析 4.3.2测试分析与结论 根据上述测试数据,XXXXXXXXXXXXXXXXXXXXXXXXXXXXX,由此可以得出以下结论: 1、 2、 3、 综上所述,本设计达到设计要求。 4 附录1:实物图 5 附录2:源程序 /* * LCD5110.h * * Created on: 2014-11-22 * Author: xiongpb */ #ifndef LCD5110_H_ #define LCD5110_H_ #include #define uchar unsigned char #define uint unsigned int //延时宏定义 #define CPU_F ((double)4000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) //枚举 D/C模式选择 typedef enum //emum为枚举常量 { DC_CMD = 0, //写命令 DC_DATA = 1 //写数据 } DCType; #define LCD_CLK_L P2OUT &= ~BIT2 //低电平 #define LCD_CLK_H P2OUT |=BIT2 //高电平 //数据输入端口 #define LCD_DIN_L P7OUT &= ~BIT4 //低电平 #define LCD_DIN_H P7OUT |=BIT4 //高电平 //数据/命令选择 #define LCD_DC_L P8OUT &= ~BIT1 //低电平 #define LCD_DC_H P8OUT |=BIT1 //高电平 //芯片使能 #define LCD_CE_L P4OUT &= ~BIT3 //低电平 #define LCD_CE_H P4OUT |=BIT3 //高电平 6 //串行输入复位 #define LCD_RST_L P4OUT &= ~BIT0 //低电平 #define LCD_RST_H P4OUT |=BIT0 //高电平 void LCD_write_byte(unsigned char data, DCType dc); void LCD5110_Init(void); void LCD5110_SetContrast(unsigned char contrast); void LCD5110_Clear(void); void LCD_Set_XY(unsigned char X, unsigned char Y); void LCD_WriteChar(unsigned char x,unsigned char y,unsigned char c); void LCD_WriteString(unsigned char X,unsigned char Y,char *s); void LCD_WriteNum(unsigned char X,unsigned char Y,unsigned int num); void LCD_Write_12X16Font(unsigned char x,unsigned char y,unsigned char *c); void LCD_DrawPicture(unsigned char X,unsigned char Y,unsigned char const *map, unsigned char Pix_x,unsigned char Pix_y); void LCD_Write_12X16FontS(unsigned char x,unsigned char y,unsigned char *c); void LCD_Write_12X16FontS_TB(unsigned char x,unsigned char y,unsigned char *c); #endif /* LCD5110_H_ */ /* * Nokia5110.c * * Created on: 2014-10-26 * Author: xiongpb */ //------------------------------------------------------------------- // Nokia5510指令集 // D7 D6 D5 D4 D3 D2 D1 D0 // 0 0 1 0 0 PD V H // | | |_______1->扩展指令集 0->基本指令集 // | |___________1->垂直寻址 0->水平寻址 // |_______________1->低功耗模式 0->正常模式 //------------------------------------------------------------------- // 显示模式 // D7 D6 D5 D4 D3 D2 D1 D0 // 0 0 0 0 1 D 0 E // | |_______0 0 1 1 7 // |_______________0 1 0 1 // 白屏 正常 全显 反转 //------------------------------------------------------------------- /******************************************************* 文件名 : Nokia5110Lcd.c 描述 : 诺基亚 5110 LCD 驱动源文件 作者 : xiongpb 编辑器 : CCS5.3 日期 : 2014-10-25 *******************************************************/ #include"LCD5110.h" #include #include"font.h" /*********************************************************************** ****************** * 函数名称:LCD5110_IO_Init() * 函数功能:I0口初始化 * 入口参数:无 * 出口参数:无 * 说明:无 *************************************************************************** **************/ void LCD5110_IO_Init() { /* P6DIR |=BIT5; P3DIR |=BIT4; P3DIR |=BIT3; P1DIR |=BIT6; P6DIR |=BIT6;*/ P2DIR |=BIT2; P7DIR |=BIT4; P8DIR |=BIT1; P4DIR |=BIT3; P4DIR |=BIT0; } /*********************************************************************** ****************** 8 * 函数名称:LCD5110_Init(void) * 函数功能:5110初始化 * 入口参数:无 * 出口参数:无 * 说明:无 *************************************************************************** **************/ void LCD5110_Init(void) { LCD5110_IO_Init(); //I0口初始化 LCD_RST_L; // 产生一个让LCD复位的低电平脉冲 delay_us(150); LCD_RST_H; LCD_CE_H; delay_ms(1); LCD_CE_L; //5110片选有效,允许输入数 //设置LCD LCD_write_byte(0x21, DC_CMD); //使用扩展命令设置LCD模式 LCD_write_byte(0xC8, DC_CMD);//设置偏置电压 LCD_write_byte(0x06, DC_CMD); //温度校正 LCD_write_byte(0x13, DC_CMD); //1:48 LCD_write_byte(0x20, DC_CMD); //使用基本命令。并设置V=0,水平寻址 LCD5110_Clear(); //清屏 LCD_write_byte(0x0C, DC_CMD);//设定显示模式,正常显示 LCD5110_SetContrast(70); //对比度为68 LCD_CE_L; // 关闭LCD } /*********************************************************************** ****************** * 函数名称:LCD5110_SetContrast(unsigned char contrast) * 函数功能:设置LCD对比度 * 入口参数:contrast 对比度(范围: 0~127) * 出口参数:无 * 说明:无 9 *************************************************************************** **************/ void LCD5110_SetContrast(unsigned char contrast) { LCD_write_byte(0x21, DC_CMD); LCD_write_byte(0x80 | contrast, DC_CMD); LCD_write_byte(0x20, DC_CMD); } /*********************************************************************** ****************** * 函数名称:LCD_write_byte(unsigned char data, DCType dc) * 函数功能:向LCD发送数据 * 入口参数:data:数据 dc:DC_CMD = 0//写命令 DC_DATA = 1 //写数据 * 出口参数:无 * 说明:无 *************************************************************************** **************/ void LCD_write_byte(unsigned char data, DCType dc) { unsigned char i; LCD_CE_L; //5110片选有效,允许输入数据 if (dc==DC_CMD) LCD_DC_L; //发送命令 else LCD_DC_H; //发送数据 for(i=0;i<8;i++) //传送8bit数据 { if(data&0x80) LCD_DIN_H; else LCD_DIN_L; LCD_CLK_L; data = data << 1; LCD_CLK_H; } LCD_CE_H; //禁止5110 } /*********************************************************************** ******************* 10 * 函数名:LCD_Set_XY * 功能: 设置LCD坐标 * 参数: X:0-83 Y:0-5 * 返回值:无 * 备 注: *********************************************************************** *******************/ void LCD_Set_XY(unsigned char X, unsigned char Y) { LCD_write_byte(0x40 | Y,DC_CMD);// column 列 LCD_write_byte(0x80 | X,DC_CMD);// row 行 } /*********************************************************************** ****************** * 函数名称:LCD5110_Clear(void) * 函数功能: LCD清屏函数 * 入口参数:无 * 出口参数:无 * 说明:无 *************************************************************************** **************/ void LCD5110_Clear(void) { unsigned char t; unsigned char k; LCD_Set_XY(0, 0);//设置RAM起始地址 for(t=0;t<6;t++) { for(k=0;k<84;k++) { LCD_write_byte(0x00, DC_DATA); } } } /*********************************************************************** ****************** * 函数名称:void LCD_WriteChar(unsigned char x,unsigned char y,unsigned char c) * 函数功能: LCD清屏函数 * 入口参数:无 11 * 出口参数:无 * 说明:无 *************************************************************************** **************/ void LCD_WriteChar(unsigned char x,unsigned char y,unsigned char c) { unsigned char i; c -= 32; //数组的行号 LCD_Set_XY(x,y); for(i=0; i<12; i++) { LCD_write_byte(font6x12[c][i], DC_DATA); if(i==5) { y++; LCD_Set_XY(x,y); } } } /* ********************************************************** *函数名:LCD_WriteString *功能: LCD写6X8的字符串 *参数:X , Y , S *返回值:无 备 注: ********************************************************** */ void LCD_WriteString(unsigned char X,unsigned char Y,char *s) { while(*s) { LCD_WriteChar(X,Y,*s); s++; X += 6; } } /* *************************************************************** 12 *函数名:LCD_WriteNum(unsigned int num) *功能:写入数字 *参数:num *返回值:无 **************************************************************** */ void LCD_WriteNum(unsigned char X,unsigned char Y,unsigned int num) { unsigned char str[8],i=0,len=0; unsigned int temp; temp = num; while(temp) { temp /=10; len++; } if(!num) { len++; str[0]=0x30; } str[len] = 0; while(num) { str[len-i-1] = num%10 + 0x30; num /=10; i++; } LCD_WriteString(X,Y,(char *)str); } /* ********************************************************** *函数名:LCD_Write_16X16Font *功能: 写一个16X16的汉字 *参数:x , y , c[2] x:0-83 y:0-5 *返回值:无 *备 注: ********************************************************** */ void LCD_Write_12X16Font(unsigned char x,unsigned char y,unsigned char *c) { unsigned char i,k; LCD_Set_XY(x-12,y); 13 for(k=0; k<5; k++) //K的值表示汉字库最多存放的字的数量(可改大) { if((font12x16[k].Index[0]==c[0])&&(font12x16[k].Index[1]==c[1])) { for(i=0; i<24; i++) { LCD_write_byte(font12x16[k].Msk[i], DC_DATA); if(i==11) { y++; LCD_Set_XY(x-12,y); } } } } } /* ********************************************************** *函数名:LCD_Write_16X16FontS *功能: 写一串16X16的汉字 *参数:x , y , c[2] x:0-83 y:0-5 *返回值:无 *备 注: ********************************************************** */ void LCD_Write_12X16FontS(unsigned char x,unsigned char y,unsigned char *c) { while(*c) {LCD_Write_12X16Font((x=x+12), y, c); c += 2;} //一个汉字GB码 由2个字节组成 } /* ********************************************************** *函数名:LCD_Write_16X16Font *功能: 取反写一个16X16的汉字 *参数:x , y , c[2] x:0-83 y:0-5 *返回值:无 *备 注: ********************************************************** */ void LCD_Write_12X16Font_TB(unsigned char x,unsigned char y,unsigned char *c) { 14 unsigned char i,k; LCD_Set_XY(x-12,y); for(k=0; k<5; k++) //K的值表示汉字库最多存放的字的数量(可改大) { if((font12x16[k].Index[0]==c[0])&&(font12x16[k].Index[1]==c[1])) { for(i=0; i<24; i++) { LCD_write_byte(~font12x16[k].Msk[i], DC_DATA); if(i==11) { y++; LCD_Set_XY(x-12,y); } } } } } /* ********************************************************** *函数名:LCD_Write_16X16FontS *功能:取反写一串16X16的汉字 *参数:x , y , c[2] x:0-83 y:0-5 *返回值:无 *备 注: ********************************************************** */ void LCD_Write_12X16FontS_TB(unsigned char x,unsigned char y,unsigned char *c) { while(*c) {LCD_Write_12X16Font_TB((x=x+12), y, c); c += 2;} //一个汉字GB 码由2个字节组成 } /* ********************************************************** *函数名:LCD_DrawPicture *功能: 绘图 *参数: X、Y :位图绘制的起始X、Y坐标; *map :位图点阵数据; 15 Pix_x :位图像素(长) <=84 Pix_y :位图像素(宽) <=48 *返回值:无 *备 注: ********************************************************** */ void LCD_DrawPicture(unsigned char X,unsigned char Y,unsigned char const *map, unsigned char Pix_x,unsigned char Pix_y) { unsigned int i,n; unsigned char row; //计算位图所占行数 if (Pix_y%8==0) //如果为位图所占行数为整数 row=Pix_y/8; else row=Pix_y/8+1; //如果为位图所占行数不是整数 LCD_Set_XY(X,Y); for (n=0;n检测
函数 } /*********************************************************************** ******************************* * 名 称:P1_IODect() * 功 能:判断是否有键被按下,哪个键被按下,并调用相应IO的中断事 件处理函数 * 入口参数:无 * 出口参数:无 * 说 明:必须用最近两次扫描的结果,才知道按键是否被按下 * 范 例:无 *************************************************************************** ***************************/ void P_IODect() { static unsigned char KEY_Now=0; //变量值出函数时需保留 unsigned char KEY_Past=0; KEY_Past=KEY_Now; Key_val=20; P8OUT&= ~BIT2; //设定P8.1=1 P3OUT |= BIT7; //设定P2.3=0 if((P6IN&BIT4)==0) Key_val=11; else if((P7IN&BIT0)==0) Key_val=12; else if((P3IN&BIT6)==0) Key_val=13; else if((P3IN&BIT5)==0) Key_val=14; P8OUT |=BIT2; //设定P8.1=1 P3OUT&= ~BIT7; //设定P2.3=0 if((P7IN&BIT0)==0) Key_val=15; else if((P3IN&BIT6)==0) Key_val=16; else if((P3IN&BIT5)==0) Key_val=17; //-----查询IO的输入寄存器----- if((10>8); VS_WriteByte(vsdata&0xff); VS_CS_H; /* 关闭片选 */ } /*********************************************************************** ********** ** 函数名称: INT16U VS_Read_Reg(INT8U addr). ** 功能描述: 从VS的功能寄存器中读取数据,一个字. ** 输入参数: INT8U addr 功能寄存器的地址. ** 输出参数: None. ** 返回参数: return temp读到的字,2字节. *********************************************************************** ***********/ unsigned int VS_Read_Reg( unsigned char addr) { unsigned int temp=0; // VS_DREQ=1; while(!VS_DREQ); /* VS的DREQ为高电平时才接收数据 */ VS_CS_L; /* 打开片选 */ VS_WriteByte(VS_Read); /* 读出操作码(功能寄存器读操作) */ VS_WriteByte(addr); /* 写入寄存器地址 */ temp =VS_ReadByte(); /* 读高字节 */ temp<<=8; temp|=VS_ReadByte(); /* 读取低字节,与高字节拼成一个字 */ VS_CS_H; /* 关闭片选 */ return temp; } /*********************************************************************** ********** ** 函数名称: void VsSetVolume(INT8U volume) . ** 功能描述: 设置音量 1 - 48. ** 输入参数: INT8U volume 1 - 48 . ** 输出参数: None. ** 返回参数: None. *********************************************************************** ***********/ void VsSetVolume( unsigned char volume) 25 { volume = volume * 0x03; VS_Write_Reg(VS_VOL,((volume<<8)|volume)); } /*********************************************************************** ********** ** 函数名称: void VS_Init(void). ** 功能描述: VS1003软复位及初始化. ** 输入参数: None. ** 输出参数: None. ** 返回参数: None. *********************************************************************** ***********/ void VS_Init(void) { VS_IO_Init(); VS_RST_H; VS_delay(100); VS_RST_L; VS_delay(100); VS_RST_H; /* 硬件复位,VS_RST低电平有效 */ VS_delay(100); VS_Write_Reg(VS_MODE ,0x0804); /* 软件复位,向0号寄存器写入0x0804 SM_SDINEW为1 SM_RESET为1 */ VS_Write_Reg(VS_CLOCKF,0x9800); /* 时钟设置,向3号寄存器写入0x9800 SC_MULT 为4 SC_ADD 为3 SC_FREQ为0 */ VS_Write_Reg(VS_VOL ,0x7070); /* 音量设置,左右声道均中等音量 */ VS_Write_Reg(0x02 ,0x7aaa); VS_DCS_L; /* 打开数据片选 */ VS_WriteByte(0); /* 写入数据,这里写入4个0,是无关数据,用来启动数据传输 */ VS_WriteByte(0); VS_WriteByte(0); VS_WriteByte(0); VS_DCS_H; /* 关闭数据片选 */ } /*********************************************************************** ********** ** 函数名称: void VS_Send_Dat32(INT8U *dat) . ** 功能描述: 向VS1003写入32个字节的音频数据. 26 ** 输入参数: INT8U *dat 音频数据. ** 输出参数: None. ** 返回参数: None. *********************************************************************** ***********/ void VS_Send_Dat32( unsigned char *dat) { unsigned char i=0; // VS_DREQ=1; VS_DCS_L; /* 打开数据片选,即开启SDI传输 */ while(!VS_DREQ); /* VS1003的DREQ为高才能写入数据 */ for(i=0;i<32;i++) VS_WriteByte(*(dat+i)); /* 通过SPI向VS1003写入32个字节的音频数据 */ VS_DCS_H; /* 打开数据片选,即开启SDI传输 */ } /*********************************************************************** ********** ** 函数名称: void VS_Flush_Buffer(void). ** 功能描述: 向VS1003写入2048个0,清空缓冲,为下一首mp3做准备. ** 输入参数: None. ** 输出参数: None. ** 返回参数: None. *********************************************************************** ***********/ void VS_Flush_Buffer(void) { unsigned char i,j=0; VS_DCS_L; /* 打开数据片选,即开启SDI传输 */ for(i=0;i<64;i++) { // VS_DREQ=1; while(!VS_DREQ); /* VS1003的DREQ为高才能写入数据 */ for(j=0;j<32;j++) VS_WriteByte(0); /* 通过SPI向VS1003写入32个字节的0 */ } VS_DCS_H; /* 关闭数据片选 */ } /*********************************************************************** ********** 27 ** 函数名称: void VS_SinTest(INT8U x). ** 功能描述: 正弦测试函数,检查vs1003是否正常. ** 输入参数: INT8U x 正弦波频率. ** 输出参数: None. ** 返回参数: None. *********************************************************************** ***********/ void VS_SinTest(int x) { VS_Write_Reg(0x00,0x0820); /* 启动测试,向0号寄存器写入0x0820 SM_SDINEW为1 SM_TEST为1 */ // VS_DREQ=1; while(!VS_DREQ); /* 等待DREQ变为高电平 */ VS_DCS_L; /* 打开数据片选 */ VS_WriteByte(0x53); /* 写入以下8个字节,进入正弦测试 */ VS_WriteByte(0xef); VS_WriteByte(0x6e); VS_WriteByte(x); /* 参数x用来调整正弦测试中正弦波的频率 */ VS_WriteByte(0); VS_WriteByte(0); VS_WriteByte(0); VS_WriteByte(0); VS_delay(60000); /* 这里延时一段时间,可以听到“正弦音” */ VS_delay(60000); VS_delay(60000); VS_delay(60000); VS_delay(60000); VS_delay(60000); VS_WriteByte(0x45); /* 写入以下8个字节,退出正弦测试 */ VS_WriteByte(0x78); VS_WriteByte(0x69); VS_WriteByte(0x74); VS_WriteByte(0); VS_WriteByte(0); VS_WriteByte(0); VS_WriteByte(0); VS_DCS_H; /* 关闭数据片选 */ } /* 28 * SPI.h * * Created on: 2015-4-12 * Author: xiongpb */ #ifndef SPI_H_ #define SPI_H_ #include #define SOFT_SPI //条件编译,SOFT_SPI启用软件SPI代码 extern void SPI_CS_High(void); extern void SPI_CS_Low(void); extern void SPI_HighSpeed(void); extern void SPI_LowSpeed(void); extern void SPI_init(void); extern unsigned char SPI_TxFrame(unsigned char *pBuffer, unsigned int size); char *pBuffer, unsigned int size); extern unsigned char SPI_RxFrame(unsigned #endif /* SPI_H_ */ /*********************************************************************** ****//** * @file HAL_SDCard.c * @addtogroup HAL_SDCard * @{ *************************************************************************** ***/ #include "msp430.h" #include "SPI.h" // Pins from MSP430 connected to the SD Card #define SPI_SIMO BIT1 #define SPI_SOMI BIT2 #define SPI_CLK BIT3 #define SD_CS BIT7 // Ports #define SPI_SEL P4SEL #define SPI_DIR P4DIR 29 #define SPI_OUT P4OUT #define SPI_REN P4REN #define SD_CS_SEL P3SEL #define SD_CS_OUT P3OUT #define SD_CS_DIR P3DIR /***************************************************************************//** * @brief Initialize SD Card * @param None * @return None ******************************************************************************/ void SPI_init(void) { // Port initialization for SD Card operation SPI_SEL |= SPI_CLK + SPI_SOMI + SPI_SIMO; SPI_DIR |= SPI_CLK + SPI_SIMO; SPI_REN |= SPI_SOMI; // Pull-Ups on SD Card SOMI SPI_OUT |= SPI_SOMI; // Certain SD Card Brands need pull-ups SD_CS_SEL &= ~SD_CS; SD_CS_OUT |= SD_CS; SD_CS_DIR |= SD_CS; // Initialize USCI_B1 for SPI Master operation UCB1CTL1 |= UCSWRST; // Put state machine in reset UCB1CTL0 = UCCKPL + UCMSB + UCMST + UCMODE_0 + UCSYNC; // 3-pin, 8-bit SPI master // Clock polarity select - The inactive state is high // MSB first UCB1CTL1 = UCSWRST + UCSSEL_2; // Use SMCLK, keep RESET UCB1BR0 = 63; // Initial SPI clock must be <400kHz UCB1BR1 = 0; // f_UCxCLK = 25MHz/63 = 397kHz UCB1CTL1 &= ~UCSWRST; // Release USCI state machine 30 UCB1IFG &= ~UCRXIFG; } /***************************************************************************//** * @brief Enable low fast SD Card SPI transfers. This function is typically * called after the initial SD Card setup is done to maximize * transfer speed. * @param None * @return None ******************************************************************************/ void SPI_LowSpeed(void) { UCB1CTL1 |= UCSWRST; // Put state machine in reset UCB1BR0 =63; // f_UCxCLK = 25MHz/2 = 12.5MHz UCB1BR1 = 0; UCB1CTL1 &= ~UCSWRST; // Release USCI state machine } /***************************************************************************//** * @brief Enable fast SD Card SPI transfers. This function is typically * called after the initial SD Card setup is done to maximize * transfer speed. * @param None * @return None ******************************************************************************/ void SPI_HighSpeed(void) { UCB1CTL1 |= UCSWRST; // Put state machine in reset UCB1BR0 = 2; // f_UCxCLK = 25MHz/2 = 12.5MHz UCB1BR1 = 0; UCB1CTL1 &= ~UCSWRST; // 31 Release USCI state machine } /***************************************************************************//** * @brief Read a frame of bytes via SPI * @param pBuffer Place to store the received bytes * @param size Indicator of how many bytes to receive * @return None ******************************************************************************/ unsigned char SPI_RxFrame(unsigned char *pBuffer, unsigned int size) { uint16_t gie = __get_SR_register() & GIE; // Store current GIE state __disable_interrupt(); // Make this operation atomic UCB1IFG &= ~UCRXIFG; // Ensure RXIFG is clear // Clock the actual data transfer and receive the bytes while (size--){ while (!(UCB1IFG & UCTXIFG)) ; // Wait while not ready for TX UCB1TXBUF = 0xff; // Write dummy byte while (!(UCB1IFG & UCRXIFG)) ; // Wait for RX buffer (full) *pBuffer++ = UCB1RXBUF; } __bis_SR_register(gie); // Restore original GIE state return 0; } /***************************************************************************//** * @brief Send a frame of bytes via SPI * @param pBuffer Place that holds the bytes to send 32 * @param size Indicator of how many bytes to send * @return None ******************************************************************************/ unsigned char SPI_TxFrame(unsigned char *pBuffer, unsigned int size) { uint16_t gie = __get_SR_register() & GIE; // Store current GIE state __disable_interrupt(); // Make this operation atomic // Clock the actual data transfer and send the bytes. Note that we // intentionally not read out the receive buffer during frame transmission // in order to optimize transfer speed, however we need to take care of the // resulting overrun condition. while (size--){ while (!(UCB1IFG & UCTXIFG)) ; // Wait while not ready for TX UCB1TXBUF = *pBuffer++; // Write byte } while (UCB1STAT & UCBUSY) ; // Wait for all TX/RX to finish UCB1RXBUF; // Dummy read to empty RX buffer // and clear any overrun conditions __bis_SR_register(gie); // Restore original GIE state return 0; } /***************************************************************************//** * @brief Set the SD Card's chip-select signal to high * @param None * @return None ******************************************************************************/ 33 void SPI_CS_High(void) { SD_CS_OUT |= SD_CS; } /*********************************************************************** ****//** * @brief Set the SD Card's chip-select signal to low * @param None * @return None *************************************************************************** ***/ void SPI_CS_Low(void) { SD_CS_OUT &= ~SD_CS; } /*********************************************************************** ****//** * @} *************************************************************************** ***/ /* * Soft_SPI.h * * Created on: 2015-4-12 * Author: xiongpb */ #ifndef SOFT_SPI_H_ #define SOFT_SPI_H_ #include "msp430.h" //sbit SPI_SCL=P40; //SPI同步时钟 输出 #define SPI_SCK_H P4OUT|=BIT0 #define SPI_SCK_L P4OUT&=~BIT0 34 //sbit SPI_SI =P42; //SPI同步数据 输出 #define SPI_SI_H P3OUT|=BIT5 #define SPI_SI_L P3OUT&=~BIT5 //sbit SPI_SO =P1^6; //SPI同步数据 输入 #define SPI_SO_IN P1IN&BIT6 extern void SPI2_Init(void); extern void SPI_WriteByte(unsigned char x); extern unsigned char SPI_ReadByte(); #endif /* SOFT_SPI_H_ */ /* * Soft_SPI.c * * Created on: 2015-4-12 * Author: xiongpb */ #include "Soft_SPI.h" /*********************************************************************** ************************************* * 名 称:SPI_Init * 功 能:初始化SPI端口 * 入口参数:无 * 出口参数:无 * 说 明: 初始化SD卡为SPI模式 * 使用范例:SPI_Init(); *********************************************************************** *************************************/ void SPI2_Init(void) { P3DIR|=BIT5; //输出 P4DIR|=BIT0; //输出 P1DIR&=~BIT6; //输入 SPI_SCK_H; } /*********************************************************************** ************************************* * 名 称:SPI_WriteByte * 功 能:SPI发送1个字节 * 入口参数:x:待发送字节 35 * 出口参数:无 * 说 明: 无 * 使用范例:无 *********************************************************************** *************************************/ void SPI_WriteByte(unsigned char x) { unsigned char i,data; data=x; for(i=0;i<8;i++) { SPI_SCK_L; if(data&BIT7) SPI_SI_H; else SPI_SI_L; SPI_SCK_H; data<<=1; } } /*********************************************************************** ************************************* * 名 称:SPI_ReadByte * 功 能:SPI接收1个字节 * 入口参数:无 * 出口参数:x:待接收字节 * 说 明: 无 * 使用范例:无 *********************************************************************** *************************************/ unsigned char SPI_ReadByte() { unsigned char i,data; for(i=0;i<8;i++) { SPI_SCK_L; if(SPI_SO_IN) { data<<=1; data=data+BIT0; } else 36 data<<=1; SPI_SCK_H; } return data; } /* * SD_SPI.h * * Created on: 2015-4-12 * Author: xiongpb */ #ifndef SD_SPI_H_ #define SD_SPI_H_ extern unsigned char SD_Init(); extern unsigned char SD_Reset(); extern unsigned char SD_Read_Sector(unsigned long Addr ,unsigned char *Ptr,unsigned int FirstNum,unsigned int Num); extern unsigned char SD_Write_Sector(unsigned long Addr ,unsigned char *Ptr,unsigned int FirstNum,unsigned int Num); extern unsigned char SD_Set_SPI(); #endif /* SD_SPI_H_ */ /* * SD_SPI.c * * Created on: 2015-4-12 * Author: xiongpb */ /* * SD_SPI.c *说明:该函数库为通用SD卡读写顶层库函数。 * 用户只需要更改“SD_HardWare.c”中的少量底层代码,即可移 植到任何处理器上。 * Created on: 2013-3-4 * */ #include"SD_HardWare.h" 37 #include "SD_SPI.h" #include"SPI.h" //-----SD 卡相关的命令宏定义----- #define SD_WRITE_DELAY 100 // 先发74个以上的时 钟 #define SD_EMPTY_CLK 0xFF #define SD_EMPTY_DATA 0xFF #define SD_SPI_CRC 0xFF //SPI模式下CRC 无效,随便给 #define SD_CMD0_CRC 0x95 //复位命令CMD0 的CRC校验码 #define SD_CMD0 0+0x40 //复位命令 #define SD_CMD1 1+0x40 //SPI模式命令 #define SD_CMD17 17+0x40 //读扇区命令 #define SD_CMD24 24+0x40 //写扇区命令 #define SD_CMD41 41+0x40 //初始化扇区命令 #define SD_CMD55 55+0x40 //初始化扇区命令 //-----SD卡相关应答----- #define SD_COMMAND_ACK 0x00 //命令应答 #define SD_RESET_ACK 0x01 //复位应答 #define SD_DATA_ACK 0xFE //数据应答 #define SD_WRITE_ACK 0x05 //写扇区应答 //----系统超时控制---- #define SD_TIMEOUT 100 #define TIMEOUT 200 /*********************************************************************** ************************************* * 名 称:Write_Command_SD() * 功 能:SD卡在SPI模式下,向SD卡中写入6个字节的命令 * 入口参数:CMD:指向存放六个字节命令的数组 * 出口参数:SD 卡应答值 * 说 明: 向SD卡中一次写入六个字节的命令 * 使用范例:Write_Command_SD(CMD); *********************************************************************** *************************************/ unsigned char Write_Command_SD(unsigned char *CMD) { unsigned char tmp=0; unsigned char i = 0; SD_CS_High(); //-----先发8个空clock----- SD_Write_Byte(0xFF); SD_CS_Low(); 38 //-----写入6个字节的命令字帧----- SD_Write_Frame(CMD,6); //-----空第一次,即忽略第一个返回值----- SD_Read_Byte(); i = SD_TIMEOUT; do { tmp = SD_Read_Byte(); i--; } while((tmp==0xff)&&i); return(tmp); } /*********************************************************************** ************************************* * 名 称:SD_Write_Sector * 功 能:SD卡在SPI模式下,向SD卡中,在指定的位置写入指定个数的数据。 * 入口参数:Addr:物理扇区的地址 * *Ptr:指向待写数据的数据缓存 * FirstNum:写入该扇区的首个字节偏移地址 * Num:此次操作要写入的数据个数 (FirstNum+Num<512) * 出口参数:0:写入失败 :写入成功 * 1 * 使用范例:SD_Write_Sector(83241,buffer,0,100); //向扇区83241中写入100个字节 *********************************************************************** *************************************/ unsigned char SD_Write_Sector(unsigned long Addr ,unsigned char *Ptr,unsigned int FirstNum,unsigned int Num) { unsigned char temp=0; unsigned int EndNum = 0; unsigned int i=0; unsigned char CMD[6]={0}; //-----发送命令----- CMD[0]=SD_CMD24; //-----将32位地址拆分------ Addr = Addr <<9; //sector = sector*512 将物理地址转换为逻辑地址;(注意一定需要此处的转换) CMD[1]=((Addr&0xFF000000)>>24); CMD[2]=((Addr&0x00FF0000)>>16); CMD[3]=((Addr&0x0000FF00)>>8); CMD[4]=Addr&0x000000FF; 39 //-----CRC校验,SPI模式下无效,可随便给----- CMD[5]=SD_SPI_CRC; //----等待SD卡应答---- i=TIMEOUT; //超时 门限值 do{ temp = Write_Command_SD(CMD); i--; }while((temp != SD_COMMAND_ACK)&&i); //超时判断 if (i==0) return(0); //超 时,返回失败代码 //----空发若干次CLK---- for(i=0;i>24); CMD[2]=((Addr&0x00FF0000)>>16); CMD[3]=((Addr&0x0000FF00)>>8); CMD[4]=Addr&0x000000FF; //-----CRC校验,SPI模式下无效,可随便给----- CMD[5]=SD_SPI_CRC; //----等待SD卡应答---- i=TIMEOUT; //超时门 限值 do{ temp = Write_Command_SD(CMD); i--; }while((temp!=SD_COMMAND_ACK)&&i); //超时判断 if (i==0) { SD_CS_High(); return(0); //超 时,返回失败代码 } //----等待SD卡应答-------------- i=TIMEOUT; //超时门 限值 do{ temp = SD_Read_Byte(); i--; }while(( temp !=SD_DATA_ACK)&&i); //超时判断 if (i==0) { SD_CS_High(); return(0); //超 时,返回失败代码 } //-----读取指定字节----- EndNum=FirstNum+Num; for(i=0;i>24); CMD[2]= ((0x00ffc000 & 0x00ff0000) >>16); CMD[3]= ((0x00ffc000 & 0x0000ff00) >>8); CMD[4]= 0x00ffc000 & 0x000000ff; CMD[5]= SD_SPI_CRC; i=TIMEOUT; //超时门限值 do{ CMD[0] = SD_CMD55; //CMD55命令 temp = Write_Command_SD(CMD); //先发送 CMD55 //-----判断是否为SD卡----- if(temp == 0x01) //如果有反应 { // //-----如无需判断存储卡类型,直接执行线间代码----- CMD[0] = SD_CMD41; //CMD41命令 temp = Write_Command_SD(CMD); //发送CMD41进行激活 if(temp == 0x00) { SD_CS_High(); //CS片选禁能 } // //--------------------------------------------------- } //-----否则,为MMC卡----- else //如果发送CMD55无反应,改发送CMD1 { CMD[0] = SD_CMD1; //CMD1命令 CMD[5] = 0xFF; temp = Write_Command_SD(CMD); //发送 45 CMD1进行激活 if(temp == 0x00) { SD_CS_High(); //CS片选禁能 } } i--; }while((temp !=SD_COMMAND_ACK)&&i); //超时 判断 if(i==0) return(0); //超时,返回失败代码 else return (1); } /* * SD_HardWare.h * * Created on: 2015-4-12 * Author: xiongpb */ #ifndef SD_HARDWARE_H_ #define SD_HARDWARE_H_ extern void SD_Write_Byte(unsigned char Value); extern void SD_Write_Frame(unsigned char *pBuffer,unsigned char size); extern void SD_CS_High(); extern void SD_CS_Low(); extern unsigned char SD_Read_Byte(); extern void SD_Read_Frame(unsigned char *pBuffer, unsigned int size); extern void SD_High_Speed(); extern void SD_Low_Speed(); #endif /* SD_HARDWARE_H_ */ 46 /* * SD_HardWare.c * * Created on: 2015-4-12 * Author: xiongpb */ /* * SD_HardWare.c *说明:此函数库文件为SD卡底层相关的读写和操作函数,也是与最底层G2的SPI唯一的衔接函数库。 * 若是需要在其他硬件微处理器上使用上层SD_SPI.c库函数,只需要更改此函数库中带有 * “此处,调用底层G2硬件接口函数”注释的4处底层SPI函数,和SD_High_Speed()、 * SD_Low_Speed()这两个函数即可完成移植。 * Created on: 2013-4-3 * */ #include"MSP430.h" #include"SPI.h" /*********************************************************************** ***** * 名 称:SD_High_Speed() * 功 能:SD卡在SPI读取模式下,使能SPI的时钟为高速传输模式 * 入口参数:无 * 出口参数:无 * 说 明: 该函数可以更改当前SPI工作的速度。 一般在初始化完SD卡后 * 需要将SPI的速度提高,加快读写速度 * 使用范例:SD_High_Speed(); *********************************************************************** *****/ void SD_High_Speed() { SPI_HighSpeed(); } /*********************************************************************** ***** * 名 称:SD_Low_Speed() * 功 能:SD卡在SPI读取模式下,使能SPI的时钟为低速(300K左右) * 入口参数:无 * 出口参数:无 47 * 说 明: 由于在初始化完SD卡时,需要的速度很低,此函数更改当前 * SPI工作的速度。使其在300K左右 * 使用范例:SD_Low_Speed(); *********************************************************************** *****/ void SD_Low_Speed() { SPI_LowSpeed(); } /*********************************************************************** ***** * 名 称:SD_CS_High() * 功 能:SD卡在SPI读取模式下,控制使能CS管脚为高电平 * 入口参数:无 * 出口参数:无 * 说 明: 此处的CS管脚可以根据硬件的需要,任意指定管脚作CS均可。 * 使用范例:SD_CS_High(); *********************************************************************** *****/ void SD_CS_High() { //-----此处,调用底层G2硬件接口函数----- SPI_CS_High(); } /*********************************************************************** ***** * 名 称:SD_CS_Low() * 功 能:SD卡在SPI读取模式下,控制使能CS管脚为低电平 * 入口参数:无 * 出口参数:无 * 说 明:: 此处的CS管脚可以根据硬件的需要,任意指定管脚作CS均可。 * 使用范例:SD_CS_Low(); *********************************************************************** *****/ void SD_CS_Low() { //-----此处,调用底层G2硬件接口函数----- SPI_CS_Low(); } /*********************************************************************** ***** * 名 称:SD_Write_Byte() * 功 能:SPI模式下,向SD卡中写入一个字节数据 48 * 入口参数:value:当前要写入的数据 * 出口参数:无 * 说 明:使用该函数可以向SD卡中写入一个字节 * 使用范例:SD_Write_Byte();// 将value写入SD 卡中 *********************************************************************** *****/ void SD_Write_Byte(unsigned char value) { unsigned char temp=0; do{ //-----此处,调用底层G2硬件接口函数----- temp=SPI_TxFrame(&value,1); }while(temp==0); } /*********************************************************************** ***** * 名 称:SD_Write_Frame() * 功 能:SPI模式下,向SD卡中写入size个字节数据 * 入口参数:pBuffer:当前要写入的数据头指针 * size:要写入的数据个数 * 出口参数:无 * 说 明:使用该函数可以向SD卡中写入size个字节 * 使用范例:无 *********************************************************************** *****/ void SD_Write_Frame(unsigned char *pBuffer,unsigned int size) { unsigned char temp=0; do{ //-----此处,调用底层G2硬件接口函数----- temp=SPI_TxFrame(pBuffer,size); }while(temp==0); } /*********************************************************************** ***** * 名 称:SD_Read_Frame() * 功 能:SPI模式下,从SD卡中读出size个字节数据 * 入口参数:pBuffer:存储的读SD数据的头指针 * size:计划要读取的数据个数 * 出口参数:无 * 说 明:使用该函数可以从SD卡中读出size个字节 * 使用范例:无 *********************************************************************** *****/ 49 void SD_Read_Frame(unsigned char *pBuffer, unsigned int size) { unsigned char temp=0; do{ //-----此处,调用底层G2硬件接口函数----- temp=SPI_RxFrame(pBuffer,size); }while(temp==0); } /*********************************************************************** ***** * 名 称:SD_Read_Byte() * 功 能:SPI模式下,读取SD卡中的一个字节 * 入口参数:无 * 出口参数:value:当前读取出的数据 * 说 明:使用该函数可以读取SD卡中的一个字节 * 使用范例:tempt=SD_Read_Byte();// 读取一个字节,并赋给tempt变量 *********************************************************************** *****/ unsigned char SD_Read_Byte() { unsigned char value=0; unsigned char temp=0; do{ -----此处,调用底层G2硬件接口函数----- // temp=SPI_RxFrame(&value,1); }while(temp==0); return value; } 未完待续。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 50
/
本文档为【基于MSP430F5529的MP3】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索