基于STM32+CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试(下篇)

发布者:DelightfulGaze最新更新时间:2024-05-27 来源: elecfans关键字:STM32  NAND  FATFS 手机看文章 扫描二维码
随时随地手机看文章

/ AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1

/ AVR32 0 *1 RL78 0 *2 R32C 0 *2

/ PIC18 0/1 SH-2 0 *1 M16C 0/1

/ PIC24 0 *2 H8S 0 *1 MSP430 0 *2

/ PIC32 0 *1 H8/300H 0 *1 8051 0/1

/

/

* 1:高位优先。/

* 2:不支持不连续的内存访问。/

* 3:一些编译器生成LDM(逻辑磁盘管理器 ) / STM mem_cpy(内存拷贝)函数。

*/


(3)实现动态内存分配函数与时间函数

ff.h文件有动态内存的释放,动态内存申请,时间获取函数接口。

25.png


在diskio.c文件实现函数功能:

26.png


代码实现如下:


//动态内存分配

void* ff_memalloc (UINT msize) /* 分配内存块 */

{

return (void*)malloc(msize); //分配空间

}



//动态内存释放

void ff_memfree (void* mblock) /* 空闲内存块 */

{

free(mblock); //释放空间

}



//返回FATFS时间

//获得时间

DWORD get_fattime (void)

{

//Get_RTC_Timer(); //获取一次RTC时间

return (RTC_Timer.year-1980)<<25|   //年

RTC_Timer.month<<21|  //月

RTC_Timer.day<<16|    //日

RTC_Timer.hour<<11|   //时

RTC_Timer.minute<<5|  //分

RTC_Timer.sec; //秒

}




/*

Return Value

Currnet local time is returned with packed into a DWORD value. The bit field is as follows:

bit31:25

Year origin from the 1980 (0..127)

bit24:21

Month (1..12)

bit20:16

Day of the month(1..31)

bit15:11

Hour (0..23)

bit10:5

Minute (0..59)

bit4:0

Second / 2 (0..29)

*/



(4)修改堆栈空间

完成了上述的修改,还需要修改堆栈空间,因为长文件支持需要占用堆空间。

修改STM32启动文件如下:

27.png




(5)编译工程测试

修改完毕之后,给开发板插上SD卡,调用API函数在SD卡创建一个文件,并写入数据,测试是否成功:


#include 'ff.h'

FATFS fs; // 用户定义的文件系统结构体

FIL file; // 用户定义的文件系统结构体

u8 buff[]='123 知识!!';

int main(void)

{

u32 data; //检测SD卡容量

u8 i,res;

LED_Init(); //LED灯初始化

Delay_Init();

KEY_Init();

USART1_Init(72,115200);

USART2_Init(36,115200);

FLASH_Init();

Set_Font_addr(); //字库地址初始化

FSMC_SRAM_Init();

LCD_Init();

RTC_Init(); //RTC时钟初始化

while(SD_Init()) //检测不到SD卡,SD相关硬件初始化

{

i=!i;

LCD_ShowString(60,150,200,16,16,'SD Card Error! Please Check SD Card!!',0xf800);

Delay_ms(500);

LED1(i)//DS0闪烁

}


f_mount(&fs,'0',1); // 注册工作区,驱动器号 0,初始化后其他函数可使用里面的参数

printf('注册工作区!n');


if(f_mkfs('0',0,4096)) //格式化SD卡

{

printf('格式化失败!!n');

}

else

{

printf('格式化成功!!n');

}

res = f_open(&file, '/file.c', FA_OPEN_ALWAYS | FA_READ | FA_WRITE);

if(res==0)

{

printf('文件创建成功!!n');

}

else

{

printf('文件创建失败!!n');

}

res =f_write(&file,buff,strlen((const char*)buff),&data);

if(res==0)

{

printf('数据写入成功!!n');

}

else

{

printf('数据写入失败!!n');

}

printf('成功写入%d字节数据n',data);

f_close(&file); //关闭文件

//_FS_RPATH


while(1)

{

Delay_ms(1000);

LED1(1);

Delay_ms(500);

LED1(0);

}

}


五、案例使用

5.1 读取GBK字库文件(LCD汉字显示)

产品开发中,如果设备带有LCD显示屏,一般会显示各种文字提示,或者机器操作说明,显示中文需要字库,为了方便字模的提取,可以将字库文件制作好之后放到SD NAND上,通过文件系统打开字库文件,读取字模进行显示。


