历史上的今天

今天是:2024年09月19日(星期四)

正在发生

2019年09月19日 | 第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

发布者:陈风102 来源: eefocus关键字:QR-Decoder  OV5640  二维码识别  STM32-F429系列 手机看文章 扫描二维码
随时随地手机看文章

本章参考资料:《STM32F4xx 中文参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f4xx_dsp_stdperiph_lib_um.chm》。


关于开发板配套的OV5640摄像头参数可查阅《ov5640datasheet》配套资料获知。


STM32F4芯片具有浮点运算单元,适合对图像信息使用DSP进行基本的图像处理,其处理速度比传统的8、16位机快得多,而且它还具有与摄像头通讯的专用DCMI接口,所以使用它驱动摄像头采集图像信息并进行基本的加工处理非常适合。本章讲解如何使用二维码识别库进行二维码的识别。


47.1 二维码简介

二维码,又称二维条码或二维条形码,二维条码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"、"1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化等特点。二维条码/二维码能够在横向和纵向两个方位同时表达信息,因此能在很小的面积内表达大量的信息。


47.2 二维条形码类型

47.2.1 矩阵式二维条码

矩阵式二维条码(2D MATRIX BAR CODE)又称:棋盘式二维条码。有代表性的矩阵式二维条码有:QR Code 、Data Matrix、Maxi Code、Code one 等,目前最流行的是QR CODE。见图 471。


图 471 矩阵式二维码


47.2.2 行排列式二维条码

行排列式二维条码(2D STACKED BAR CODE)又称:堆积式二维条码或层排式二维条码,其编码原理是建立在一维条码基础之上,按需要堆积成二行或多行。有代表性的行排式二维条码有:PDF417、CODE49、CODE 16K等。见图 472。


图 472 行排列式二维条码


47.3 二维条形码的优点

1.    可靠性强,条形码的读取准确率远远超过人工记录,平均每15000个字符才会出现一个错误。


2.    效率高,条形码的读取速度很快,相当于每秒40个字符。


3.    成本低,与其它自动化识别技术相比较,条形码技术仅仅需要一小张贴纸和相对构造简单的光学扫描仪,成本相当低廉。


4.    易于制作,条形码制作:条形码的编写很简单,制作也仅仅需要印刷,被称作为"可印刷的计算机语言"。


5.    构造简单,条形码识别设备的构造简单,使用方便。


6.    灵活实用,条形码符号可以手工键盘输入,也可以和有关设备组成识别系统实现自动化识别,还可和其他控制设备联系起来实现整个系统的自动化管理。


7.    高密度,二维条码通过利用垂直方向的堆积来提高条码的信息密度,而且采用高密度图形表示,因此不需事先建立数据库,真正实现了用条码对信息的直接描述。


8.    纠错功能,二维条形码不仅能防止错误,而且能纠正错误,即使条形码部分损坏,也能将正确的信息还原出来。


9.    多语言形式、可表示图像,二维条码具有字节表示模式,即提供了一种表示字节流的机制。不论何种语言文字它们在计算机中存储时以机内码的形式表现,而内部码都是字节码,可识别多种语言文字的条码。


10.    具有加密机制,可以先用一定的加密算法将信息加密,再用二维条码表示。在识别二维条码时,再加以一定的解密算法,便可以恢复所表示的信息。


47.4 QR二维码的编码及识别

47.4.1 QR码基本结构

QR码基本结构,见图 473。


1.    位置探测图形、位置探测图形分隔符、定位图形:用于对二维码的定位,对每个QR码来说,位置都是固定存在的,只是大小规格会有所差异。


2.    校正图形:规格确定,校正图形的数量和位置也就确定了。


3.    格式信息:表示改二维码的纠错级别,分为L、M、Q、H。


4.    版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每边增加4个模块。


5.    数据和纠错码字:实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误)。

图 473 QR码基本结构


47.4.2 QR码编码过程

1.    数据分析:确定编码的字符类型,按相应的字符集转换成符号字符; 选择纠错等级,在规格一定的条件下,纠错等级越高其真实数据的容量越小。


2.    数据编码:将数据字符转换为位流,每8位一个码字,整体构成一个数据的码字序列。其实知道这个数据码字序列就知道了二维码的数据内容。见表 471和表 472。


表 471 QR码数据容量

image.png

表 472 QR数据模式指示符

image.png

3.    编码过程:数据可以按照一种模式进行编码,以便进行更高效的解码,例如:对数据:01234567编码(版本1-H)。


a)    分组:012 345 67


b)    转成二进制:


012 → 0000001100


345 → 0101011001


67 → 1000011


c)    转成序列:0000001100 0101011001 1000011


d)    字符数转成二进制:8 → 0000001000


e)    加入模式指示符:


0001:0001 0000001000 0000001100 0101011001 1000011


对于字母、中文、日文等只是分组的方式、模式等内容有所区别。基本方法是一致的。


4.    纠错编码:按需要将上面的码字序列分块,并根据纠错等级和分块的码字,产生纠错码字,并把纠错码字加入到数据码字序列后面,成为一个新的序列。


错误修正容量, L水平有7%的字码可被修正; M水平有15%的字码可被修正;Q水平有25%的字码可被修正;H水平有30%的字码可被修正。


二维码规格和纠错等级确定的情况下,其实它所能容纳的码字总数和纠错码字数也就确定了,比如:版本10,纠错等级时H时,总共能容纳346个码字,其中224个纠错码字。 


就是说二维码区域中大约1/3的码字时冗余的。对于这224个纠错码字,它能够纠正112个替代错误(如黑白颠倒)或者224个据读错误(无法读到或者无法译码),这样纠错容量为:112/346=32.4%。


5.    构造最终数据信息:在规格确定的条件下,将上面产生的序列按次序放如分块中,按规定把数据分块,然后对每一块进行计算,得出相应的纠错码字区块,把纠错码字区块按顺序构成一个序列,添加到原先的数据码字序列后面。


        例如:D1, D12, D23, D35, D2, D13, D24, D36, ... D11, D22, D33, D45, D34, D46, E1, E23,E45, E67, E2, E24, E46, E68,...


6.    构造矩阵:将探测图形、分隔符、定位图形、校正图形和码字模块放入矩阵中。把上面的完整序列填充到相应规格的二维码矩阵的区域中,见图 474 构造矩阵。

图 474 构造矩阵


7.    掩摸:将掩摸图形用于符号的编码区域,使得二维码图形中的深色和浅色(黑色和白色)区域能够比率最优的分布。见图 474 构造矩阵。


8.    格式和版本信息:生成格式和版本信息放入相应区域内。版本7-40都包含了版本信息,没有版本信息的全为0。二维码上两个位置包含了版本信息,它们是冗余的。版本信息共18位,6X3的矩阵,其中6位是数据位,如版本号8,数据位的信息时 001000,后面的12位是纠错位。


47.4.3 QR码识别过程

通过图像的采集设备(激光扫描器、面阵CCD、数码相机等成像设备),我们得到含有条码的图像,此后主要经过条码定位(预处理,定位,角度纠正和特征值提取)、分割和解码三个步骤实现条码的识别。


1.    条码的定位就是找到条码符号的图像区域,对有明显条码特征的区域进行定位。然后根据不同条码的定位图形结构特征对不同的条码符号进行下一步的处理。


2.    实现条码的定位,采用以下步骤:


a)    利用点运算的阈值理论将采集到的图象变为二值图像, 即对图像进行二值化处理;


b)    得到二值化图像后,对其进行膨胀运算;


c)    对膨胀后的图象进行边缘检测得到条码区域的轮廓;


下图 475是经过上述处理后得到的一系列图像。

图 475 图像处理


3.    对图像进行二值化处理,按下式进行


其中,f(x,y)是点(x,y)处像素的灰度值,T为阈值(自适应门限)。找到条码区域后,我们还要进一步区分到底是哪种矩阵式条码。下面图形是几种常见的矩阵式条码:


a)    位于左上角、左下角、右上角的三个定位图形


b)    位于符号中央的三个等间距同心圆环(或称公牛眼定位图形)


c)    位于左边和下边的两条垂直的实线段


图 476 图像处理


4.    条码的分割


边缘检测后条码区域的边界不是很完整,所以需要进一步的修正边界,然后分割出一个完整的条码区域。首先采用区域增长的方法对符号进行分割,以此修正条码边界。其基本思想是从符号内的一个小区域(种子)开始,通过区域增长来修正条码边界,把符号内的所有点都包括在这个边界内。然后通过凸壳计算准确分割出整个符号。之后区域增长和凸壳计算交替进行,通常对那些密度比较大的条码重复两次就足够了,而对于那些模块组合比较稀疏的条码至少要重复四次。


5.    译码


得到一幅标准的条码图像后,对该符号进行网格采样,对网格每一个交点上的图像像素取样,并根据阈值确定是深色块还是浅色块。构造一个位图,用二进制的"1"表示深色像素, "0"表示浅色像素,从而得到条码的原始二进制序列值,然后对这些数据进行纠错和译码,最后根据条码的逻辑编码规则把这些原始的数据位流转换成数据码字,即将码字图像符号换成ASCII码字符串。


47.5 QR-Decoder-OV564摄像头实验

本小节讲解如何使用QR-Code库在DCMI—OV5640摄像头实验基础上进行二维码解码的过程,建议学习之前先把DCMI—OV5640摄像头实验弄明白。


学习本小节内容时,请打开配套的"QR-Decoder-OV5640"工程配合阅读。由于硬件设计方面跟DCMI—OV5640摄像头实验的是一样的,这里不再重复。下面直接介绍如何使用QR-Code库进行二维码识别。OV5640识别二维码的过程包括以下几个重要部分:图像采集,液晶驱动,图像处理,数据解码,串口打印输出结果。见图 477。

图 477 OV5640识别二维码过程


47.5.1 QR-Code解码库特点

QR-Code解码库是秉火专门针对STM32F429移植的一个的条码解码库,因为其结构复杂,移植过程繁琐,所以打包为一个解码库,提供接口方便用户直接调用,提高开发的效率。其主要特点如下:


    条码种类: 支持常用QR-Code、EAN、UPC


    扫描速度: 400 毫秒


    扫描英文: 250 个字符


    扫描中文: 90中文字符,UTF-8编码格式(需上位机支持)


    多码扫描: 支持多个二维码同时解码,同时输出结果


47.5.2 软件设计

1.    编程要点

根据OV5640识别二维码的过程,软件设计可以根据以下几个模块分别进行:


(1)    图像采集,通过STM32F429的DCMI接口驱动OV5640,采集适合液晶屏分辨率的图像。OV5640支持自动对焦功能,因此很容易采集到高清度的图像。


(2)    液晶驱动,通过STM32F429的LTDC接口驱动液晶屏,使用外部SDRAM作为液晶屏的显存,通过DMA2D来刷屏;同时LTDC支持双层叠加显示,可以在液晶屏上实现半透明的扫描窗并且支持绘制扫描线的动画效果。


(3)    图像处理,使用外部SDRAM作为缓存为图像处理提供足够的空间,通过调用QR-Code解码库的get_image函数获取一帧图像。通过图像处理将图像的数据流转变为一个二进制的码流再进行数据解码。


(4)    数据解码,直接通过QR_decoder函数来解码。返回值为解码的条码个数。并将解码结果保存到decoded_buf的二维数组当中。


(5)    串口发送,根据解码结果的个数及decoded_buf二维数组的数据,通过串口发送到电脑上位机。


2.    代码分析

QR-Code解码库相关宏定义

我们把QR-Code解码库相关的配置都以宏的形式定义到"qr_decoder_user.h"文件中,其中包括数据缓冲基地址、扫描窗大小、扫描框线条大小、解码结果二维数组、扫描二维码的函数,见代码清单 242。


代码清单 471 QR-Code解码库配置相关的宏


 1 #ifndef  __QR_DECODER_USER_H

2 #define __QR_DECODER_USER_H


3


4 #include "qr_decoder.h"


5 #include


6


7 // 开辟SDRAM的3M字节作为数据缓存,这里使用显存以外的空间,


8 // 0xD0800000-0x300000 = 0xD0500000


9 #define QR_FRAME_BUFFER ((uint32_t)0xD0500000)


10


11 /*扫描窗口参数*/


12 #define Frame_width ((uint16_t)320)//扫描窗口边长(正方形)


13


14 /*扫描框线条参数*/


15 #define Frame_line_length ((uint16_t)30) //扫描框线条长度


16 #define Frame_line_size ((uint16_t)3) //扫描框线条宽度


17


18 #define QR_SYMBOL_NUM 5 //识别二维码的最大个数


19 #define QR_SYMBOL_SIZE 512 //每组二维码的的最大容量


20


21 //解码数据封装为二维数组decoded_buf,格式为:


22 // (第一组:解码类型长度(8bit)+解码类型名称+解码数据长度(16bit,高位在前低位在后)+ 解码数据)


23                     


24 // (第二组:解码类型长度(8bit)+解码类型名称+解码数据长度(16bit,高位在前低位在后)+ 解码数据)


25                 


26 // 。。。


27 //以此类推


28 extern char decoded_buf[QR_SYMBOL_NUM][QR_SYMBOL_SIZE];


29


30 //解码函数,返回值为识别条码的个数


31 char QR_decoder(void);


32


33 //获取一帧图像


34 void get_image(uint32_t src_addr,uint16_t img_width,uint16_t img_height);


35


36 #endif /* __QR_DECODER_USER_H */


    以上代码首先定义一个3M字节的空间用作解码库的数据的缓冲,只需要定义SDRAM的空闲空间的基地址;然后定义扫描二维码的窗口及框体大小,范围由100~480(图像不能太小,否则图像很难识别);定义decoded_buf[QR_SYMBOL_NUM][QR_SYMBOL_SIZE]二维数组存放解码的结果,存放解码的最大个数由QR_SYMBOL_NUM决定,存放解码的最大数据量由QR_SYMBOL_SIZE决定,没有特殊要求就不需要做变动;存放数据的格式介绍如下表 473。


表 473 二维数组数据格式

image.png

image.png

    QR_decoder为解码函数,用户可以直接调用这个函数,返回值为解码成功的个数。get_image函数为获取图片的函数,通过指定存放图片的首地址,图片的分辨率来获取图片。


图像采集

我们需要通过OV5640摄像头采集的图像数据传递到解码库解码,在帧中断提取一帧图片用来解码,见代码清单 243。


代码清单 472 DCMI的中断响应函数(stm32f4xx.it)


1 //使用帧中断重置line_num,可防止有时掉数据的时候DMA传送行数出现偏移


2 void DCMI_IRQHandler(void)


3 {


4 /*判断帧中断标志位是否被置位*/


5 if ( DCMI_GetITStatus (DCMI_IT_FRAME) == SET ) {


6 /*传输完一帧,计数复位*/


7 line_num=0;


8 /*停止采集*/


9 DCMI_CaptureCmd(DISABLE);


10 /*获取一帧图片,FSMC_LCD_ADDRESS为存放图片的首地址*/


11 /*LCD_PIXEL_WIDTH为图片宽度,LCD_PIXEL_HEIGHT为图片高度*/


12 get_image(FSMC_LCD_ADDRESS,LCD_PIXEL_WIDTH,LCD_PIXEL_HEIGHT);


13 /*绘制扫描窗口里边的扫描线,放在这里主要是避免屏幕闪烁*/


14 LCD_Line_Scan_ARGB8888();


15 /*重新开始采集*/


16 DCMI_CaptureCmd(ENABLE);


17 /*清除帧中断标志位*/


18 DCMI_ClearITPendingBit(DCMI_IT_FRAME);


19 }


20


21 }


在DCMI中断函数中增加获取图片函数,先停止摄像头的采集,然后通过get_image 函数获取一帧图片,这个函数传递的第一个参数FSMC_LCD_ADDRESS是图片存放的首地址,第二个参数LCD_PIXEL_WIDTH为图片宽度,第三个参数是LCD_PIXEL_HEIGHT为图片高度,图片通过这个函数传递给解码函数进行解码,主函数将介绍如何调用解码函数。


通过LCD_Line_Scan_ARGB8888函数来绘制扫描线,绘制完后再启动摄像头的采集。LCD_Line_Scan_ARGB8888函数放在这个位置解决了当同时操作液晶的前景层和背景层时闪烁的问题。


液晶驱动

F429的LTDC支持双层叠加显示功能,具体可以参考我们LTDC部分章节的详细介绍。现在主要介绍如何绘制扫描窗口。我们定义背景层为显示摄像头图像层,前景层为扫描框显示层,代码清单 455。


代码清单 473 配置DMA数据传输(bsp_ov5640.c文件)


1 /*扫描窗口参数*/


2 #define Frame_width ((uint16_t)320)//扫描窗口边长(正方形)


3


4 /*扫描框线条参数*/


5 #define Frame_line_length ((uint16_t)30) //扫描框线条长度


6 #define Frame_line_size ((uint16_t)3) //扫描框线条宽度


7


8 //指定扫描窗口里边扫描线的初始位置


9 int pos=(LCD_PIXEL_HEIGHT-Frame_width)/2+5*Frame_line_size;


10 /**


11 * @brief 清屏


12 * @param Color: 清屏颜色


13 * @retval None


14 */


15 void LCD_Clear_ARGB8888(uint32_t Color)


16 {


17 DMA2D_InitTypeDef DMA2D_InitStruct;


18


19 uint16_t Alpha_Value=0,Red_Value = 0, Green_Value = 0, Blue_Value = 0;


20


21 Alpha_Value = (0xFF000000&Color)>>24;


22 Red_Value = (0x00FF0000 & Color) >> 16;


23 Blue_Value = 0x000000FF & Color;


24 Green_Value = (0x0000FF00 & Color) >> 8;


25


26 /* configure DMA2D */


27 DMA2D_DeInit();


28 DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;


29 DMA2D_InitStruct.DMA2D_CMode = DMA2D_ARGB8888;


30 DMA2D_InitStruct.DMA2D_OutputGreen = Green_Value;


31 DMA2D_InitStruct.DMA2D_OutputBlue = Blue_Value;


32 DMA2D_InitStruct.DMA2D_OutputRed = Red_Value;


33 DMA2D_InitStruct.DMA2D_OutputAlpha = Alpha_Value; //设置透明度


34 DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CurrentFrameBuffer;


35 DMA2D_InitStruct.DMA2D_OutputOffset = 0;


36 DMA2D_InitStruct.DMA2D_NumberOfLine = LCD_PIXEL_HEIGHT;


37 DMA2D_InitStruct.DMA2D_PixelPerLine = LCD_PIXEL_WIDTH;


38 DMA2D_Init(&DMA2D_InitStruct);


39


40 /* Start Transfer */


41 DMA2D_StartTransfer();


42


43 /* Wait for CTC Flag activation */


44 while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET) {


45 }


46 }


47 /**


48 * @brief 绘制一条线条


49 * @param Xpos: 起点X轴坐标,范围0 到800


50 * @param Ypos: 起点Y轴坐标,范围0 到480


51 * @param Length: 线条长度


52 * @param Line_width: 线条宽度


53 * @param Direction: 线条方向(水平或者垂直).


54 * @retval None


55 */


