雷龙发展 发表于 2024-7-24 18:22

【CS创世 SD NAND】SD NAND芯片的测评与使用(基于卷积神经网络的数字识别)

<div class='showpostmsg'><p>目录</p>

<p>前言:</p>

<p>简介:</p>

<p>对照:</p>

<p>测试:</p>

<p>使用:</p>

<p>照片存储:</p>

<p>基于卷积神经网络的数字识别:</p>

<p>&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;</p>

<p>前言:</p>

<p>感谢深圳雷龙公司寄送的样品,其中包括两张2代的4gbit和32gbit的SD NAND FLASH芯片以及一份测试板卡。</p>

<figure contenteditable="false" data-block="true" data-editor="5c13" data-offset-key="udc5-0-0">
<p><img src="https://mp.toutiao.com/mp/agw/article_material/open_image/get?code=YmJmM2Q4ODc0NDYyOTFmMjVjYzdiYzYxOTU4OTQ3YTEsMTcyMTgxNDkxNzE0MA==" width="766" /></p>

<figcaption>添加描述</figcaption>
</figure>

<p>简介:</p>

<p>根据官方文档的描述,这款芯片采用LGA-8封装,具有标准SDIO接口,并同时兼容SPI和SD接口。因此,可以直接移植标准驱动代码,支持使用SD NAND FLASH的SOC也可以用于TF卡启动。</p>

<p>以下是该芯片的主要参数(以CSNP32GCR01-BOW手册为准):</p>

<p>接口:符合标准SD Specification Version 2.0规范,包括1-I/O和4-I/O两种模式。</p>

<p>默认模式:在默认模式下,时钟频率可变范围为0-25 MHz,接口速度高达12.5 MB/sec(使用4条并行数据线路)。</p>

<p>高速模式:在高速模式下,时钟频率可变范围为0-50 MHz,接口速度高达25 MB/sec(使用4条并行数据线路)。</p>

<p>对照:</p>

<p>下面是SD NAND芯片和传统TF卡的一些对比:</p>

<figure contenteditable="false" data-block="true" data-editor="5c13" data-offset-key="6e97p-0-0">
<p><img src="https://mp.toutiao.com/mp/agw/article_material/open_image/get?code=YzU0OTAyZmFmYjY5ZjhiM2RmOGM4YzkwZmZlODgyZWMsMTcyMTgxNDkxNzE0MA==" width="766" /></p>

<figcaption>添加描述</figcaption>
</figure>

<p>目前,一些树莓派和一些国产的微处理器经常通过SD卡进行系统的移植,但一些设计不合理的卡槽经常不能保护SD卡,反而会损坏折断。相比之下,SD NAND可以通过贴片直接嵌入嵌入式设备中,更适合嵌入式环境的开发。同时,裸露的SD卡槽和松动的SD卡时常会影响系统的稳定性,因此一个可以反复擦拭的稳定存储芯片显得十分重要。</p>

<p>通过将测试板和芯片进行简单的焊接,我们可以像使用SD卡一样对SD NAND FLASH进行测试。</p>

<p>测试:</p>

<p>首先,我们使用CrystalDiskMark 8.0.4c对这款储存器进行了测试:</p>

<p>本次测试的是512MB的容量的产品,容量是真实的。我们可以看出,在包括顺序读取、顺序写入、随机读取和随机写入的四个测试方式下,SD NAND取得了不错的测试结果,接近官方数据,可以成功进行高速存储。</p>

<figure contenteditable="false" data-block="true" data-editor="5c13" data-offset-key="hedf-0-0">
<p><img src="https://mp.toutiao.com/mp/agw/article_material/open_image/get?code=NDQ0OGQ3ZDMxNmVkYThlODVkZGI5ZDM4MmVlNzVhZTgsMTcyMTgxNDkxNzE0MA==" width="267" /></p>

<figcaption>添加描述</figcaption>
</figure>

<p>使用:</p>

<p>此外,我们还利用k210与SD NAND进行了照片的存储和基于卷积神经网络的数字识别。</p>

<p>1.照片存储:</p>

<p>通过向SD NAND内烧录micropython代码,实现了k210对照片的拍摄和存储。存储速度非常快。</p>

<p>import sensor, lcd</p>

<p>from Maix import GPIO</p>

<p>from fpioa_manager import fm</p>

<p>from board import board_info</p>

<p>import os, sys</p>

<p>import time</p>

<p>import image</p>

<p>#### image size ####</p>

<p>set_windowing = (224, 224)</p>

<p>#### sensor config ####</p>

<p>sensor.reset(freq=22000000, dual_buff=False)</p>

<p>sensor.set_pixformat(sensor.RGB565)</p>

<p>sensor.set_framesize(sensor.QVGA) # 320x240</p>

<p>try:</p>

<p>sensor.set_jb_quality(95) # for IDE display quality</p>

<p>except Exception:</p>

<p>pass # no IDE support</p>

<p>if set_windowing:</p>

<p>sensor.set_windowing(set_windowing)</p>

<p># sensor.set_auto_gain(False)</p>

<p># sensor.set_auto_whitebal(False, rgb_gain_db=(0x52,0x40,0x4d))</p>

<p># sensor.set_saturation(0)</p>

<p># sensor.set_brightness(4)</p>

<p># sensor.set_contrast(0)</p>

<p># sensor.set_hmirror(True) # image horizonal mirror</p>

<p># sensor.set_vflip(True) # image vertical flip</p>

<p># sensor.set_auto_whitebal(False)</p>

<p>sensor.skip_frames()</p>

<p>#### lcd config ####</p>

<p>lcd.init(type=1, freq=15000000)</p>

<p>lcd.rotation(2)</p>

<p>#### boot key ####</p>

<p>boot_pin = 16 # board_info.BOOT_KEY</p>

<p>fm.register(boot_pin, fm.fpioa.GPIOHS0)</p>

<p>key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)</p>

<p>######################################################</p>

<p>#### main ####</p>

<p>def capture_main(key):</p>

<p>def draw_string(img, x, y, text, color, scale, bg=None , full_w = False):</p>

<p>if bg:</p>

<p>if full_w:</p>

<p>full_w = img.width()</p>

<p>else:</p>

<p>full_w = len(text)*8*scale+4</p>

<p>img.draw_rectangle(x-2,y-2, full_w, 16*scale, fill=True, color=bg)</p>

<p>img = img.draw_string(x, y, text, color=color,scale=scale)</p>

<p>return img</p>

<p>def del_all_images():</p>

<p>os.chdir(&quot;/sd&quot;)</p>

<p>images_dir = &quot;cap_images&quot;</p>

<p>if images_dir in os.listdir():</p>

<p>os.chdir(images_dir)</p>

<p>types = os.listdir()</p>

<p>for t in types:</p>

<p>os.chdir(t)</p>

<p>files = os.listdir()</p>

<p>for f in files:</p>

<p>os.remove(f)</p>

<p>os.chdir(&quot;..&quot;)</p>

<p>os.rmdir(t)</p>

<p>os.chdir(&quot;..&quot;)</p>

<p>os.rmdir(images_dir)</p>

<p># del_all_images()</p>

<p>os.chdir(&quot;/sd&quot;)</p>

<p>dirs = os.listdir()</p>

<p>images_dir = &quot;cap_images&quot;</p>

<p>last_dir = 0</p>

<p>for d in dirs:</p>

<p>if d.startswith(images_dir):</p>

<p>if len(d) &gt; 11:</p>

<p>n = int(d)</p>

<p>if n &gt; last_dir:</p>

<p>last_dir = n</p>

<p>images_dir = &quot;{}_{}&quot;.format(images_dir, last_dir+1)</p>

<p>print(&quot;save to &quot;, images_dir)</p>

<p>if images_dir in os.listdir():</p>

<p>img = image.Image()</p>

<p>img = draw_string(img, 2, 200, &quot;please del cap_images dir&quot;, color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>lcd.display(img)</p>

<p>sys.exit(1)</p>

<p>os.mkdir(images_dir)</p>

<p>last_cap_time = 0</p>

<p>last_btn_status = 1</p>

<p>save_dir = 0</p>

<p>save_count = 0</p>

<p>os.mkdir(&quot;{}/{}&quot;.format(images_dir, save_dir))</p>

<p>while(True):</p>

<p>img0 = sensor.snapshot()</p>

<p>if set_windowing:</p>

<p>img = image.Image()</p>

<p>img = img.draw_image(img0, (img.width() - set_windowing)//2, img.height() - set_windowing)</p>

<p>else:</p>

<p>img = img0.copy()</p>

<p># img = img.resize(320, 240)</p>

<p>if key.value() == 0:</p>

<p>time.sleep_ms(30)</p>

<p>if key.value() == 0 and (last_btn_status == 1) and (time.ticks_ms() - last_cap_time &gt; 500):</p>

<p>last_btn_status = 0</p>

<p>last_cap_time = time.ticks_ms()</p>

<p>else:</p>

<p>if time.ticks_ms() - last_cap_time &gt; 5000:</p>

<p>img = draw_string(img, 2, 200, &quot;release to change type&quot;, color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>else:</p>

<p>img = draw_string(img, 2, 200, &quot;release to capture&quot;, color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>if time.ticks_ms() - last_cap_time &gt; 2000:</p>

<p>img = draw_string(img, 2, 160, &quot;keep push to change type&quot;, color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>else:</p>

<p>time.sleep_ms(30)</p>

<p>if key.value() == 1 and (last_btn_status == 0):</p>

<p>if time.ticks_ms() - last_cap_time &gt; 5000:</p>

<p>img = draw_string(img, 2, 200, &quot;change object type&quot;, color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>lcd.display(img)</p>

<p>time.sleep_ms(1000)</p>

<p>save_dir += 1</p>

<p>save_count = 0</p>

<p>dir_name = &quot;{}/{}&quot;.format(images_dir, save_dir)</p>

<p>os.mkdir(dir_name)</p>

<p>else:</p>

<p>draw_string(img, 2, 200, &quot;capture image {}&quot;.format(save_count), color=lcd.WHITE,scale=1, bg=lcd.RED)</p>

<p>lcd.display(img)</p>

<p>f_name = &quot;{}/{}/{}.jpg&quot;.format(images_dir, save_dir, save_count)</p>

<p>img0.save(f_name, quality=95)</p>

<p>save_count += 1</p>

<p>last_btn_status = 1</p>

<p>img = draw_string(img, 2, 0, &quot;will save to {}/{}/{}.jpg&quot;.format(images_dir, save_dir, save_count), color=lcd.WHITE,scale=1, bg=lcd.RED, full_w=True)</p>

<p>lcd.display(img)</p>

<p>del img</p>

<p>del img0</p>

<p>def main():</p>

<p>try:</p>

<p>capture_main(key)</p>

<p>except Exception as e:</p>

<p>print(&quot;error:&quot;, e)</p>

<p>import uio</p>

<p>s = uio.StringIO()</p>

<p>sys.print_exception(e, s)</p>

<p>s = s.getvalue()</p>

<p>img = image.Image()</p>

<p>img.draw_string(0, 0, s)</p>

<p>lcd.display(img)</p>

<p>main()</p>

<figure contenteditable="false" data-block="true" data-editor="5c13" data-offset-key="1k127-0-0">
<p>EEWORLDIMGTK3</p>

<figcaption>添加描述</figcaption>
</figure>

<p>2.基于卷积神经网络的数字识别:</p>

<p>我们向SD NAND内烧录了功能代码、模型参数和模型结构。SD NAND可以很好地存储以上内容,并通过k210正确加载模型。在使用过程中,SD NAND表现出了出色的稳定性,没有出现崩溃或弹出的情况。</p>

<figure contenteditable="false" data-block="true" data-editor="5c13" data-offset-key="ei83c-0-0">
<p>EEWORLDIMGTK4</p>

<figcaption>添加描述</figcaption>
</figure>

<p># generated by maixhub, tested on maixpy3 v0.4.8</p>

<p># copy files to TF card and plug into board and power on</p>

<p>import sensor, image, lcd, time</p>

<p>import KPU as kpu</p>

<p>import gc, sys</p>

<p>input_size = (224, 224)</p>

<p>labels = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;, &#39;6&#39;, &#39;7&#39;, &#39;8&#39;]</p>

<p>anchors = </p>

<p>def lcd_show_except(e):</p>

<p>import uio</p>

<p>err_str = uio.StringIO()</p>

<p>sys.print_exception(e, err_str)</p>

<p>err_str = err_str.getvalue()</p>

<p>img = image.Image(size=input_size)</p>

<p>img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))</p>

<p>lcd.display(img)</p>

<p>def main(anchors, labels = None, model_addr=&quot;/sd/m.kmodel&quot;, sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):</p>

<p>sensor.reset()</p>

<p>sensor.set_pixformat(sensor.RGB565)</p>

<p>sensor.set_framesize(sensor.QVGA)</p>

<p>sensor.set_windowing(sensor_window)</p>

<p>sensor.set_vflip(1)</p>

<p>sensor.run(1)</p>

<p>lcd.init(type=1)</p>

<p>lcd.rotation(lcd_rotation)</p>

<p>lcd.clear(lcd.WHITE)</p>

<p>if not labels:</p>

<p>with open(&#39;labels.txt&#39;,&#39;r&#39;) as f:</p>

<p>exec(f.read())</p>

<p>if not labels:</p>

<p>print(&quot;no labels.txt&quot;)</p>

<p>img = image.Image(size=(320, 240))</p>

<p>img.draw_string(90, 110, &quot;no labels.txt&quot;, color=(255, 0, 0), scale=2)</p>

<p>lcd.display(img)</p>

<p>return 1</p>

<p>try:</p>

<p>img = image.Image(&quot;startup.jpg&quot;)</p>

<p>lcd.display(img)</p>

<p>except Exception:</p>

<p>img = image.Image(size=(320, 240))</p>

<p>img.draw_string(90, 110, &quot;loading model...&quot;, color=(255, 255, 255), scale=2)</p>

<p>lcd.display(img)</p>

<p>try:</p>

<p>task = None</p>

<p>task = kpu.load(model_addr)</p>

<p>kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:, nms_value: </p>

<p>while(True):</p>

<p>img = sensor.snapshot()</p>

<p>t = time.ticks_ms()</p>

<p>objects = kpu.run_yolo2(task, img)</p>

<p>t = time.ticks_ms() - t</p>

<p>if objects:</p>

<p>for obj in objects:</p>

<p>pos = obj.rect()</p>

<p>img.draw_rectangle(pos)</p>

<p>img.draw_string(pos, pos, &quot;%s : %.2f&quot; %(labels, obj.value()), scale=2, color=(255, 0, 0))</p>

<p>img.draw_string(0, 200, &quot;t:%dms&quot; %(t), scale=2, color=(255, 0, 0))</p>

<p>lcd.display(img)</p>

<p>except Exception as e:</p>

<p>raise e</p>

<p>finally:</p>

<p>if not task is None:</p>

<p>kpu.deinit(task)</p>

<p>if __name__ == &quot;__main__&quot;:</p>

<p>try:</p>

<p># main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)</p>

<p>main(anchors = anchors, labels=labels, model_addr=&quot;/sd/model-54796.kmodel&quot;)</p>

<p>except Exception as e:</p>

<p>sys.print_exception(e)</p>

<p>lcd_show_except(e)</p>

<p>finally:</p>

<p>gc.collect()</p>

<p>通过以上两个实验,SD NAND代替传统的SD/TF卡进行数据存储表现出了极大的优势和稳定性。</p>

<p>​</p>

<p>&nbsp;</p>
</div><script>                                var loginstr = '<div class="locked">查看精华帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                               
                                if(parseInt(discuz_uid)==0){
                                                                                        (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                }
</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

lugl4313820 发表于 2024-7-24 20:49

<p>雷总,好久不见呀,最近生意怎么样呀?</p>

lugl4313820 发表于 2024-7-24 20:50

<p>去微信上回复一下我,我找了你好久,找不到。</p>

通途科技 发表于 2024-8-3 12:02

<p>感谢分享,来学习的,收藏下来,慢慢学习,加油!!!!</p>
页: [1]
查看完整版本: 【CS创世 SD NAND】SD NAND芯片的测评与使用(基于卷积神经网络的数字识别)