下面贴出文件系统读取字模的核心代码:

/*

函数功能: 显示GBK字库数据

u32 x 范围0~319

u32 y 范围0~479

u32 size 数据的宽度(必须是8的倍数) 是正方形

u8 *p 中文

说明: 取模横向坐标必须保证是8的倍数

*/


void ILI9341_DisplayGBKData(u32 x,u32 y,u32 size,u8 *p)

{

FIL fp;

UINT br;

u8 L,H;

u32 Addr;

u16 font_size=size/8*size; //字体占用的点阵码字节大小

u8 *buff=NULL;

H=*p;

L=*(p+1);

if(L<0x7f)L=L-0x40;

else L=L-0x41;

H=H-0x81;

Addr=(190*H+L)*font_size; //中文在字库里的偏移量

buff=malloc(font_size); //使用的堆空间

if(buff==NULL)return;


switch(size)

{

case 16:

if(f_open(&fp,'0:/font/gbk16.DZK',FA_READ)!=FR_OK)

{

printf('f_open error.rn');

}

f_lseek(&fp,Addr);

f_read(&fp,buff,font_size,&br);

f_close(&fp);


break;

case 24:

f_open(&fp,'0:/font/gbk24.DZK',FA_READ);

f_lseek(&fp,Addr);

f_read(&fp,buff,font_size,&br);

f_close(&fp);

break;

case 32:


break;

}

//显示中文

ILI9341_DisplayData(x,y,size,size,buff);


//释放空间

free(buff);

}


这是读取字模,显示的效果:


28.png


5.2 读取MP3文件播放(开机音乐)

这个例子是演示文件系统的目录扫描函数使用方式,读取指定目录下的MP3文件进行播放。


u8 PlayerMP3(const char *path);

FATFS FatFs;

int main()

{

LED_Init();

BEEP_Init();

KeyInit();

USARTx_Init(USART1,72,115200);



SDCardDeviceInit(); //初始化SD卡


// res=f_mkfs('0:',FM_ANY,0,work,sizeof work);

// if(res)printf('格式化失败!n');

// else printf('格式化成功!n');

f_mount(&FatFs, '0:', 0); //注册工作区


PlayerMP3('0:/MP3');


while(1)

{

DelayMs(100);

LED0=!LED0;

}

}



/*

函数功能: 扫描目录mp3播放

0表示成功 1表示失败

*/

u8 PlayerMP3(const char *path)

{

DIR dir;

FRESULT res;

FILINFO fno; //存放读取的文件信息

char *abs_path=NULL;


/*1. 打开目录*/

res=f_opendir(&dir,path);

if(res!=FR_OK)return res;


/*2. 循环读取目录*/

while(1)

{

res=f_readdir(&dir,&fno);

if(fno.fname[0] == 0 || res!=0)break;

printf('文件名称: %s,文件大小: %ld 字节rn',fno.fname,fno.fsize);


/*过滤目录*/

if(strstr(fno.fname,'.mp3'))

{

//申请存放文件名称的长度

abs_path=malloc(strlen(path)+strlen(fno.fname)+1);

if(abs_path==NULL)break;


strcpy(abs_path,path);

strcat(abs_path,'/');

strcat(abs_path,fno.fname);


printf('abs_path=%sn',abs_path);

VS1053_MP3(0,0,abs_path);

free(abs_path);

}

}


/*3. 关闭目录*/

f_closedir(&dir);

return 0;

}


[1] [2]
关键字:STM32  NAND  FATFS 引用地址:基于STM32+CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试(下篇)

上一篇:stm32单片机pwm设置与实际输出频率不一致
下一篇:STM32入门学习笔记之MPU6050传感器解析实验4

推荐阅读最新更新时间:2024-11-05 19:08