56 void LCD_DrawLine_ARGB8888(


57 uint16_t Xpos,


58 uint16_t Ypos,

[1] [2] [3]
关键字:QR-Decoder  OV5640  二维码识别  STM32-F429系列 引用地址:第47章 QR-Decoder-OV5640二维码识别—零死角玩转STM32-F429系列

上一篇:第44章 MPU6050传感器—姿态检测—零死角玩转STM32-F429系列
下一篇:第48章 MDK的编译过程及文件类型全解—零死角玩转STM32-F429

推荐阅读

  美国试图以进为退来换取更多讹诈利益,中国则坚守底线以退为进不给美国任何讹诈获利机会。   今(9月18日),有媒体报道,特朗普称这些关税将于9月24日以10%开始,并将在2019年1月1日增加至25%。在与记者的电话会议中,高级政府官员指出,延迟是为了让依赖这些进口的公司转移供应链的时间。   但截至记者发稿,中国并未作出回应。   上周四...
01、全球能源数字化技术发展态势 当前,新一轮科技革命和产业革命加速兴起,“大云物智移链”等数字化技术与能源产业有机相融,成为引领能源产业变革、实现创新驱动发展的源动力。目前,世界各国纷纷采取措施,推动数字化进程,将大数据分析及机器学习、区块链、分布式能源管理和云计算等数字技术,应用到能源生产、输送、交易、消费及监管等各个环节。...
据外媒报道,巴拉德动力公司(Ballard Power Systems)推出FCgen-HPS燃料电池组。这款高性能、零排放的质子交换膜(PEM)燃料电池组,可为一系列轻型、中型和重型汽车提供动力,体积功率密度高达4.3 kW/L。Ballard公司巴拉德公司与奥迪合作的技术解决方案项目按照严格的汽车标准,开发设计FCgen-HPS电池组。目前巴拉德公司拥有在各领域应用FCgen-HPS电...

史海拾趣

问答坊 | AI 解惑

xilinx FPGA的最小系统怎么画???

哪位好心人帮忙一下,FPGA(xc3s400)的最小系统由那些组成?谢谢了…

查看全部问答∨

2010年新兴视频监控技术指南(序列三)

基于IP的存储(SAN)潜在优势     在部署传统视频监控系统时会把视频管理软件和硬件驱动器合成到一个统一的设备(通常是DVR)中,而在比较大型的系统中,这种方式有可能会造成上百个硬盘驱动器分布在几十个DVR中。这样可能会造成多种不 ...…

查看全部问答∨

ucos-ii的OSQPost和OSQPend的怪问题

硬件arm7 GPG2接AD复位,使AD复位就是使其中一个任务接收AD转换后的数据并进行一些计算。软件中使该脚复位后,有计算的数据显示但另一个任务控制的按键不起作用了(此时按按键会有乱数据显示)。两者不能同时运行。软件中不给AD复位则按键起作用, ...…

查看全部问答∨

关于IDE驱动的问题

我编译好的NK.bin在pc上成功运行但是IDE口的硬盘和CF卡都驱动不起。 PC:康拓APCI5096 硬件:芯片组 Intel 855 GME内建 软件:WINCE 5.0(PB为微软120天的免费版), 谁有855的主板的IDE驱动。…

查看全部问答∨

我开发一个ocx 如何把她注册到pda上面,用程序如何才能实现?

我开发一个ocx 如何把她注册到pda上面,用程序如何才能实现?需要那些资源?…

查看全部问答∨

请好心人帮助解决通信协议的定制及数据的提取,急等

最近在学习单片机与PC的串行通信, 我的第一个问题是,如果单片机下位机端要发送20个参数数据给上位机PC, 通信协议应该怎样定制呢?帧格式中数据部分有速度,高度等数据,这些数据如果用两个字节表示该怎样表示啊? 我的想法是 :0xaa 0x2d0x2f ...…

查看全部问答∨

关于Vxworks开发工具的问题

我从网站下载了几个开发工具: [VxWorks6.2.&.Workbench.2.4].VxWorks6.2_Arm.zip [VxWorks6.2.&.Workbench.2.4].Wind.River.GNU.Compiler.3.3.2.for.VxWorks.6.2.iso [VxWorks6.2.&.Workbench.2.4].Wind.River.Compiler.5.3.iso [VxWork ...…

查看全部问答∨

获取来电号码的问题

我在mobile 6 的模拟器上写了电话的测试程序,想要获取来电号码。 我的做法是在LINE_CALLINFO的LINECALLINFOSTATE_CALLERID消息下,调用lineGetCallInfo去获去LINECALLINFO,然后加上dwCallerIDOffset长度,在去拿号码。但每次dwCallerIDOffset, ...…

查看全部问答∨

求助:分享点示波器、电源、万用表等设备的选型经验吧

本帖最后由 ddllxxrr 于 2016-1-7 17:15 编辑 我们学校目前筹划明年开办电子信息学院,将增加一批新的实验室设备,主要添置的包括频率计、数字万用表、示波器和直流电源等,约50万的预算,下面是一个初拟的购买方案:      &n ...…

查看全部问答∨

好的设计必须在你的实验室中Fail过

推荐一篇博文,做设计的都适用,写得很切实际。https://home.eeworld.com.cn/my/space.php?uid=169593&do=blog&id=42094…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • ARM裸机篇--按键中断
    先看看GPOI的输入实验:按键电路图:GPF1管教的功能:EINT1要使用GPF1作为EINT1的功能时,只要将GPFCON的3:2位配置成10就可以了!GPF1先配 ...
  • 网上下的--ARM入门笔记
    简单的介绍打今天起菜鸟的ARM笔记算是开张了,也算给我的这些笔记找个存的地方。为什么要发布出来?也许是大家感兴趣的,其实这些笔记之所 ...
  • 学习ARM开发(23)
    三个任务准备与运行结果下来看看创建任务和任运的栈空间怎么样的,以及运行输出。Made in china by UCSDN(caijunsheng)Lichee 1 0 0 ...
  • 学习ARM开发(22)
    关闭中断与打开中断中断是一种高效的对话机制,但有时并不想程序运行的过程中中断运行,比如正在打印东西,但程序突然中断了,又让另外一个 ...
  • 学习ARM开发(21)
    先要声明任务指针,因为后面需要使用。 任务指针 volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • 学习ARM开发(20)
  • 学习ARM开发(19)
  • 学习ARM开发(14)
  • 学习ARM开发(15)
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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