1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/xiang07-NIOS_ii_FATFS

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
sd_card.c 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Trail07 Отправлено 02.05.2018 11:27 2e2eca3
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
/*****************************************************************************
* Name: sd_card.c
* Describ: 通过SPI接口对SD卡的访问,实现SD卡的初始化,读写操作等等
* Version:Rev1.0
* Author:zjxiang
* Data:2018.03.13
******************************************************************************/
#include <unistd.h>
#include "sd_card.h"
#include "system.h"
#include "stdio.h"
#include "altera_avalon_pio_regs.h"
#include "../FATFS/diskio.h"
#include "../FATFS/ff.h"
#include "../FATFS/ffconf.h"
#include "OLED.h"
#include <string.h>
uint8_t SD_Type = 0; //SD卡的类型
SD_CardInfo SDCardInfo;
FILINFO fileinfo; //文件信息
char memu[10][16] = {};
//char *memu;
unsigned char CURR_FLAG = 1;
#define SD_CLK_HIGH IOWR_ALTERA_AVALON_PIO_DATA(SD_CLK_BASE,0x01)
#define SD_CLK_LOW IOWR_ALTERA_AVALON_PIO_DATA(SD_CLK_BASE,0x00)
#define SD_NCS_HIGH IOWR_ALTERA_AVALON_PIO_DATA(SD_NCS_BASE,0x01)
#define SD_NCS_LOW IOWR_ALTERA_AVALON_PIO_DATA(SD_NCS_BASE,0x00)
#define SD_DIN_HIGH IOWR_ALTERA_AVALON_PIO_DATA(SD_DIN_BASE,0x01)
#define SD_DIN_LOW IOWR_ALTERA_AVALON_PIO_DATA(SD_DIN_BASE,0x00)
#define SD_DOUT IORD_ALTERA_AVALON_PIO_DATA(SD_DOUT_BASE)
bool gSD_CARDInit=FALSE; // set it to 1 when SD-CARD is initialized
// SD-CARD(SPI mode) initial with low speed
// insert a certain delay
#define SD_CARD_INIT_DELAY usleep(10)
/******************************************************************************
函数名称:SD_CARD_Port_Init
函数功能:初始化SD卡引脚
入口参数:无
出口参数:无
******************************************************************************/
void SD_CARD_Port_Init()
{
IOWR_ALTERA_AVALON_PIO_DIRECTION(SD_CLK_BASE,1); //设置为输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(SD_DIN_BASE,1); //设置为输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(SD_NCS_BASE,1); //设置为输出
IOWR_ALTERA_AVALON_PIO_DIRECTION(SD_DOUT_BASE,0); //设置为输入
SD_CLK_HIGH;
SD_NCS_HIGH;
}
/******************************************************************************
函数名称:SD_CARD_Write_Byte
函数功能:SPI字节写函数
入口参数:无
出口参数:无
******************************************************************************/
void SD_CARD_Write_Byte(u8 byte)
{
u8 i;
for(i=0;i<8;i++)
{ // MSB First
//...sd_DIN=(byte >> (7-i)) & 0x1;
if(((byte >> (7-i)) & 0x01) == 0x01)
SD_DIN_HIGH;
else
SD_DIN_LOW;
//...sd_CLK=0;
SD_CLK_LOW;
if(gSD_CARDInit) SD_CARD_INIT_DELAY;
//...sd_CLK=1;
SD_CLK_HIGH;
if(gSD_CARDInit) SD_CARD_INIT_DELAY;
}
}
/******************************************************************************
函数名称:SD_CARD_Read_Byte
函数功能:SPI字节读函数
入口参数:无
出口参数:无
******************************************************************************/
u8 SD_CARD_Read_Byte()
{
u8 i,byte;
byte=0;
for(i=0;i<8;i++)
{ // MSB First
//...sd_CLK=0;
SD_CLK_LOW;
if(gSD_CARDInit) SD_CARD_INIT_DELAY;
byte<<=1;
//...if(sd_DOUT) byte++;
if((SD_DOUT&0x01) == 0x01) byte++;
//...sd_CLK=1;
SD_CLK_HIGH;
if(gSD_CARDInit) SD_CARD_INIT_DELAY;
}
return byte;
}
/******************************************************************************
函数名称:SD_WaitReady
函数功能:等待SD卡准备好
入口参数:无
出口参数:返回值为0表示SD卡准备好了,返回值为1表示错误
******************************************************************************/
uint8_t SD_WaitReady(void)
{
uint32_t retry = 0;
do
{
//if (SPI2_WriteReadByte(0xFF) == 0xFF) //卡准备好了吗
if (SD_CARD_Read_Byte() == 0xFF) //卡准备好了吗
{
return 0;
}
retry++;
}
while (retry < 0xFFFFFF); //等待直到SD卡准备好
return 1; //超时,退出
}
/******************************************************************************
函数名称:SD_DisSelect
函数功能:取消选择,释放SPI总线
入口参数:无
出口参数:无
******************************************************************************/
void SD_DisSelect(void)
{
//...SET_SDCARD_CS;
//...SPI2_WriteReadByte(0xFF); //提供8个额外的补偿时钟
SD_NCS_HIGH;
SD_CARD_Write_Byte(0xFF);
}
/******************************************************************************
函数名称:SD_Select
函数功能:选择SD卡并且等待SD卡准备OK
入口参数:无
出口参数:返回值为0表示成功,返回值为1表示失败
******************************************************************************/
uint8_t SD_Select(void)
{
SD_NCS_LOW;
if (SD_WaitReady() == 0)
{
return 0;
}
SD_DisSelect();
return 1;
}
/******************************************************************************
函数名称:SDCard_Initial
函数功能:SD卡初始化
入口参数:无
出口参数:返回值为0表示成功,返回值为1表示失败
******************************************************************************/
uint8_t SDCard_Initial(void)
{
uint8_t res; // 存放SD卡的返回值
uint16_t retry; // 用来进行超时计数
uint8_t buf[4] = {0, 0, 0, 0};
uint16_t i;
SD_CARD_Port_Init();
usleep(1000);
printf("SD-CARD Init...\n");
gSD_CARDInit=TRUE; // Set init flag of SD-CARD
//SET_SDCARD_CS; //关闭SD卡的片选信号PCS0
for (i = 0;i < 10; i++)
{
SD_CARD_Write_Byte(0xff); //初始化时至少发送74个连续脉冲
}
retry = 20;
do
{
res = SD_SendCmd(CMD0, 0, 0x95); //进入IDDLE状态
}
while ((res != 0x01) && (retry--));
SD_Type = SD_TYPE_ERR; //初始化默认无卡
if (res == 0x01)
{
if (SD_SendCmd(CMD8, 0x1AA, 0x87) == 1) //判断是否是SD V2.0版本的卡
{
for (i = 0;i < 4; i++)
{
//buf[i] = SPI2_WriteReadByte(0xFF);
buf[i] = SD_CARD_Read_Byte();
}
if ((buf[2] == 0x01) && (buf[3] == 0xAA)) //检查卡是否支持2.7~3.6V
{
retry = 0xFFFE; //超级计数器初值
do
{
SD_SendCmd(CMD55, 0, 0x01); //发送CMD55
res = SD_SendCmd(CMD41, 0x40000000, 0x01); //发送CMD41
}
while (res && (retry--));
if (retry && (SD_SendCmd(CMD58, 0, 0X01) == 0)) //开始读OCR信息鉴别SD2.0卡版本开始
{
for (i = 0;i < 4; i++)
{
//...buf[i] = SPI2_WriteReadByte(0xFF); //得到32位OCR值
buf[i] = SD_CARD_Read_Byte();
}
if (buf[0] & 0x40) //检查CCS位判断是否是高速SD卡
{
SD_Type = SD_TYPE_V2HC;
}
else
{
SD_Type = SD_TYPE_V2;
}
}
}
}
else //不是V2.0版本的卡,则有可能是V1.x/MMC V3版本
{
SD_SendCmd(CMD55, 0, 0x01); //发送CMD55
res = SD_SendCmd(CMD41, 0, 0x01); //发送CMD41
if (res <= 1)
{
SD_Type = SD_TYPE_V1; //当前SD卡是V1.x版本
retry = 0xFFFE;
do
{
SD_SendCmd(CMD55, 0, 0x01); //发送CMD55
res = SD_SendCmd(CMD41, 0, 0x01); //发送CMD41
}
while (res && (retry--));
}
else
{
SD_Type = SD_TYPE_MMC; //当前SD卡是MMC V3
retry = 0xFFFE;
do //等待退出IDLE模式
{
res = SD_SendCmd(CMD1, 0, 0X01); //发送CMD1
}
while(res && (retry--));
}
if ((retry==0) || (SD_SendCmd(CMD16, 512, 0X01) != 0)) //设置扇区大小为512字节,如果设置成功应该返回值为0x00
{
SD_Type = SD_TYPE_ERR; //错误的卡
}
}
}
SD_DisSelect(); //取消片选信号
//...SPI2_HighSpeed_Config(); //配置SPI2为高速模式
gSD_CARDInit=FALSE;
if (SD_Type)
{
return 0; //若检测到正确的卡类型则返回0
}
else if (res)
{
return (res); //返回命令响应错误信息
}
return 0xAA; //返回其它错误
}
/******************************************************************************
函数名称:SD_SendCmd
函数功能:向SD卡发送一个命令并返回SD卡收到命令后的响应
入口参数:cmd:命令;arg:命令参数;crc:crc校验值
出口参数:SD卡返回的响应
******************************************************************************/
uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{
uint8_t r1;
uint8_t Retry = 0;
SD_DisSelect(); //取消上次片选
if (SD_Select()) //选择SD卡,查看其是否准备好(返回值为0表示其准备好了)
{
return 0xFF; //片选失效
}
//开始发送写入命令
/*----------------------------------------------------------
SPI2_WriteReadByte(cmd | 0x40); //写入命令
SPI2_WriteReadByte(arg >> 24); //开始写入命令参数
SPI2_WriteReadByte(arg >> 16);
SPI2_WriteReadByte(arg >> 8);
SPI2_WriteReadByte(arg);
SPI2_WriteReadByte(crc); //写入CRC校验值
-----------------------------------------------------------*/
SD_CARD_Write_Byte(cmd | 0x40); //写入命令
SD_CARD_Write_Byte(arg >> 24); //开始写入命令参数
SD_CARD_Write_Byte(arg >> 16);
SD_CARD_Write_Byte(arg >> 8);
SD_CARD_Write_Byte(arg);
SD_CARD_Write_Byte(crc); //写入CRC校验值
if (cmd == CMD12)
{
//...SPI2_WriteReadByte(0xFF);
SD_CARD_Write_Byte(0xFF);
}
Retry = 0x1F;
do
{
//...r1 = SPI2_WriteReadByte(0xFF); //读取SD卡的响应
r1 = SD_CARD_Read_Byte();
}
while ((r1 & 0x80) && (Retry--));
return r1;
}
/******************************************************************************
函数名称:SD_ReadDisk
函数功能:读取SD卡磁盘上的数据存储在buffer缓冲区中
入口参数:buffer:读取的数据存储的缓冲区
sector:起始扇区
cnt:扇区数
出口参数:返回值为0表示读取数据成功,返回其它值表示读取数据失败
******************************************************************************/
uint8_t SD_ReadDisk(uint8_t *buffer, uint32_t sector, uint8_t cnt)
{
uint8_t response = 0;
if (SD_Type != SD_TYPE_V2HC) //判断是否是高速SD卡
{
sector <<= 9; //将扇区地址转换成字节地址
}
if (cnt == 1) //判断是否是仅仅读取1扇区数据
{
response = SD_SendCmd(CMD17, sector, 0x01); //向SD卡发送读扇区数据命令
if (response == 0) //发送读扇区数据命令成功
{
response = SD_ReceiveData(buffer, 512); //接收1扇区(512字节)数据
}
}
else
{
response = SD_SendCmd(CMD18, sector, 0x01); //向SD卡发送读多扇区数据命令(连续读)
do
{
response = SD_ReceiveData(buffer, 512); //接收1扇区(512字节)数据
buffer += 512; //缓冲区地址增加512
}
while ((--cnt) && (response == 0));
SD_SendCmd(CMD12, sector, 0x01); //发送停止命令
}
SD_DisSelect(); //取消片选信号
return (response);
}
/******************************************************************************
函数名称:SD_ReceiveData
函数功能:从SD卡中读取一个数据包的内容
入口参数:buffer:读取的数据存储的缓冲区
length:要读取的数据长度
出口参数:返回值为0表示读取数据成功,返回其它值表示读取数据失败
******************************************************************************/
uint8_t SD_ReceiveData(uint8_t *buffer, uint16_t length)
{
if (SD_GetResponse(0xFE)) //等待SD卡发回数据起始令牌
{
return 1;
}
while (length--) //开始接受数据
{
//...*buffer = SPI2_WriteReadByte(0xFF);
*buffer = SD_CARD_Read_Byte();
buffer++;
}
//...SPI2_WriteReadByte(0xFF); //2字节的CRC校验码,用户不用关心
SD_CARD_Write_Byte(0xFF);
//...SPI2_WriteReadByte(0xFF);
SD_CARD_Write_Byte(0xFF);
return 0; //读取成功
}
/******************************************************************************
函数名称:SD_GetResponse
函数功能:等待SD卡的回应
入口参数:response:需要得到的回应值
出口参数:返回值为0表示成功得到了回应值,其它得到的回应值失败
******************************************************************************/
uint8_t SD_GetResponse(uint8_t response)
{
uint16_t count = 0xFFFF; //等待次数
//...while ((SPI2_WriteReadByte(0xFF) != response) && count) //等待得到准确的回应
while ((SD_CARD_Read_Byte() != response) && count)
{
count--;
}
if (count == 0)
{
return (MSD_RESPONSE_FAILURE); //得到的回应失败
}
else
{
return (MSD_RESPONSE_NO_ERROR); //正确回应
}
}
/******************************************************************************
函数名称:SD_WriteDisk
函数功能:向SD卡磁盘上指定扇区位置写入指定数目的数据
入口参数:buffer:待写入的数据存储的缓冲区
sector:起始扇区
number:扇区数
出口参数:返回值为0表示写入数据成功,返回其它值表示写入数据失败
******************************************************************************/
uint8_t SD_WriteDisk(uint8_t *buffer, uint32_t sector, uint8_t number)
{
uint8_t response = 0;
if (SD_Type != SD_TYPE_V2HC)
{
sector *= 512; //扇区地址转换成字节地址
}
if (number == 1) //仅仅写入1扇区数据吗
{
response = SD_SendCmd(CMD24, sector, 0x01); //向SD卡发送写入单个扇区数据的命令
if (response == 0) //发送写入单个扇区数据命令成功
{
response = SD_SendBlock(buffer, 0xFE); //写入512字节数据
}
}
else
{
if (SD_Type != SD_TYPE_MMC)
{
SD_SendCmd(CMD55, 0, 0x01);
SD_SendCmd(CMD23, number, 0x01);
}
response = SD_SendCmd(CMD25, sector, 0x01); //写多个扇区的命令
if (response == 0)
{
do
{
response = SD_SendBlock(buffer, 0xFC);
buffer += 512;
}
while ((--number) && (response == 0));
response = SD_SendBlock(0, 0xFD);
}
}
SD_DisSelect(); //取消片选信号
return (response);
}
/******************************************************************************
函数名称:SD_SendBlock
函数功能:向SD卡中写入一个数据包的内容
入口参数:buffer:待写入的数据存储的缓冲区
cmd:指令
出口参数:返回值为0表示写入数据成功,返回其它值表示写入数据失败
******************************************************************************/
uint8_t SD_SendBlock(uint8_t *buffer, uint8_t cmd)
{
uint16_t t = 0;
if (SD_WaitReady()) //等待SD卡准备好
{
return 1;
}
//...SPI2_WriteReadByte(cmd); //向SD卡写入命令
SD_CARD_Write_Byte(cmd);
if (cmd != 0xFD) //不是结束指令
{
for (t = 0;t < 512; t++)
{
//...SPI2_WriteReadByte(buffer[t]);
SD_CARD_Write_Byte(buffer[t]);
}
//...SPI2_WriteReadByte(0xFF);
SD_CARD_Write_Byte(0xFF);
//...SPI2_WriteReadByte(0xFF); //2字节CRC校验码
SD_CARD_Write_Byte(0xFF);
//...t = SPI2_WriteReadByte(0xFF); //接受SD卡的应答响应
t = SD_CARD_Read_Byte(0xFF);
if ((t & 0x1F) != 0x05)
{
return 2; //响应错误
}
}
return 0; //写入成功,返回0
}
/******************************************************************************
函数名称:SD_GetCID_Register
函数功能:获取SD卡的CID寄存器信息,包括SD卡制造商的信息
入口参数:cid_data:存放接受的CID寄存器数据的指针(至少是16字节)
出口参数:返回值为0表示成功,返回其它值表示失败
******************************************************************************/
uint8_t SD_GetCID_Register(uint8_t *cid_data)
{
uint8_t response = 0;
response = SD_SendCmd(CMD10, 0, 0x01); //发送CMD10命令,读取CID寄存器
if (response == 0x00)
{
response = SD_ReceiveData(cid_data, 16); //接收16字节CID寄存器数据
}
SD_DisSelect(); //取消片选信号
if (response)
{
return 1;
}
else
{
return 0;
}
}
/******************************************************************************
函数名称:SD_GetCSD_Register
函数功能:获取SD卡的CSD寄存器信息
入口参数:csd_data:存放接受的CSD寄存器数据的指针(至少是16字节)
出口参数:返回值为0表示成功,返回其它值表示失败
******************************************************************************/
uint8_t SD_GetCSD_Register(uint8_t *csd_data)
{
uint8_t response = 0;
response = SD_SendCmd(CMD9, 0, 0x01); //发送CMD9命令,读出CSD寄存器
if (response == 0)
{
response = SD_ReceiveData(csd_data, 16); //接收16字节CID寄存器数据
}
SD_DisSelect(); //取消片选信号
if (response)
{
return 1;
}
else
{
return 0;
}
}
/******************************************************************************
函数名称:SD_GetSectorCount
函数功能:获取SD卡的扇区数容量信息
入口参数:无
出口参数:返回值为0表示获取容量数出错
返回其它值表示获取SD卡的容量值
******************************************************************************/
uint32_t SD_GetSectorCount(void)
{
uint8_t csd[16];
uint32_t Capacity = 0;
uint8_t n = 0;
uint16_t csize = 0;
if (SD_GetCSD_Register(csd) != 0) //读取CSD寄存器内容
{
return 0; //出错,返回
}
//如果是SDHC卡,则按照下面的方式计算卡容量
if ((csd[0] & 0xC0) == 0x40) //V2.00的卡
{
csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;
Capacity = (uint32_t)csize << 10; //得到扇区数
}
else //V1.xx的卡
{
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
Capacity = (uint32_t)csize << (n - 9); //得到扇区数
}
return (Capacity);
}
/*--------------------------------------------------------
*SD卡检测函数
*-------------------------------------------------------*/
void SD_CARD_Detect()
{
//while (SDCard_Initial())
while(disk_initialize(0))
{
printf("SD CARD initialize Failed\r\n");
usleep(100000);
usleep(100000);
}
printf("SD CARD initialize succeed!");
switch(SD_Type)
{
case SD_TYPE_ERR:
{
printf("CARD ERRORR\r\n");
}
break;
case SD_TYPE_MMC:
{
printf("MMC CARD\r\n");
}
break;
case SD_TYPE_V1:
{
printf("SD CARD Rev1.x\r\n");
}
break;
case SD_TYPE_V2:
{
printf("SD CARD Rev2.0\r\n");
}
break;
case SD_TYPE_V2HC:
{
printf("SD CARD SDCH Rev2.0\r\n");
}
break;
default:break;
}
printf("SD CARD Capacity:%dMB\r\n",(int)SD_GetSectorCount()>>11);
}
unsigned char FATFS_test()
{
FATFS fatfs;
FRESULT res;
FIL fil;
char diskname[] = {"newdir"};
unsigned char i;
unsigned int br;
disk_initialize(0);
f_mount(0,&fatfs);
res = f_mkdir(diskname);
res = f_open(&fil,"123.txt",FA_OPEN_ALWAYS|FA_READ);
unsigned char buff[128];
if(res == FR_OK)
{
res = f_read(&fil,buff,sizeof(buff),&br);
for(i=0;i<br;i++)
printf("char %d is %c",i,(char)buff[i]);
f_close(&fil);
}
f_mount(0,NULL);
return 0;
}
//遍历文件
//path:路径
//返回值:执行结果
u8 SD_Card_Scan_files()
{
FRESULT res;
DIR dir;
FATFS fatfs;
unsigned char i;
char *fn; /* This function is assuming non-Unicode cfg. */
#if _USE_LFN
static char lfn[_MAX_LFN*2+1];
fileinfo.lfsize = sizeof(lfn);
fileinfo.lfname = lfn;
#endif
f_mount(0,&fatfs);
res = f_opendir(&dir, "/MP3"); /* 如果不带参数,则从当前目录开始 */
i = 0;
// res = f_opendir(&dir,(const TCHAR*)path); //打开一个目录
if (res == FR_OK)
{
printf("\r\n");
while(1)
{
res = f_readdir(&dir, &fileinfo); //读取目录下的一个文件
if (res != FR_OK || fileinfo.fname[0] == 0) break; //错误了/到末尾了,退出
//if (fileinfo.fname[0] == '.') continue; //忽略上级目录
#if _USE_LFN
fn = *fileinfo.lfname ? fileinfo.lfname : fileinfo.fname;
#else
fn = fileinfo.fname;
#endif /* It is a file. */
//printf("%s\r\n", fn);//打印文件名
//memu[i] = fn;
//memcpy(memu[i],fn,16);
strcpy(memu[i],fn);
//printf("index %d : %s\r\n",MP3_memu.index,MP3_memu.fn[MP3_memu.index]);
printf("index %d : %s\r\n",i,memu[i]);
i ++;
}
}
//memset(OLED_ROW.ROW0,0,16);
strcpy(OLED_ROW.ROW0,memu[CURR_FLAG]);
//sprintf(OLED_ROW.ROW0,"%s",MP3_memu.fn[1]);
sprintf(OLED_ROW.ROW1,"%s","LAST: ");
strcat(OLED_ROW.ROW1,memu[CURR_FLAG-1]);
sprintf(OLED_ROW.ROW2,"%s","NEXT: ");
strcat(OLED_ROW.ROW2,memu[CURR_FLAG+1]);
sprintf(OLED_ROW.ROW3,"%s"," MP3 PLAYER ");
OLED_display();
return res;
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/xiang07-NIOS_ii_FATFS.git
git@api.gitlife.ru:oschina-mirror/xiang07-NIOS_ii_FATFS.git
oschina-mirror
xiang07-NIOS_ii_FATFS
xiang07-NIOS_ii_FATFS
master