单片机添加文件系统_单片机怎么添加头文件 - CSDN
  • 准备再单片机CH579上移植FATFS...FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个2M大小的SPI_FLASH( W25Q1

    准备再单片机CH579上移植FATFS1.3方便数据管理,下面简单介绍一下移植注意事项和误区。

    需要准备的材料有:

    (1)FATFS文件系统源码FATFS1.3(点此下载最新FATFS源码)。

    (2)单片机平台一个(CH579)。

    (3)SPI_FLASH芯片一个(如:W25Q16)。

    FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个2M大小的SPI_FLASH( W25Q16)上建立一个文件系统,主控制器是CH579单片机。在做文件系统移植前,你需要把操作SPI_FLASH的驱动调通,能读写SPI_FLASH就可以了。

    第一步、 解压缩新下载的FATFS源码,看看里面都是些什么文件。如下图所示,红色框是移植FATFS所必须的文件,蓝色框内的文件是可选的移植文件。

    diskio.c个diskio.h是和存储器读写控制相关的驱动接口,比如SPI_FLASH的读写函数接口,都要映射到这里面。必须的文件 

    ff.h和ff.h是FATFS的核心文件,必须的文件

    ffconf.h是FATFS的配置文件,用来裁剪FATFS,必须的文件

    integer.h是FATFS所用到的数据类型定义,用以兼容不同字长CPU,必须的文件

    ffsystem.c是一些关于在带操作系统平台中,使用的示例,可选文件

    ffunicode.c是万国码编码文件,文件里主要是大数组定义,假如你需要让文件名支持中文就需要这个文件,这个文件会使代码空间急剧变大,可选文件

    第二步、 本次FATFS移植未使用操作系统,文件系统支持中文路径和名称,所以需要ff.c、ff.h、ffconf.h、diskio.c、diskio.h、ffunicode.c和integer.h这六个文件添加到工程中即可。如下图:

     

    第三步 修改ffconf.h文件,来裁剪我们的FATFS,通过宏开关来去掉不用的功能,来精简文件系统。想知道每个宏的功能?(点击这里)

    需要注意的是:由于我们此次移植支持了中文路径和名称,所以这个要设置这个宏    #define FF_CODE_PAGE936 /*936代表 简体中文*/

    特别注意:下图的修改,FF_MAX_SS的值必须和FLASH的块的值一直,我在这里走了歪路,搞了半天,它默认的是512,网上其它文档没有提示这里的修改。

    第四步 修改diskio.c 来映射我们的存储器读写控制接口,如下:

    /*-----------------------------------------------------------------------*/
    /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
    /*-----------------------------------------------------------------------*/
    /* If a working storage control module is available, it should be        */
    /* attached to the FatFs via a glue function rather than modifying it.   */
    /* This is an example of glue functions to attach various exsisting      */
    /* storage control modules to the FatFs module with a defined API.       */
    /*-----------------------------------------------------------------------*/
    #include "ff.h"            /* Obtains integer types */
    #include "diskio.h"        /* Declarations of disk functions */
    #include "SPIFlash.H"

    /* Definitions of physical drive number for each drive */
    #define SPI_FLASH        0    /* Example: Map Ramdisk to physical drive 0 */
     
    /*-----------------------------------------------------------------------*/
    /* Get Drive Status                                                      */
    /*-----------------------------------------------------------------------*/
     
    DSTATUS disk_status (
        BYTE pdrv        /* Physical drive nmuber to identify the drive */
    )
    {

        if(pdrv == SPI_FLASH) 
        {
            PRINT("!!!disk_status OK\r\n");
            return RES_OK; //Ö±½Ó·µ»ØOK¼´¿É
        }
        else
        {
        PRINT("!!!disk_status ERR\r\n");

            return RES_PARERR;
        }
    }
     
     
     
    /*-----------------------------------------------------------------------*/
    /* Inidialize a Drive                                                    */
    /*-----------------------------------------------------------------------*/
     
    DSTATUS disk_initialize (
        BYTE pdrv                /* Physical drive nmuber to identify the drive */
    )
    {
        if(pdrv == SPI_FLASH) 
        {
            SPIFlash_Init();//³õʼ»¯spi flash
            PRINT("!!!disk_initialize OK\r\n");
            return RES_OK;
        }
        else
        {
            PRINT("!!!disk_initialize ERR\r\n");

            return RES_PARERR;
        }
    }
     
     
     
    /*-----------------------------------------------------------------------*/
    /* Read Sector(s)                                                        */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_read (
        BYTE pdrv,        /* Physical drive nmuber to identify the drive */
        BYTE *buff,        /* Data buffer to store read data */
        DWORD sector,    /* Start sector in LBA */
        UINT count        /* Number of sectors to read */
    )
    {
        DRESULT res;
        PRINT("disk_read---sector:%d,count:%d\r\n",sector,count);
        if(pdrv == SPI_FLASH) 
        {
            for(;count>0;count--)
            {
                
            ReadExternalFlash_SPI_DAN(sector*4096,4096,buff);//spi flashµÄ¶Áº¯Êý£¬×¢Òâ²ÎÊýÀàÐÍÒ»ÖÂ
                sector++;
                buff+=4096;
            }
            
            res = RES_OK; //ĬÈÏдÈëÕý³££¬¿ÉÒÔ¼Ó
        
            return res;
        }
        else
        {
            
            return RES_PARERR;
        }
    }
     
     
     
    /*-----------------------------------------------------------------------*/
    /* Write Sector(s)                                                       */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_write (
        BYTE pdrv,            /* Physical drive nmuber to identify the drive */
        const BYTE *buff,    /* Data to be written */
        DWORD sector,        /* Start sector in LBA */
        UINT count            /* Number of sectors to write */
    )
    {
        DRESULT res;
     PRINT("disk_write---sector:%d,count:%d\r\n",sector,count);
        if(pdrv == SPI_FLASH) 
        {
                for(;count>0;count--)
            {
                EraseExternal4KFlash_SPI(sector*4096);
             BlukWriteExternalFlash_SPI(sector*4096,4096,(uint8_t *)buff);//spi flashµÄдº¯Êý£¬×¢Òâ²ÎÊýÀàÐÍÒ»ÖÂ
            sector++;
                buff+=4096;
                
            }
             res=RES_OK;
            return res;
        }
        else
        {
        
            PRINT("!!!disk_write ERR\r\n");
            return RES_PARERR;
        }
    }
     
     
     
    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions                                               */
    /*-----------------------------------------------------------------------*/
     
    DRESULT disk_ioctl (
        BYTE pdrv,        /* Physical drive nmuber (0..) */
        BYTE cmd,        /* Control code */
        void *buff        /* Buffer to send/receive control data */
    )
    {
        if (pdrv == SPI_FLASH)
        {
            switch (cmd) 
            {
             case CTRL_SYNC:
                 return RES_OK;
     
             /* ÉÈÇøÊýÁ¿ 1024*1024*1024 =4 (MB) */
     
             case GET_SECTOR_COUNT:
              *(DWORD * )buff = 512;////spi flashµÄ¿é´óСÊÇ4K Bytes
        //         *(DWORD * )buff = 8*1024;//W25Q16 ÓÐ512´óСΪ4k bytesµÄÉÈÇø
                 return RES_OK;
     
             /* ÉÈÇø´óС*/
     
             case GET_SECTOR_SIZE :
         *(WORD * )buff = 4096;//spi flashµÄ¿é´óСÊÇ4K Bytes
                // *(WORD * )buff = 512;//spi flashµÄ¿é´óСÊÇ4K Bytes
                 return RES_OK;
     
             /*¿é */
     
             case GET_BLOCK_SIZE :
                  *(DWORD * )buff =1;
                 return RES_OK;
                 
             default:
                  return RES_PARERR;
             }
        }
        else
        {
            
            PRINT("!!!disk_ioctl ERR\r\n");
            return RES_PARERR;
        }
    }
    DWORD get_fattime(void) {
    //    DWORD time; 
        return 0;
    }

     

    这里面一定注意,FLASH读写函数驱动的调用。很关键,决定是否能移植成功。

    展开全文
  • 文件系统对于嵌入式系统的重要性是不言而喻的,有了文件系统管理数据和外设变得方便许多,同时简化了应用的开发。今天我们来以在SPI_FLASH上建立文件系统为例,看看FATFS文件系统怎么移植和使用。 需要准备的材料有...

    文件系统对于嵌入式系统的重要性是不言而喻的,有了文件系统管理数据和外设变得方便许多,同时简化了应用的开发。今天我们来以在SPI_FLASH上建立文件系统为例,看看FATFS文件系统怎么移植和使用。

    需要准备的材料有:

    (1)FATFS文件系统源码(点此下载最新FATFS源码)。

    (2)单片机平台一个(内存越大越好)。

    (3)SPI_FLASH芯片一个(如:W25Q32)。

    FATFS是一个通用的嵌入式文件系统,对不同的平台支持很好,大到硬盘、U盘、存储卡,小到spi_flash芯片甚至单片机内部FLASH都可以使用FATFS。今天我们就在一个4M大小的SPI_FLASH( W25Q32 )上建立一个文件系统,主控制器是飞思卡尔K60单片机。在做文件系统移植前,你需要把操作SPI_FLASH的驱动调通,能读写SPI_FLASH就可以了。

    step 0.1:下载最新的FATFS源码,当前版本:R0.13。

    step 0.2 解压缩新下载的FATFS源码,看看里面都是些什么文件。如下图所示,红色框是移植FATFS所必须的文件,蓝色框内的文件是可选的移植文件。

    diskio.c个diskio.h是和存储器读写控制相关的驱动接口,比如SPI_FLASH的读写函数接口,都要映射到这里面。必须的文件 

    ff.h和ff.h是FATFS的核心文件,必须的文件

    ffconf.h是FATFS的配置文件,用来裁剪FATFS,必须的文件

    integer.h是FATFS所用到的数据类型定义,用以兼容不同字长CPU,必须的文件

    ffsystem.c是一些关于在带操作系统平台中,使用的示例,可选文件

    ffunicode.c是万国码编码文件,文件里主要是大数组定义,假如你需要让文件名支持中文就需要这个文件,这个文件会使代码空间急剧变大,可选文件

    step 0.3 本次FATFS移植未使用操作系统,文件系统支持中文路径和名称,所以需要ff.c、ff.h、ffconf.h、diskio.c、diskio.h、ffunicode.c和integer.h这六个文件添加到工程中即可。如下图:

     

    step 1.0 修改ffconf.h文件,来裁剪我们的FATFS,通过宏开关来去掉不用的功能,来精简文件系统。想知道每个宏的功能?(点击这里

    需要注意的是:由于我们此次移植支持了中文路径和名称,所以这个要设置这个宏    #define FF_CODE_PAGE936 /*936代表 简体中文*/

    step 1.1 修改diskio.c 来映射我们的存储器读写控制接口,如下:

     

    /*-----------------------------------------------------------------------*/
    /* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2016        */
    /*-----------------------------------------------------------------------*/
    /* If a working storage control module is available, it should be        */
    /* attached to the FatFs via a glue function rather than modifying it.   */
    /* This is an example of glue functions to attach various exsisting      */
    /* storage control modules to the FatFs module with a defined API.       */
    /*-----------------------------------------------------------------------*/
    
    #include "diskio.h"		/* FatFs lower layer API */
    #include "w25qxx.h"
    #include "debug.h"
    
    #define DISKIO_DEBUG 1
    #if defined DISKIO_DEBUG&&(DISKIO_DEBUG)
    #define diskio_printf  uart_printf
    #else
    #define diskio_printf(a,...)
    #endif
    
    /* Definitions of physical drive number for each drive */
    #define SPI_FLASH		0	/* Example: Map Ramdisk to physical drive 0 */
    
    /*-----------------------------------------------------------------------*/
    /* Get Drive Status                                                      */
    /*-----------------------------------------------------------------------*/
    
    DSTATUS disk_status (
    	BYTE pdrv		/* Physical drive nmuber to identify the drive */
    )
    {
    	if(pdrv == SPI_FLASH) 
    	{
    		return RES_OK; //直接返回OK即可
    	}
    	else
    	{
    		diskio_printf("!!!disk_status ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Inidialize a Drive                                                    */
    /*-----------------------------------------------------------------------*/
    
    DSTATUS disk_initialize (
    	BYTE pdrv				/* Physical drive nmuber to identify the drive */
    )
    {
    	if(pdrv == SPI_FLASH) 
    	{
    		w25qxx_init();//初始化 spi flash
    		return RES_OK;
    	}
    	else
    	{
    		diskio_printf("!!!disk_initialize ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Read Sector(s)                                                        */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_read (
    	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
    	BYTE *buff,		/* Data buffer to store read data */
    	DWORD sector,	/* Start sector in LBA */
    	UINT count		/* Number of sectors to read */
    )
    {
    	DRESULT res;
    	//uart_printf("disk_read---sector:%d,count:%d\r\n",sector,count);
    	if(pdrv == SPI_FLASH) 
    	{
    		res = FS_SpiFlash_Read(buff,sector,count);//spi flash的读接口,注意函数参数类型一致性
    
    		return res;
    	}
    	else
    	{
    		diskio_printf("!!!disk_read ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Write Sector(s)                                                       */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_write (
    	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
    	const BYTE *buff,	/* Data to be written */
    	DWORD sector,		/* Start sector in LBA */
    	UINT count			/* Number of sectors to write */
    )
    {
    	DRESULT res;
    
    	if(pdrv == SPI_FLASH) 
    	{
    		res = FS_SpiFlash_Write((uint8_t *)buff,sector,count);//spi flash的写接口,注意函数参数类型一致性
    		return res;
    	}
    	else
    	{
    		diskio_printf("!!!disk_write ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions                                               */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_ioctl (
    	BYTE pdrv,		/* Physical drive nmuber (0..) */
    	BYTE cmd,		/* Control code */
    	void *buff		/* Buffer to send/receive control data */
    )
    {
    	if (pdrv == SPI_FLASH)
    	{
    		switch (cmd) 
    		{
    		 case CTRL_SYNC:
    			 return RES_OK;
    
    		 /* 扇区数量 1024*1024*1024 =4 (MB) */
    
    		 case GET_SECTOR_COUNT:
    
    			 *(DWORD * )buff = 1024;//W25Q32 有1024个大小为4k bytes 的扇区
    			 return RES_OK;
    
    		 /* 扇区大小 */
    
    		 case GET_SECTOR_SIZE :
    
    			 *(WORD * )buff = 4096;//spi flash的扇区大小是 4K Bytes
    			 return RES_OK;
    
    		 /*块大小 */
    
    		 case GET_BLOCK_SIZE :
    		 	 *(DWORD * )buff = 1;
    			 return RES_OK;
    			 
    		 default:
    		 	 return RES_PARERR;
    		 }
    	}
    	else
    	{
    		diskio_printf("!!!disk_ioctl ERR\r\n");
    		return RES_PARERR;
    	}
    }//spi flash的读接口,注意函数参数类型一致性
    
    		return res;
    	}
    	else
    	{
    		diskio_printf("!!!disk_read ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Write Sector(s)                                                       */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_write (
    	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
    	const BYTE *buff,	/* Data to be written */
    	DWORD sector,		/* Start sector in LBA */
    	UINT count			/* Number of sectors to write */
    )
    {
    	DRESULT res;
    
    	if(pdrv == SPI_FLASH) 
    	{
    		res = FS_SpiFlash_Write((uint8_t *)buff,sector,count);//spi flash的写接口,注意函数参数类型一致性
    		return res;
    	}
    	else
    	{
    		diskio_printf("!!!disk_write ERR\r\n");
    		return RES_PARERR;
    	}
    }
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Miscellaneous Functions                                               */
    /*-----------------------------------------------------------------------*/
    
    DRESULT disk_ioctl (
    	BYTE pdrv,		/* Physical drive nmuber (0..) */
    	BYTE cmd,		/* Control code */
    	void *buff		/* Buffer to send/receive control data */
    )
    {
    	if (pdrv == SPI_FLASH)
    	{
    		switch (cmd) 
    		{
    		 case CTRL_SYNC:
    			 return RES_OK;
    
    		 /* 扇区数量 1024*1024*1024 =4 (MB) */
    
    		 case GET_SECTOR_COUNT:
    
    			 *(DWORD * )buff = 1024;//W25Q32 有1024个大小为4k bytes 的扇区
    			 return RES_OK;
    
    		 /* 扇区大小 */
    
    		 case GET_SECTOR_SIZE :
    
    			 *(WORD * )buff = 4096;//spi flash的扇区大小是 4K Bytes
    			 return RES_OK;
    
    		 /*块大小 */
    
    		 case GET_BLOCK_SIZE :
    		 	 *(DWORD * )buff = 1;
    			 return RES_OK;
    			 
    		 default:
    		 	 return RES_PARERR;
    		 }
    	}
    	else
    	{
    		diskio_printf("!!!disk_ioctl ERR\r\n");
    		return RES_PARERR;
    	}
    }
    DWORD get_fattime(void) { DWORD time; /* 返回当前时间戳 */ //暂不添加时间获取,需要的话就把RTC数据传入这里//暂不添加时间获取,需要的话就把RTC数据传入这里
    	
    	return 0;
    }
    
     

    要修改的文件就这么多了,其他文件直接使用,不用改动。

    step2.0  下面写个测试函数,来测测我们移植成功 了没有。

     

    void fs_test(void)
    {
    	FATFS fs;           /* Filesystem object */
        FIL fil;            /* File object */
        FRESULT res;  /* API result code */
        UINT bw;            /* Bytes written */
        BYTE work[FF_MAX_SS]; /* Work area (larger is better for processing time) */
    	BYTE mm[50];
    	UINT i;
    	
    	uart_printf("文件系统测试开始:\r\n");
    	/* 格式化文件系统 */
    	res = f_mkfs("0:", FM_ANY, 0, work, sizeof work);//"0:"是卷标,来自于 #define SPI_FLASH		0
    	if (res)
    	{
    		uart_printf("文件系统格式化失败.\r\n");
    		return ;
    	}
    	else
    	{
    		uart_printf("文件系统格式化成功.\r\n");
    	}
    	/* 挂载文件系统 */
    	res = f_mount(&fs, "0:", 0);
    	if (res)
    	{
    		uart_printf("文件系统挂载失败.\r\n");
    	}
    	else
    	{
    		uart_printf("文件系统挂载成功.\r\n");
    	}
    	/* Create a file as new */
    	res = f_open(&fil, "0:/测试文件.txt", FA_CREATE_NEW|FA_WRITE|FA_READ);
    	if (res)
    	{
    		uart_printf("打开文件失败.\r\n");
    	}
    	else
    	{
    		uart_printf("打开文件成功.\r\n");
    	}
    	/* Write a message */
    	res = f_write(&fil, "Hello,World!", 12, &bw);
    	//uart_printf("res write:%d\r\n",res);
    	if (bw == 12)
    	{
    		uart_printf("写文件成功!\r\n");
    	}
    	else
    	{
    		uart_printf("写文件失败!\r\n");
    	}
    	res = f_size(&fil);
    	uart_printf("文件大小:%d Bytes.\r\n",res);
    	memset(mm,0x0,50);
    	f_lseek(&fil,0);
    	res = f_read(&fil,mm,12,&i);
    	if (res == FR_OK)
    	{
    		uart_printf("读文件成功!\r\n");
    		uart_printf("读到数据长度:%d Bytes.\r\n",i);
    	}
    	else
    	{
    		uart_printf("读文件失败!\r\n");
    	}
    	uart_printf("读到如下数据:\r\n");
    	buff_print((char *)mm,12);
    	/* Close the file */
    	f_close(&fil);
    	/*卸载文件系统*/
    	f_mount(0, "0:", 0);
    	uart_printf("文件系统测试完毕.\r\n");

    step2.1  Congratulations!!!瞧, 我们成功了,尽情享用文件系统带来的便利吧。

    
     
    <img data-cke-saved-src="https://img-blog.csdn.net/20170920181046007?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjE0NzU2MDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" src="https://img-blog.csdn.net/20170920181046007?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjE0NzU2MDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
    
    
    
    

     

    说的比较浅显,大家有问题或建议欢迎留言。over

    
     
    展开全文
  • 单片机启动文件

    2018-01-21 18:12:58
    初始化堆栈指针SP 初始化PC指针 初始化中断向量表 配置系统时钟 调用C库函数_main,最终去到C的世界
    • 初始化堆栈指针SP
    • 初始化PC指针
    • 初始化中断向量表
    • 配置系统时钟
    • 调用C库函数_main,最终去到C的世界
    展开全文
  •  一直对MP3的制作报有极大的兴趣,之前己经用沁恒的CH375 + STC12C5A60S2 + VS1003方案实现,但对于底层文件系统和USB通讯协议都是由沁恒提供的库实现的,并且它不开源,同时考虑到一块CH375价格在20价左右,...

        一直对MP3的制作报有极大的兴趣,之前己经用沁恒的CH375 + STC12C5A60S2 + VS1003方案实现,但对于底层文件系统和USB通讯协议都是由沁恒提供的库实现的,并且它不开源,同时考虑到一块CH375价格在20价左右,不菲,于是下定决心要直接在SD卡上实现文件系统的管理。

        在网上找了下文件系统,发现几乎没有针对51单片机的文件系统,偶然之间在看到网上看到了Petit FatFS,http://hi.baidu.com/tlptotop/blog/item/21c30b2ae0c9a4f5e7cd40de.html

    兴奋之余,立即着手开始移植,由于对SD卡己经有一些的时间的认识于是移植的过程倒是没没有花费多少时间,由于考虑做的是MP3,在移植时并没有移植写函数。

    涉及的文件是diskio.c中的disk_readp()函数,修改如下

    /*-----------------------------------------------------------------------*/
    /* Read Partial Sector                                                   */
    /*-----------------------------------------------------------------------*/

    DRESULT disk_readp (
     BYTE* dest,   /* Pointer to the destination object */
     DWORD sector,  /* Sector number (LBA) */
     WORD sofs,   /* Offset in the sector */
     WORD count   /* Byte count (bit15:destination) */
    )
    {
     DRESULT res;
     // Put your code here
     int8u temp; 
     int16u i=0; 
        int8u cmd[]={0x51,0x00,0x00,0x00,0x00,0xff};
     sector=sector<<9;
     cmd[1]=((sector&0xff000000)>>24);
     cmd[2]=((sector&0x00ff0000)>>16);
     cmd[3]=((sector&0x0000ff00)>>8);
     SPI_CS=0;
    //写命令
     do{
      temp=SDWriteCmd(cmd);
      i++;
      if(i>100)
       return 0x01;
     }while(temp!=0x00);
     while(SDReadByte()!=0xfe);
     for(i=0;i<sofs;i++)
      SDReadByte();//跳过sofs个字节
     for(i=0;i<count;i++)//读取count个字节
      *(dest+i)=SDReadByte();
     SDReadByte();
     SDReadByte();
     SPI_CS=1;
     SDWriteByte(0xff);
     res=RES_OK;
     return res;
    }

    展开全文
  • STM32F103RCT6: STM32F103RCT6是一种嵌入式-微控制器的...所谓单片机最小系统,就是让单片机能够正常运行,最少且必须的器件所组成的系统单片机最小系统上电之后,单片机可以正常复位,下载程序,除此之外没...

    喜欢请关注微信公众号:嵌入式从0到1

    公众号内容面向在校大学生、电子爱好者、嵌入式工程师;

    涉及电子制作、模块使用、单片机技术、物联网相关知识分享;

    软硬件全栈工程师,玩模块,学硬件,带你从0走到1


    STM32F103RCT6:
    STM32F103RCT6是一种嵌入式-微控制器的集成电路(IC),32位 Cortex-M3内核处理器,速度是72MHz,程序存储器容量是256KB,程序存储器类型是FLASH,RAM容量是48K,封装LQFP64。

     

     
     
    STM32单片机命名规则:

     
     
    STM32单片机最小系统:
    所谓单片机最小系统,就是让单片机能够正常运行,最少且必须的器件所组成的系统。
    单片机最小系统上电之后,单片机可以正常复位,下载程序,除此之外没有其他任何功能。
    在最小系统保证正确的基础上,可以依次添加其他功能模块或器件,使之单片机具有实际功能。
     
     
    STM32单片机最小系统包括一个复位电路和一个时钟电路。如下图1所示。
    图中复位电路使用的是上电复位电路,STM32单片机NRST引脚输入低电平,则发生复位。
    标题图1  STM32F103单片机最小系统
     
     
     
    电源引脚:
     
    VDD是单片机的数字电源正极,VSS是数字电源负极,共有5个VDD引脚,5个VSS引脚。VDDA是单片机的模拟电源正极,负责给内部的ADC、DAC模块供电,VSSA是模拟电源负极。
     
     
    还有一个电源引脚,就是VBAT,BAT就是Battery(电池),这个引脚用来连接电池的正极的。STM32带RTC功能(实时时钟),所以有VBAT引脚。
     
     
    原理图上预留了一个CR1220纽扣锂电池,当主电源供电存在的情况下,由系统中的VCC3.3给VBAT供电;
    当主电源断电之后,由CR1220纽扣电池给STM32自带的RTC模块供电,从而能够保证实时时钟模块在主电源掉电的情况下还能够正常工作。
     
     
    但是这样设计的话,这里有一个矛盾需要解决。如果VBAT引脚直接与VCC3.3和CR1220连接的话,会存在下面问题:
    1、当电池电压高于3.3V,电池就会输出电流到AMS1117,使得芯片发烫,还会很快消耗电池电量。
    2、如果电池电压低于3.3V,AMS1117产生的3.3V,就会给电池充电,而这种CR1220电池是不能够充电的。
     
    为了解决上面问题,我们将VBAT引脚的供电电路设计如下:
     

     
     
    D1防止电池的电流流向AMS1117,D2防止AMS1117产生的3.3V流向电池。
    之所以这样设计,用的就是“二极管的单向导通性”。
     
    正常产品设计的时候,每个电源引脚旁边,最好放置一个0.1uF的电容滤波,用来滤除电源的噪声杂波。
     
     
    复位引脚NRST
     
    复位就是重启。STM32复位引脚是低电平复位,正常工作状态,复位引脚是高电平。
     

     
      单片机的置位和复位,其目的都是为了把电路初始化到一个确定状态。复位时在单片机内部单片机是将存储设备和一些寄存器装入生产厂商预设的一个值。一般来说,单片机复位电路的作用是把一个状态机初始化到一个空的状态。
     
    单片机实现上电复位的原理:
    在复位引脚NRST上外接电容和电阻。
     
    当复位电平(低电平)持续两个机器周期以上时复位有效,系统上电后由于电容的充电,会保持一段时间的低电平来使单片机复位。
     
    刚上电,电容两端电压为0,即低电平复位,RC电路有个充电曲线(即电容两端电压变化曲线),单片机识别外部电平有一个连接电压,保证rc电路电容电压充到单片机临界电压的时间在两个机器周期以上就能满足单片机复位条件;
     
    当3.3V电源加到VCC3.3时,RC电路导通,NRST与地的电位差为电容与地的电位差。NRST与地的电位差只有电容充电完毕后才会达到3.3V,所以在电容的充电过程中,给芯片引脚的信号都是低电平。根据RC电路充电方程式V(t)=U+A*e-(t/RC),只要合理的选择好R跟C的值就可以保证充电时间大于芯片复位所要求的时间。我们一般R选择10K电阻,C选择0.1uF电容。
     
     
    晶振引脚
     
    STM32有两组晶振,一组用来给单片机提供主时钟(5:OSC_IN,6:OSC_OUT),主时钟晶振使用8MHz的晶振(为了程序内部倍频方便,一般选用8MHz的晶振)。
     
    一组用来给RTC提供时钟(3:OSC32_IN,4:OSC32_OUT),RTC时钟晶振,需要连接32.768K的晶振,关于为什么要用32.768KHz,大家可以去百度了解一下哈。
     
    实际应用中,如果不用RTC功能的话,RTC的晶振不必连接。
     
    STM32的时钟电路又分为内时钟和外时钟两种模式。
     
    外部时钟是在OSC_IN和OSC_OUT之间加上一个晶振,单片机内部振荡器便能产生自激震荡,产生时钟信号,在晶振的两侧加上20~30pF的瓷片电容起到了微调时钟频率的作用,让频率更加稳定。
     
    内部时钟是STM32内部有时钟产生,所以如果不用外部晶振的话,也可以不用连接,内部时钟是用芯片内部振荡电路,精度不高,温飘也较大,不需要外部振荡器件。
     
     

     
     
    BOOT引脚
     
    STM32有两个BOOT引脚,分别是BOOT0和BOOT1,这两个引脚的高低电平,决定了单片机的启动方式和运行方式。
     
     

    第一种(BOOT1=X,BOOT0=0)启动方式是最常用的用户FLASH启动。默认启动方式
    第二种(BOOT1=0,BOOT0=1)启动方式是系统存储器启动方式。STM32中自带的BootLoader( 就是通常说的ISP程序)就是在这种启动方式中,如果出现程序硬件错误的话可以切换BOOT0=1到该模式下重新烧写Flash即可恢复正常。 BootLoader所在区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。
    第三种(BOOT1=1,BOOT0=1)启动方式是STM32内嵌的SRAM启动。该模式用于调试。
     
     

    一般我都是将BOOT0和BOOT1接地。
     
     
    上面就是最小系统的全部内容,当然只有上面的部分还不行,一般最小系统还包括下面几部分:
     
     
    电源电路:
    因为STM32单片机一般都是3.3V供电,而生活中一般常见的都是5V电源(电脑的USB口,手机充电器,移动电源...),所以一般使用AMS1117-3.3V 稳压电源芯片将5V降压为3.3V,该芯片的封装一般为SOT223。

     
    下载电路:
    当然除了上面几部分以为,还需要一个下载电路,STM32的下载方式有如下几种:
    (1)串口下载:使用串口下载需要单片机内有相应的程序的支持,而系统存储器中就放了这么一段程序,由ST 在生产线上写入,用于通过可用的串行接口对闪存存储器进行重新编程。(在系统存储器启动模式下下载,因为在厂家提供的BootLoader中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。程序烧录在FLASH)。
    注意:使用此种方式需要BOOT0=1,即需要有外部电路支持才可以实现串口下载。
     
    (2)JLINK或者STLINK下载
    一般我们使用JTAG或者SWD模式下载程序。
     
    推荐使用SWD模式下载,SWD模式只需要三个引脚(GND、SWCLK、SWDIO)即可实现程序的下载功能。
     

     
     

    从六月份开始,每个月会制作一个毕业设计难度的DIY作品,

    前期作品以模块组合的形式搭建,降低门槛,方便大家一起跟着做;

    DIY过程只在微信公众号中分享,大家没关注的,赶紧关注哈。

     

    每个月时间大致安排:

    上个月25号,公布DIY作品名称;

    每月1日公布作品功能点及所需要的功能模块链接;

    每月10日前绘制完模块配合的线路板;

    每月15日之前硬件搭建完毕,之后按模块撰写代码,调试,随时公众号更新进展;

    每月月底开源整个作品的源码和PCB工程文件。

     

    题目选取原则:

    公众号每个月20日发起投票,25号截止,票数最多的作为下个月的DIY内容;

    投票的备选项大家可以后台留言给我,我会选出五种留言最多的作为选项;

    每个月的DIY内容尽量与上个月分享的文章有一定的相关度,起到温故知新的作用。

     

    有什么想法或者建议,留言给我哈。


     

    展开全文
  • 记录整理一下,关于一个单片机菜单系统的idea,偶然翻到,怕流失,在此记录,为那美好青春,哈哈哈 首先不是完整系统,只有能找到的代码段,这是上课没认真听讲,别人玩手机,自己乱想,写下了一些片段。不过还是...
  • 华大单片机如何向MDK中加入头文件和库文件关键文件介绍加入头文件 大多数习惯于8位单片机开发的工程师,都会使用操作寄存器的方式来使用单片机。当初次接触华大单片机库开发的时候,会发现库里有好多的文件,不知道...
  • 第三步:继续新建原理图文件和PCB文件,新建的文件都会被保存到刚刚新建的工程中 新建原理图: 新建PCB文件: 新建完之后,你的屏幕左边就会是这样的: 第四步:保存工程 像上图一样,右击工程名,...
  • 第三步:继续新建原理图文件和PCB文件,新建的文件都会被保存到刚刚新建的工程中 新建原理图: 新建PCB文件: 新建完之后,你的屏幕左边就会是这样的: 第四步:保存工程 像上图一样,右击工程名,...
  • 简介:简单的门禁系统,包含RFID,时间,温度,1602液晶,按键。 收获:①多个文件的keil工程的组织方法:Main函数包含各个头文件(.h);各个头文件中包含#ifndef,#define,#endif、声明函数、位定义、extern申明...
  • 首先明确概念,什么是单片机单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括...
  • 一、绘制51单片机原理图库 新建原理图库,并ctrl+s保存起来 2、画出方框,并放置引脚,如下图。 注意:画出第一个引脚后,可以双击修改它的编号为1,之后再次放置引脚时,编号会自动从1开始自加。 3、在方框...
  • 大家都知道,目前主要流利的日志文件系统有JFFS,YAFFS等,这些都是目前在Linux中应用较多的日志文件系统。前期在做嵌入式方面的开发工作时,发现原来同事使用FLASH存储数据时使用了非常多的全局变量来保存FLASH的...
  • 参考链接: ... 第一步:安装Altium Designer Summer 09并破解(详情见软件安装) 第二步:建立工
  • MODULE ?cstartup ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start EXTERN S...
  • 文件系统:Fat16 硬件平台:stm32f103c8 描述:利用mcu的ram虚拟一个U盘,用于存储即时小数据,通过usb以u盘的方式供上位机读取。 一:硬盘篇 1、硬盘物理结构:  盘片(platter):硬盘由很多盘片组成,每个盘片...
  • 单片机只是一个集成芯片,但它本质上还只是一个电子元件,它不... 单片机最小系统就是能让单片机工作的最简单的电路,它需要满足单片机运行的基本条件,主要有电源,时钟(振荡)电路,复位电路,EA引脚    时钟电
  • 一、面板说明 1.最上面一栏为菜单栏 2.第二栏为常用工具栏 3.左边的一栏为模式选择栏 4.旋转和镜像工具栏 旋转和镜像工具栏,第一个为顺时针宣传,第二个...
  • 摘要:为方便单片机对AT24C512中的数据进行系统化管理,在介绍AT24C512基本结构和工作原理的基础上,按照PC机文件管理的思想实现AT24C512的文件系统,提高数据管理的效率。  关键词:AT24C512 单片机 文件系统 ...
  • 2.在**Keil uVision4**的集成环境中新建一个Keil工程,将给出的程序添加到Keil工程中,编译生成单片机可执行的**hex**文件 3.用**STC-ISP**工具软件将hex文件**下载至单片机实验板**上来 4.观察发光二极管的显示效果...
1 2 3 4 5 ... 20
收藏数 8,584
精华内容 3,433
关键字:

单片机添加文件系统