智林STM32程序源代码的分析和整理01
一、目的 1、前些天,编写了开发板上键盘扫描、字符输入和简单shell的程序,该程序的编写是在以前工程的基础上修改而成的,源代码的组织比较乱,也没有很好的注释。这两天,先把代码整理一下,加上比较详细的注释,使得可读性、扩展性更好。 2、乘这个机会,也把程序里与STM32硬件相关的部分好好学习一下。 二、开发板配置分析 1、PA口 PA0对应按键PB3,开发板右下角。 PA1用于模拟电位器,JP1在这里。 PA2用定时器的PWM产生液晶的背光电源。PA4-PA7用于SPI模式操作SD卡。PA9,PA10用于串口0通信。PA11,PA12是USB差分线。PA13、PA14、PA15是JTAG的三个脚。 PA3、
[单片机]
Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin文件SD卡运行
代码烧写 I.MX6U 虽然内部有 96K 的 ROM,但是这 96K 的 ROM 是 NXP自己用的,不向用户开放。所以相当于说 I.MX6U 是没有内部 flash 的,但是我们的代码得有地方存放啊,为此,I.MX6U 支持从外置的 NOR Flash、NAND Flash、SD/EMMC、SPI NOR Flash和 QSPI Flash 这些存储介质中启动,所以我们可以将代码烧写到这些存储介质中中。在这些存储介质中,除了 SD 卡以外,其他的一般都是焊接到了板子上的,我们没法直接烧写。但是 SD卡是活动的,是可以从板子上插拔的,我们可以将 SD 卡插到电脑上,在电脑上使用软件将.bin文件烧写到 SD 卡中,然后再插到板子
[单片机]
Linux之ARM(IMX6U)裸机汇编LED驱动实验--烧写bin<font color='red'>文件</font>到<font color='red'>SD</font>卡运行
STM32关于使用定时器触发ADC转换的解决办法和详细说明
以STM32 ADC的常规通道为例(注入通道类似): 如上图,STM32 ADC的常规通道可以由以上6个信号触发任何一个,我们以使用TIM2_CH2触发ADC1,独立模式,每次仅测一条通道,则ADC的配置如下:(以下代码使用STM32固件库V3.5) void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; //关闭通道扫描模式 ADC_InitStructur
[单片机]
<font color='red'>STM32</font>关于使用定时器触发ADC转换的解决办法和详细说明
STM32 ADC 规则多通道转换
看了这个代码之后终于明白了规则多通道转是怎么回事,以及整体如何实现了。附代码: /******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ in
[单片机]
STM32端口配置
1、上拉输入:上拉就是把电位拉高,比如拉到Vcc。上拉就是将不确定的信号通过一个电阻嵌位在高电平!电阻同时起限流作用!强弱只是上拉电阻的阻值不同,没有什么严格区分。 2、下拉输入:就是把电压拉低,拉到GND。与上拉原理相似。 3、浮空输入:浮空(floating)就是逻辑器件的输入引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构,当它输入引脚悬空时,相当于该引脚接了高电平。一般实际运用时,引脚不建议悬空,易受干扰。 通俗讲就是让管脚什么都不接,浮空着。 4、模拟输入:模拟输入是指传统方式的输入。数字输入是输入PCM数字信号,即0,1的二进制数字信号,通过数模转换,转换成模拟信号,经前级放大进入功率放大器,功率放大
[单片机]
<font color='red'>STM32</font>端口配置
Flash原厂64层/72层3D NAND产能增加 加速SSD普及
  6月15日, 三星 电子宣布已经开始量产第四代64层256Gb V-NAND,与48层256Gb V-NAND相比,生产效率将提高30%以上。东芝/西部数据、美光、SK海力士等在2017上半年也均宣布推出64层/72层3D NAND,预计从下半年开始将陆续进入量产阶段,届时3D NAND产能将大幅增加。下面就随网络通信小编一起来了解一下相关内容吧。 ▲ 三星 64层256Gb V-NAND   Flash原厂64层/72层3D NAND产能增加,对Q3旺季需求的成长有利。受NAND Flash缺货,以及高成本压力的影响,2017上半年手机市场出货成长不如预期,市场需求也表现平平。随着Q2季度进入尾声,即将进入Q3需
[网络通信]
STM32 SST25VF016B驱动程序
///** // ****************************************************************************** // * @file stm32f10x_SST25VF016B.c // * @brief SST25VF10B驱动程序 // ****************************************************************************** // * @ // * 接口定义(STM32 SPI1) // * CE--PA4 SO--PA6 SCK--PA5 SI--PA7 // * // *
[单片机]
stm32常见错误与工程模板
1.新建工程的时候编译出现如下错误(MDK4.12 使用v3.4的库) ..CMSISstm32f10x.h(80): error: #35: #error directive: Please select first the target STM32F10x device used in your application (in stm32f10x.h file) 解决方法:双击错误进入出错的地方,在stm32f10x.h处 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM
[单片机]
<font color='red'>stm32</font>常见错误与工程模板
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved