历史上的今天
返回首页

历史上的今天

今天是:2024年09月20日(星期五)

正在发生

2019年09月20日 | 第25章 串行FLASH文件系统FatFs—零死角玩转STM32-F429系列

2019-09-20 来源:eefocus

本章参考资料:《00index_e.html》,这是FatFs官方的编译好的HTML文档,里面有FatFs所有函数的介绍和函数的应用示例,学习FatFs看这个官方的文档即可。

图 261 FatFs参考资料


25.1 文件系统

即使读者可能不了解文件系统,读者也一定对"文件"这个概念十分熟悉。数据在PC上是以文件的形式储存在磁盘中的,这些数据的形式一般为ASCII码或二进制形式。在上一章我们已经写好了SPI Flash芯片的驱动函数,我们可以非常方便的在SPI Flash芯片上读写数据。如需要记录本书的书名"零死角玩转STM32-F429系列",可以把这些文字转化成ASCII码,存储在数组中,然后调用SPI_FLASH_BufferWrite函数,把数组内容写入到SPI Flash芯片的指定地址上,在需要的时候从该地址把数据读取出来,再对读出来的数据以ASCII码的格式进行解读。


但是,这样直接存储数据会带来极大的不便,如难以记录有效数据的位置,难以确定存储介质的剩余空间,以及应以何种格式来解读数据。就如同一个巨大的图书馆无人管理,杂乱无章地存放着各种书籍,难以查找所需的文档。想象一下图书馆的采购人员购书后,把书籍往馆内一扔,拍拍屁股走人,当有人来借阅某本书的时候,就不得不一本本地查找。这样直接存储数据的方式对于小容量的存储介质如EEPROM还可以接受,但对于SPI Flash芯片或者SD卡之类的大容量设备,我们需要一种高效的方式来管理它的存储内容。


这些管理方式即为文件系统,它是为了存储和管理数据,而在存储介质建立的一种组织结构,这些结构包括操作系统引导区、目录和文件。常见的windows下的文件系统格式包括FAT32、NTFS、exFAT。在使用文件系统前,要先对存储介质进行格式化。格式化先擦除原来内容,在存储介质上新建一个文件分配表和目录。这样,文件系统就可以记录数据存放的物理地址,剩余空间。


使用文件系统时,数据都以文件的形式存储。写入新文件时,先在目录中创建一个文件索引,它指示了文件存放的物理地址,再把数据存储到该地址中。当需要读取数据时,可以从目录中找到该文件的索引,进而在相应的地址中读取出数据。具体还涉及到逻辑地址、簇大小、不连续存储等一系列辅助结构或处理过程。


文件系统的存在使我们在存取数据时,不再是简单地向某物理地址直接读写,而是要遵循它的读写格式。如经过逻辑转换,一个完整的文件可能被分开成多段存储到不连续的物理地址,使用目录或链表的方式来获知下一段的位置。


上一章的SPI Flash芯片驱动只完成了向物理地址写入数据的工作,而根据文件系统格式的逻辑转换部分则需要额外的代码来完成。实质上,这个逻辑转换部分可以理解为当我们需要写入一段数据时,由它来求解向什么物理地址写入数据、以什么格式写入及写入一些原始数据以外的信息(如目录)。这个逻辑转换部分代码我们也习惯称之为文件系统。


25.2 FatFs文件系统简介

上面提到的逻辑转换部分代码(文件系统)即为本章的要点,文件系统庞大而复杂,它需要根据应用的文件系统格式而编写,而且一般与驱动层分离开来,很方便移植,所以工程应用中一般是移植现成的文件系统源码。


FatFs是面向小型嵌入式系统的一种通用的FAT文件系统。它完全是由AISI C语言编写并且完全独立于底层的I/O介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如8051、PIC、AVR、SH、Z80、H8、ARM等。FatFs支持FAT12、FAT16、FAT32等格式,所以我们利用前面写好的SPI Flash芯片驱动,把FatFs文件系统代码移植到工程之中,就可以利用文件系统的各种函数,对SPI Flash芯片以"文件"格式进行读写操作了。


FatFs文件系统的源码可以从fatfs官网下载:


http://elm-chan.org/fsw/ff/00index_e.html


25.2.1 FatFs的目录结构

在移植FatFs文件系统到开发板之前,我们先要到FatFs的官网获取源码,最新版本为R0.11a,官网有对FatFs做详细的介绍,有兴趣可以了解。解压之后可看到里面有 doc 和 src 这两个文件夹,见图 251。doc 文件夹里面是一些使用帮助文档; src 才是FatFs文件系统的源码。

图 251 FatFs文件目录


25.2.2 FatFs帮助文档

打开 doc 文件夹,可看到如图 252的文件目录:

图 252 doc文件夹的文件目录


其中 en 和 ja 这两个文件夹里面是编译好的html文档,讲的是FATFS里面各个函数的使用方法,这些函数都是封装得非常好的函数,利用这些函数我们就可以操作SPI Flash芯片。有关具体的函数我们在用到的时候再讲解。这两个文件夹的唯一区别就是 en 文件夹下的文档是英文的,ja 文件夹下的是日文的。img文件夹包含en和ja文件夹下文件需要用到的图片,还有四个名为app.c文件,内容都是FatFs具体应用例程。00index_e.html和00index_j.html是一些关于FATFS的简介,至于另外两个文件可以不看。


25.2.3 FATFS源码

打开 src 文件夹,可看到如图 253的文件目录:


图 253 src文件夹的文件目录


option 文件夹下是一些可选的外部c文件,包含了多语言支持需要用到的文件和转换函数。


diskio.c文件是FatFs移植最关键的文件,它为文件系统提供了最底层的访问SPI Flash芯片的方法,FatFs有且仅有它需要用到与SPI Flash芯片相关的函数。diskio.h定义了FatFs用到的宏,以及diskio.c文件内与底层硬件接口相关的函数声明。


00history.txt介绍了FatFs的版本更新情况。


00readme.txt说明了当前目录下 diskio.c 、diskio.h、ff.c、ff.h、integer.h的功能。


src文件夹下的源码文件功能简介如下:


    integer.h:文件中包含了一些数值类型定义。


    diskio.c:包含底层存储介质的操作函数,这些函数需要用户自己实现,主要添加底层驱动函数。


    ff.c: FatFs核心文件,文件管理的实现方法。该文件独立于底层介质操作文件的函数,利用这些函数实现文件的读写。


    cc936.c:本文件在option目录下,是简体中文支持所需要添加的文件,包含了简体中文的GBK和Unicode相互转换功能函数。


    ffconf.h:这个头文件包含了对FatFs功能配置的宏定义,通过修改这些宏定义就可以裁剪FatFs的功能。如需要支持简体中文,需要把ffconf.h中的_CODE_PAGE 的宏改成936并把上面的cc936.c文件加入到工程之中。


建议阅读这些源码的顺序为:integer.h --> diskio.c --> ff.c 。


阅读文件系统源码ff.c文件需要一定的功底,建议读者先阅读FAT32的文件格式,再去分析ff.c文件。若仅为使用文件系统,则只需要理解integer.h及diskio.c文件并会调用ff.c文件中的函数就可以了。本章主要讲解如何把FATFS文件系统移植到开发板上,并编写一个简单读写操作范例。


25.3 FatFs文件系统移植实验

25.3.1 FatFs程序结构图

移植FatFs之前我们先通过FatFs的程序结构图了解FatFs在程序中的关系网络,见图 254。


图 254 FatFs程序结构图


用户应用程序需要由用户编写,想实现什么功能就编写什么的程序,一般我们只用到f_mount()、f_open()、f_write()、f_read()就可以实现文件的读写操作。


FatFs组件是FatFs的主体,文件都在源码src文件夹中,其中ff.c、ff.h、integer.h以及diskio.h四个文件我们不需要改动,只需要修改ffconf.h和diskio.c两个文件。


底层设备输入输出要求实现存储设备的读写操作函数、存储设备信息获取函数等等。我们使用SPI Flash芯片作为物理设备,在上一章节已经编写好了SPI Flash芯片的驱动程序,这里我们就直接使用。


25.3.2 硬件设计

FatFs属于软件组件,不需要附带其他硬件电路。我们使用SPI Flash芯片作为物理存储设备,其硬件电路在上一章已经做了分析,这里就直接使用。


25.3.3 FatFs移植步骤

上一章我们已经实现了SPI Flash芯片驱动程序,并实现了读写测试,为移植FatFs方便,我们直接拷贝一份工程,我们在工程基础上添加FatFs组件,并修改main函数的用户程序即可。


1)    先拷贝一份SPI Flash芯片测试的工程文件(整个文件夹),并修改文件夹名为"SPI—FatFs文件系统"。将FatFs源码中的src文件夹整个文件夹拷贝一份至"SPI—FatFs文件系统USER"文件夹下并修改名为"FATFS",见图 255。

图 255 拷贝FatFs源码到工程


2)    使用KEIL软件打开工程文件(..SPI—FatFs文件系统ProjectRVMDK(uv5) BH-F429.uvprojx),并将FatFs组件文件添加到工程中,需要添加有ff.c、diskio.c和cc936.c三个文件,见图 256。


图 256 添加FatFS文件到工程


3)    添加FATFS文件夹到工程的include选项中。打开工程选项对话框,选择"C/C++"选项下的"Include Paths"项目,在弹出路径设置对话框中选择添加"FATFS"文件夹,见图 257。

图 257 添加FATFS路径到工程选项


4)    如果现在编译工程,可以发现有两个错误,一个是来自diskio.c文件,提示有一些头文件没找,diskio.c文件内容是与底层设备输入输出接口函数文件,不同硬件设计驱动就不同,需要的文件也不同;另外一个错误来自cc936.c文件,提示该文件不是工程所必需的,这是因为FatFs默认使用日语,我们想要支持简体中文需要修改FatFs的配置,即修改ffconf.h文件。至此,将FatFs添加到工程的框架已经操作完成,接下来要做的就是修改diskio.c文件和ffconf.h文件。


25.3.4 FatFs底层设备驱动函数

FatFs文件系统与底层介质的驱动分离开来,对底层介质的操作都要交给用户去实现,它仅仅是提供了一个函数接口而已。表 251为FatFs移植时用户必须支持的函数。通过表 251我们可以清晰知道很多函数是在一定条件下才需要添加的,只有前三个函数是必须添加的。我们完全可以根据实际需求选择实现用到的函数。


前三个函数是实现读文件最基本需求。接下来三个函数是实现创建文件、修改文件需要的。为实现格式化功能,需要在disk_ioctl添加两个获取物理设备信息选项。我们一般只有实现前面六个函数就可以了,已经足够满足大部分功能。


为支持简体中文长文件名称需要添加ff_convert和ff_wtoupper函数,实际这两个已经在cc936.c文件中实现了,我们只要直接把cc936.c文件添加到工程中就可以了。


后面六个函数一般都不用。如真有需要可以参考syscall.c文件(srcoption文件夹内)。


表 251 FatFs移植需要用户支持函数

image.png?imageView2/2/w/550

底层设备驱动函数是存放在diskio.c文件,我们的目的就是把diskio.c中的函数接口与SPI Flash芯片驱动连接起来。总共有五个函数,分别为设备状态获取(disk_status)、设备初始化(disk_initialize)、扇区读取(disk_read)、扇区写入(disk_write)、其他控制(disk_ioctl)。


接下来,我们对每个函数结合SPI Flash芯片驱动做详细讲解。


宏定义

代码清单 251 物理编号宏定义


1 /* 为每个设备定义一个物理编号 */


2 #define ATA 0 // 预留SD卡使用


3 #define SPI_FLASH 1 // 外部SPI Flash


这两个宏定义在FatFs中非常重要,FatFs是支持多物理设备的,必须为每个物理设备定义一个不同的编号。


SD卡是预留接口,在讲解SDIO接口相关章节后会用到,可以实现使用读写SD卡内文件。


设备状态获取

代码清单 252设备状态获取


1 DSTATUS disk_status (


2 BYTE pdrv /* 物理编号 */


3 )


4 {


5


6 DSTATUS status = STA_NOINIT;


7


8 switch (pdrv) {


9 case ATA: /* SD CARD */


10 break;


11


12 case SPI_FLASH:


13 /* SPI Flash状态检测:读取SPI Flash 设备ID */


14 if (sFLASH_ID == SPI_FLASH_ReadID()) {


15 /* 设备ID读取结果正确 */


16 status &= ~STA_NOINIT;


17 } else {


18 /* 设备ID读取结果错误 */


19 status = STA_NOINIT;;


20 }


21 break;


22


23 default:


24 status = STA_NOINIT;


25 }


26 return status;


27 }


disk_status函数只有一个参数pdrv,表示物理编号。一般我们都是使用switch函数实现对pdrv的分支判断。对于SD卡只是预留接口,留空即可。对于SPI Flash芯片,我们直接调用在SPI_FLASH_ReadID()获取设备ID,然后判断是否正确,如果正确,函数返回正常标准;如果错误,函数返回异常标志。SPI_FLASH_ReadID()是定义在bsp_spi_flash.c文件中,上一章节已做了分析。


设备初始化

代码清单 253 设备初始化


1 DSTATUS disk_initialize (


2 BYTE pdrv /* 物理编号 */


3 )


4 {


5 uint16_t i;


6 DSTATUS status = STA_NOINIT;


7 switch (pdrv) {


8 case ATA: /* SD CARD */


9 break;


10


11 case SPI_FLASH: /* SPI Flash */


12 /* 初始化SPI Flash */


13 SPI_FLASH_Init();


14 /* 延时一小段时间 */


15 i=500;


16 while (--i);


17 /* 唤醒SPI Flash */


18 SPI_Flash_WAKEUP();


19 /* 获取SPI Flash芯片状态 */


20 status=disk_status(SPI_FLASH);


21 break;


22


23 default:


24 status = STA_NOINIT;


25 }


26 return status;


27 }


disk_initialize函数也是有一个参数pdrv,用来指定设备物理编号。对于SPI Flash芯片我们调用SPI_FLASH_Init()函数实现对SPI Flash芯片引脚GPIO初始化配置以及SPI通信参数配置。SPI_Flash_WAKEUP()函数唤醒SPI Flash芯片,当SPI Flash芯片处于睡眠模式时需要唤醒芯片才可以进行读写操作。


最后调用disk_status函数获取SPI Flash芯片状态,并返回状态值。


读取扇区

代码清单 254 扇区读取


1 DRESULT disk_read (


2 BYTE pdrv, /* 设备物理编号(0..) */


3 BYTE *buff, /* 数据缓存区 */


4 DWORD sector, /* 扇区首地址 */


5 UINT count /* 扇区个数(1..128) */


6 )


7 {


8 DRESULT status = RES_PARERR;


9 switch (pdrv) {


10 case ATA: /* SD CARD */


11 break;


12


13 case SPI_FLASH:


14 /* 扇区偏移6MB,外部Flash文件系统空间放在SPI Flash后面10MB空间 */


15 sector+=1536;


16 SPI_FLASH_BufferRead(buff, sector <<12, count<<12);


17 status = RES_OK;


18 break;


19


20 default:


21 status = RES_PARERR;


22 }


23 return status;


24 }


disk_read函数有四个形参。pdrv为设备物理编号。buff是一个BYTE类型指针变量,buff指向用来存放读取到数据的存储区首地址。sector是一个DWORD类型变量,指定要读取数据的扇区首地址。count是一个UINT类型变量,指定扇区数量。


BYTE类型实际是unsigned char类型,DWORD类型实际是unsigned long类型,UINT类型实际是 unsigned int类型,类型定义在integer.h文件中。


开发板使用的SPI Flash芯片型号为W25Q128FV,每个扇区大小为4096个字节(4KB),总共有16M字节空间,为兼容后面实验程序,我们只将后部分10MB空间分配给FatFs使用,前部分6MB空间用于其他实验需要,即FatFs是从6MB空间开始,为实现这个效果需要将所有的读写地址都偏移1536个扇区空间。


对于SPI Flash芯片,主要是使用SPI_FLASH_BufferRead()实现在指定地址读取指定长度的数据,它接收三个参数,第一个参数为指定数据存放地址指针。第二个参数为指定数据读取地址,这里使用左移运算符,左移12位实际是乘以4096,这与每个扇区大小是息息相关的。第三个参数为读取数据个数,也是需要使用左移运算符。


扇区写入

代码清单 255 扇区输入


1 DRESULT disk_write (


2 BYTE pdrv, /* 设备物理编号(0..) */


3 const BYTE *buff, /* 欲写入数据的缓存区 */


4 DWORD sector, /* 扇区首地址 */


5 UINT count /* 扇区个数(1..128) */


6 )


7 {


8 uint32_t write_addr;


9 DRESULT status = RES_PARERR;


10 if (!count) {


11 return RES_PARERR; /* Check parameter */


12 }


13


14 switch (pdrv) {


15 case ATA: /* SD CARD */


16 break;


17


18 case SPI_FLASH:


19 /* 扇区偏移6MB,外部Flash文件系统空间放在SPI Flash后面10MB空间 */


20 sector+=1536;


21 write_addr = sector<<12;


22 SPI_FLASH_SectorErase(write_addr);


23 SPI_FLASH_BufferWrite((u8 *)buff,write_addr,count<<12);


24 status = RES_OK;


25 break;


26


27 default:


28 status = RES_PARERR;


29 }


30 return status;


31 }


disk_write函数有四个形参,pdrv为设备物理编号。buff指向待写入扇区数据的首地址。sector,指定要读取数据的扇区首地址。count指定扇区数量。对于SPI Flash芯片,在写入数据之前需要先擦除,所以用到扇区擦除函数(SPI_FLASH_SectorErase)。然后就是在调用数据写入函数(SPI_FLASH_BufferWrite)把数据写入到指定位置内。


其他控制

代码清单 256 其他控制


1 DRESULT disk_ioctl (


2 BYTE pdrv, /* 物理编号 */


3 BYTE cmd, /* 控制指令 */


4 void *buff /* 写入或者读取数据地址指针 */


5 )


6 {


7 DRESULT status = RES_PARERR;


8 switch (pdrv) {


9 case ATA: /* SD CARD */


10 break;


11


12 case SPI_FLASH:


13 switch (cmd) {


14 /* 扇区数量:2560*4096/1024/1024=10(MB) */


15 case GET_SECTOR_COUNT:


16 *(DWORD * )buff = 2560;


17 break;


18 /* 扇区大小 */


19 case GET_SECTOR_SIZE :


20 *(WORD * )buff = 4096;


21 break;


22 /* 同时擦除扇区个数 */


23 case GET_BLOCK_SIZE :


24 *(DWORD * )buff = 1;


25 break;


26 }


27 status = RES_OK;


28 break;


29


30 default:


31 status = RES_PARERR;


32 }


33 return status;


34 }


disk_ioctl函数有三个形参,pdrv为设备物理编号,cmd为控制指令,包括发出同步信号、获取扇区数目、获取扇区大小、获取擦除块数量等等指令,buff为指令对应的数据指针。


对于SPI Flash芯片,为支持FatFs格式化功能,需要用到获取扇区数量(GET_SECTOR_COUNT)指令和获取擦除块数量(GET_BLOCK_SIZE)。另外,SD卡扇区大小为512字节,SPI Flash芯片一般设置扇区大小为4096字节,所以需要用到获取扇区大小(GET_SECTOR_SIZE)指令。


时间戳获取

代码清单 257 时间戳获取


1 __weak DWORD get_fattime(void)


2 {


3 /* 返回当前时间戳 */


4 return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */


5 | ((DWORD)1 << 21) /* Month 1 */


6 | ((DWORD)1 << 16) /* Mday 1 */


7 | ((DWORD)0 << 11) /* Hour 0 */


8 | ((DWORD)0 << 5) /* Min 0 */


9 | ((DWORD)0 >> 1); /* Sec 0 */


10 }


get_fattime函数用于获取当前时间戳,在ff.c文件中被调用。FatFs在文件创建、被修改时会记录时间,这里我们直接使用赋值方法设定时间戳。为更好的记录时间,可以使用控制器RTC功能,具体要求返回值格式为:


    bit31:25 ——从1980至今是多少年,范围是 (0..127) ;


    bit24:21 ——月份,范围为 (1..12) ;


    bit20:16 ——该月份中的第几日,范围为(1..31) ;


    bit15:11——时,范围为 (0..23);


     bit10:5 ——分,范围为 (0..59);


     bit4:0 ——秒/ 2,范围为 (0..29) 。


25.3.5 FatFs功能配置

ffconf.h文件是FatFs功能配置文件,我们可以对文件内容进行修改,使得FatFs更符合我们的要求。ffconf.h对每个配置选项都做了详细的使用情况说明。下面只列出修改的配置,其他配置采用默认即可。

推荐阅读

史海拾趣

Fortiming Corporation公司的发展小趣事

背景:随着公司规模的扩大和产品线的丰富,Fortiming开始寻求更广阔的市场空间。

发展:公司积极参加国内外电子展会,展示其最新技术和产品,吸引了众多客户的关注。同时,Fortiming还与国际知名电子企业建立了合作关系,共同开发新产品,开拓新市场。这些合作不仅提升了Fortiming的品牌影响力,还为公司带来了更多的商业机会。

乔光电子(FTR)公司的发展小趣事

背景:2001年9月5日,Fortiming Corporation在内华达州正式成立(来源:企查查)。在成立之初,公司就明确了自己的市场定位——专注于提供高质量的石英晶振、晶体振荡器等频率控制产品。

发展:面对当时竞争激烈的电子行业,Fortiming凭借其对技术的深刻理解和对市场需求的敏锐洞察,迅速在石英晶振领域站稳脚跟。公司不仅注重产品研发,还积极引进先进生产设备,提升产品质量和生产效率。

Advanced Thermal Products Inc公司的发展小趣事

随着技术的不断积累,ATP公司开始加大产品创新的力度。他们推出了一系列具有竞争力的热管理产品,不仅满足了市场对于高效散热的需求,还凭借其优异的性能赢得了客户的青睐。同时,公司积极拓展市场,与多家电子设备制造商建立了长期合作关系,产品广泛应用于手机、电脑、服务器等领域。

芯联(CHIPLINK)公司的发展小趣事

芯联集成始终将技术创新作为公司发展的核心驱动力。公司不断加大研发投入,积极推动技术迭代,确保在行业内保持领先地位。同时,公司还注重知识产权保护,积极申请专利,为公司的技术成果提供了坚实的法律保障。这些努力使芯联集成在竞争中始终保持优势,赢得了市场的广泛认可。

Bkc Semiconductors Inc公司的发展小趣事

随着全球环保意识的提高,Bkc积极响应绿色发展的号召。公司不仅加大了对环保技术和绿色生产的投入,还积极参与社会公益事业和环保活动。通过实际行动履行企业社会责任,Bkc不仅赢得了社会的尊重和支持,也为公司的可持续发展注入了新的动力。

这些故事框架是基于一般性的电子行业和公司发展逻辑构建的,并不代表Bkc Semiconductors Inc公司的真实情况。如果您需要更具体、更准确的信息,建议直接查阅该公司的官方网站、年报或相关新闻报道。

潮州三环(Three-circle)公司的发展小趣事

潮州三环(集团)股份有限公司,最初成立于1970年,主要从事陶瓷基体及固定电阻器的制造和销售。然而,随着电子行业的快速发展,公司意识到单一产品已无法满足市场需求。因此,在1996年,三环集团开始投资生产片式电阻用的氧化铝陶瓷基片,这一决策标志着公司正式进入片式化元件制造领域。通过引进国外先进设备和技术,三环集团成功实现了电阻及瓷体的自动化生产,为公司后续的发展奠定了坚实基础。

问答坊 | AI 解惑

matlab珍藏实例大分享

分享几个大学期间的matlab实例分享,大家有兴趣学matlab的可以拿来参考,较多的用到GUI界面设计~~~ MATLAB界面制作总结1. 7以上版本的matlab,控件pushbutton背景颜色修改以后并没有什么明显效果,只是按钮的边缘显示为所设置的背景颜色。  ...…

查看全部问答>

请教CE如何读取nandflash容量

    最近遇到一个问题,不知道如何读取系统所在nandflash的容量。目前我们系统ms不知道自己flash有多大,不停的copy文件进去就会把nk.bin所在的区域冲掉,然后系统就挂掉了。不知道有么有大哥遇到过?…

查看全部问答>

现在从网络接收H.264视频流,然后在WinCE上边解码边播放,请给个思路呀!

现在从网络接收H.264视频流,然后在WinCE上边解码边播放,请给个思路呀!…

查看全部问答>

送分了进者有份啊

现有项目 个人 团队皆可合作 最好在广州或者深圳 有意邮件yqb_box@163.com 或者QQ:437395559 在PDA上做应用软件开发 PDA支持读卡器 条码扫描 CDMA GSM 网络 GPS 打印机等 应用相对简单 在PDA上能录入数据 检索服务器上的相关信息 驱动设备 设备 ...…

查看全部问答>

抗干扰复位电路

此图是单片机抗干扰电路 请问它都抗了哪些方面的干扰,原理是什么…

查看全部问答>

有人要热敏打印机驱动不,可以联系xgx_a1@163.com

有人要热敏打印机驱动不,可以联系xgx_a1@163.com…

查看全部问答>

现在对430的时钟有点迷糊,希望高人指点?

ACLK,MCLK,SMCLK三个什么意思理解,可是有什么具体的关系,求指点?…

查看全部问答>

c1602在usb仿真器调试下不亮

我用的是f149的板子,在上面驱动1602,程序都对,就是使用usb仿真器时lcd不亮,用那种usb线直接供电的时候它倒是亮,不知道什么原因。求大侠指教啊…

查看全部问答>

刚画了个简单的51仿PLC电路,各位大大们帮看一下哈!

我是新手,刚画了个简单的51仿PLC电路,想做个板子试试,但不知有没有什么问题,所以请大家帮指点一下。…

查看全部问答>