深入理解AMetal,掌握蜂鸣器和温度采集接口设计

周立功单片机 2018-01-17 08:29 次阅读

周立功教授新书《面向AMetal框架与接口的编程(上)》,对AMetal框架进行了详细介绍,通过阅读这本书,你可以学到高度复用的软件设计原则和面向接口编程的开发思想,聚焦自己的“核心域”,改变自己的编程思维,实现企业和个人的共同进步。

第八章为深入理解AMetal,本文内容为8.3 蜂鸣器接口和8.4 温度采集接口。

8.3 蜂鸣器接口

>>> 8.3.1 定义接口

1. 接口命名

由于操作的对象是蜂鸣器(buzzer),因此,接口命名以“am_buzzer_”作为前缀。对于蜂鸣器,基本的操作是打开和关闭蜂鸣器,可定义相应的两个接口名为:

  • am_buzzer_on

  • am_buzzer_off

特别地,在一些应用场合,还需要类似蜂鸣器“嘀一声”这样的操作,即鸣叫一定的时间后自动停止。可以定义其接口名为:

  • am_buzzer_beep

  • am_buzzer_beep_async

这里定义了两个接口,都是用于蜂鸣器鸣叫指定的时间,二者的区别在于函数返回的时机不同。am_buzzer_beep 会等待鸣叫结束后返回,am_buzzer_beep_async 不会等待,函数立即返回,蜂鸣器鸣叫指定时间后自动停止。

显然,对于am_buzzer_beep_async 接口,在最开始的蜂鸣器接口设计中,很可能是不会想到的,该接口是在大量实际应用中得出的,由于在一些特殊的应用场景,不希望程序被阻塞,因此,需要提供am_buzzer_beep_async 这样的异步接口。

2. 接口参数

在LED 通用接口的设计中,由于在一个系统中,可能存在多个LED,这就必须使用某种方法区分不同的LED,如使用了唯一ID 号led_id 表示来区分系统中的多个LED。按照这种逻辑,是否也需要一个buzzer_id 来区分不同的蜂鸣器呢?

蜂鸣器的功能单一,是一种发声器件,在一个具体应用中,发声器件往往只有一个,没有必要使用多个蜂鸣器。因此,蜂鸣器可以看做系统的一个单实例设备,基于此,也就无需使用类似于buzzer_id 这样的参数来区分多个蜂鸣器了,对于打开和关闭蜂鸣器的接口,则无需任何参数,即:

  • am_buzzer_on(void);

  • am_buzzer_off(void);

特别地,对于am_buzzer_beep 和am_buzzer_beep_async 接口,虽无需参数来区分多个蜂鸣器,但由于其功能是鸣叫一定的时间,因此,还需要一个用于指定鸣叫时长的参数。

  • am_buzzer_beep(uint32_t ms);

  • am_buzzer_beep_async (uint32_t ms);

其中,ms 用于指定鸣叫时长,单位为毫秒。

3. 返回值

接口无特殊说明,直接将所有接口的返回值定义为int 类型的标准错误号。基于此,蜂鸣器控制接口的完整定义详见表8.5。

表8.5 蜂鸣器通用接口(am_buzzer.h)

其对应的类图详见图8.8。

图8.8 蜂鸣器接口类图

>>> 8.3.2 实现接口

1. 抽象的蜂鸣器设备类

蜂鸣器共计4 个通用接口,其中,am_buzzer_beep()和am_buzzer_beep_async()接口可以直接基于am_buzzer_on()和am_buzzer_off()接口实现,am_buzzer_beep()的实现详见程序清单8.24。

程序清单8.24 am_buzzer_beep()的实现

程序中,首先使用am_buzzer_on()打开蜂鸣器,若打开蜂鸣器失败(返回值为负数),则直接返回相应的错误号,若打开成功,则使用am_mdelay()延时指定的时间,最后关闭蜂鸣器。对于am_buzzer_beep_async()接口,其需要立即返回,不能在函数内部直接使用延时函数,可以基于软件定时器实现,范例程序详见程序清单8.25。

程序清单8.25 am_buzzer_beep_async()的范例程序

程序中,首先使用am_buzzer_on()打开蜂鸣器,若打开蜂鸣器失败(返回值为负数),则直接返回相应的错误号,若打开成功,则启动软件定时器,定时时间为指定的鸣叫时间,启动定时器后,函数立即返回。软件定时器定时时间到后,需要调用自定义回调函数__beep_timer_callback(),在回调函数中,关闭了软件定时器和蜂鸣器,鸣叫结束。

显然,软件定时器在使用前,需要初始化,以将__beep_timer_callback()函数作为其定时时间到后的回调函数,如:

初始化语句放在哪里呢?这里仅仅展示了使用软件定时器实现am_buzzer_beep_async()函数的范例,后文再介绍初始化软件定时器的合适时机。

由于am_buzzer_beep()和am_buzzer_beep_async()接口可以直接基于am_buzzer_on()和am_buzzer_off()实现,因此实现蜂鸣器接口的核心是实现am_buzzer_on()和am_buzzer_off()接口,按照LED 或HC595 的设计方法,可以抽象对应的两个方法。即:

虽然按照这种设计方法是完全可行的,但是考虑到on 和off 是一组相互对称的接口,功能是同属一类的,具有很大的相似性,因此,可以仅抽象一个方法,使用一个布尔类型的参数区分操作是打开还是关闭,比如:

可见,定义抽象方法并不一定是原封不动的按照接口定义抽象方法,可以作适当的调整,只要基于抽象方法,能够实现通用接口即可。

虽然只有一个抽象方法,但是为了保证结构的统一,也为了方便后续扩展(如新增抽象方法等),往往还是将抽象方法放到一个虚函数表中。即:

类似地,将抽象方法和p_cookie 定义在一起,即为抽象的蜂鸣器设备。如:

在前面实现am_buzzer_beep_async()接口时,使用到了软件定时器,显然,软件定时器是用于实现一个蜂鸣器鸣叫功能的,是与蜂鸣器设备相关的,其不应定义为全局变量,取而代之的是,直接定义在抽象设备结构体中,即:

抽象设备中定义的抽象方法需要由具体的蜂鸣器设备来完成,am_buzzer_on()和am_buzzer_off()接口则可以直接基于抽象方法实现。

在定义蜂鸣器接口时,由于蜂鸣器是单实例设备(系统中只有一个),因此没有在接口中定义区分蜂鸣器对象的参数,如ID 号或者句柄参数等,那么,在实现接口时,如何找到相应的设备呢?由于在系统中只有一个蜂鸣器设备,因此,可以直接使用一个全局变量来指向蜂鸣器设备,am_buzzer_on()和am_buzzer_off()的实现详见程序清单8.26。

程序清单8.26 am_buzzer_on 和am_buzzer_off ()的范例程序

其中,__gp_buzzer_dev 是指向蜂鸣器设备的指针,初始没有任何有效的蜂鸣器设备,因此初始值为NULL。显然,要正常使用蜂鸣器,就必须使__gp_buzzer_dev 指向有效的蜂鸣器设备,这就需要由具体蜂鸣器设备实现pfn_buzzer_set 抽象方法。

为了完成__gp_buzzer_dev 的赋值,需要定义一个设备注册接口,用于向系统中注册一个有效蜂鸣器设备:

其中,为了方便向系统中添加一个蜂鸣器设备时,避免直接操作蜂鸣器设备的各个成员,将需要赋值的成员通过参数传递给接口函数。其实现详见程序清单8.27。

程序清单8.27 向系统中添加蜂鸣器设备

该程序首先判定参数的有效性,然后完成了抽象设备中抽象方法和p_cookie 赋值,接着给全局变量__gp_buzzer_dev 的赋值,使其指向有效的蜂鸣器设备,最后,初始化了抽象设备中的软件定时器,便于实现异步的蜂鸣器鸣叫接口,由此可见,软件定时器的初始化操作是在添加一个蜂鸣器设备时完成的。

显然,接下来,就需要基于抽象的蜂鸣器设备派生具体的蜂鸣器设备,在具体的蜂鸣器设备中,完成抽象方法pfn_buzzer_set 的实现,并使用am_buzzer_dev_register()接口向系统中添加一个蜂鸣器设备,使得用户可以使用蜂鸣器通用接口操作到具体有效的蜂鸣器。

为了便于查阅,如程序清单8.28 所示展示了蜂鸣器设备接口文件(am_buzzer_dev.h)的内容。其对应的类图详见图8.9。

程序清单8.28 am_buzzer_dev.h 文件内容

图8.9 抽象的蜂鸣器设备类

2. 具体的蜂鸣器设备类

以使用PWM 输出控制蜂鸣器发声为例,简述具体蜂鸣器设备的实现方法。首先应该基于抽象设备类派生一个具体的设备类,其类图详见图8.10,可直接定义具体的蜂鸣器设备类,如:

图8.10 具体的蜂鸣器设备类

am_buzzer_pwm_dev_t 即为具体的蜂鸣器设备类。具有该类型后,即可使用该类型定义一个具体的蜂鸣器设备实例,即:

特别地,由于蜂鸣器是单实例设备,不能够使用该类型定义多个实例,因此,可以直接在具体设备实现的文件内部定义一个蜂鸣器设备实例,无需用户使用该类型自定义设备实例。基于此,am_buzzer_pwm_dev_t 类型无需开放给用户,可以直接定义在.c 文件中,由于am_buzzer_pwm_dev_t 类型无需开放给用户,仅内部使用,因此可以修改类型名为双下划线“__”开头,如在am_buzzer_pwm.c 文件中定义设备类型以及对应的设备实例如下:

在使用PWM 输出控制蜂鸣器时,需要知道PWM 的句柄,通道号等相关信息,这些信息需要保存在设备中,因此更新设备类型的定义如下:

显然,这些成员需要初始化后才能使用,定义初始化函数的原型为:

其中,pwm_handle 为标准的PWM 服务句柄,chan 为PWM 通道号,duty_ns 和period_ns分别指定了输出PWM 波形的脉宽和周期,决定了蜂鸣器鸣叫的响度和频率,比如,AM824-Core 板载的蜂鸣器。

若使用SCT 输出PWM,由于PIO0_24 对应SCT 的通道1,因此初始话函数的调用形式如下:

程序中,使用了am_lpc82x_sct0_pwm_inst_init()函数获取到了PWM 句柄,使用了通道1,并设定输出PWM 的周期为400000ns,即 2.5KHz (1000000000 / 400000),脉宽恰好为周期的一半,即输出PWM 的占空比为50%。初始化函数的实现范例详见程序清单8.29。

程序清单8.29 初始化函数实现范例

该程序首先判定了参数的有效性,然后完成了设备实例中相关成员的赋值,接着调用了am_buzzer_dev_register()函数,将蜂鸣器设备添加到系统中,最后配置了PWM 输出通道的脉宽和周期。添加设备时,将p_funcs 赋值为&__g_buzzer_pwm_drv_funcs,p_cookie 赋值为具体设备的地址,即p_cookie 指向了设备自身。__g_buzzer_pwm_drv_funcs 中包含了抽象方法的具体实现,完整定义详见程序清单8.30。

程序清单8.30 抽象方法的实现

为了便于查阅,如程序清单8.31 所示展示了蜂鸣器设备接口文件(am_buzzer_pwm.h)的内容。

程序清单8.31 am_buzzer_pwm.h 文件内容

由此可见,与其它具体设备的接口文件(详见程序清单8.14、程序清单8.17 和程序清单8.23)相比,不同的是,其没有包含具体设备类型的定义,初始化接口的第一个参数,也不是指向具体设备的指针。这是由于蜂鸣器是单实例设备,系统中最多只能定义一个,因此直接在实现文件的内部完成了设备实例的定义,相关类型无需开放给用户。同理,由于是单实例设备,初始化函数初始化的必然是文件内部定义的设备实例,无需额外使用指向设备的指针指定要初始化的设备。

至此,详细介绍了LED 通用接口、HC595 接口和蜂鸣器接口,它们代表了AMetal 中典型的3 种类型的设备接口。

  • LED 通用接口:使用唯一ID 区分不同设备;

  • HC595 接口:使用句柄区分不同的设备,句柄本质上是指向设备的指针;

  • 蜂鸣器接口:不使用任何参数区分不同设备,是一种单实例设备。

8.4 温度采集接口

>>> 8.4.1 定义接口

1. 接口命名

由于操作的对象是温度(temperature),为了缩短接口名,将temperature 缩写为temp,因此,接口命名以“am_temp_”作为前缀。对于温度采集,主要的操作就是读取当前温度。可定义接口名为:

  • am_temp_read

2. 接口参数

显然,一个系统中可能存在多个温度传感器,可以简单的使用句柄来区分不同的温度传感器,因此第一个参数的类型定义为温度传感器句柄,和HC595 设备类似,其应该定义为指向抽象温度设备的指针,假定抽象温度设备的类型为am_temp_dev_t,则handle 的类型可以定义为:

读取温度接口的核心功能是返回当前的温度值,首先需要定义温度值的类型,然后再确定温度值的返回方式:通过返回值返回或通过出口参数返回。

通常使用1 位小数表示温度值,比如,37.5℃,由此可见,温度值需要使用小数表示,但要求的精度并不高,往往只会精确到小数点后一位,因此温度值可以使用float 类型表示。

由于AMetal 运行的实际硬件平台往往是以低端的Cortex-M0、Cortex-M0+和Cortex-M3等作为内核的芯片,这些芯片没有硬件浮点运算单元,浮点运算的效率很低。因此,AMetal平台中,不建议使用浮点类型,据此,可以使用整数表示温度值,同时,为了保证一定的精度,使用整数表示扩大1000 倍后的温度值。如实际温度为37.5 度,则使用整数37500 表示。使用这种方法巧妙的避免了使用浮点类型,但也能保证实际温度的精度为小数点后三位。由于温度可能存在负值,因此,使用有符号的32 位数据来表示温度值,即温度值的类型定义为int32_t。

在通用接口中,返回值往往定义为int 类型的错误号,且使用负数表示出错,显然,如果使用返回值直接返回温度,用户将无法区分温度为负数和读取温度出错的情况。为此,使用一个输出参数,用以返回温度值,即定义一个int32_t 类型的指针作为输出参数:

  • am_temp_read(am_temp_handle_t handle, int32_t *p_temp)

其中,handle 为温度传感器的句柄,p_temp 为输出参数,用于返回当前的温度值,其表示的温度值为实际温度值的1000 倍。

3. 返回值

接口无特殊说明,直接将所有接口的返回值定义为int 类型的标准错误号。基于此,完整的读取温度接口的原型为:

其对应的类图详见图8.11。

图8.11 温度采集接口

>>> 8.4.2 实现接口

1. 抽象的温度采集设备类

根据读取温度接口,可以定义相应的抽象方法,并将其存放在一个虚函数表中:

类似地,将抽象方法和p_cookie 定义在一起,即为抽象的温度采集设备。比如:

显然,具体的温度采集设备直接从抽象的温度采集设备派生,然后由具体的温度采集设备根据实际的硬件,实现读取温度的抽象方法。

在读取温度接口中,使用了handle 作为第一个参数,其本质上是指向设备的指针,读取温度接口可以直接调用抽象方法实现,详见程序清单8.32。

程序清单8.32 读取温度接口实现

在接口实现中,没有与硬件相关的实现代码,仅仅是简单的调用了抽象方法。抽象方法需要由具体的温度采集设备来实现。类似地,由于读取温度接口的实现非常简单,往往将其实现直接以内联函数的形式存放在.h 文件中。

为便于查阅,如程序清单8.33 所示展示了抽象温度采集设备接口文件(am_temp.h)的内容,其包含了抽象温度采集设备相关的抽象方法定义、类型定义和接口实现,对应的类图详见图8.12。

图8.12 抽象的温度采集设备类

程序清单8.33 am_temp.h 文件内容

2. 具体的温度采集设备类

以使用LM75B 温度传感器实现温度采集为例,简述具体温度采集设备的实现方法。首先应该基于抽象设备类派生一个具体的设备类,其类图详见图8.13,可直接定义具体的温度采集设备类。比如:

图8.13 具体的温度采集设备类

am_temp_lm75_t 为具体的温度采集设备类,具有该类型后,即可使用该类型定义一个具体的温度采集设备实例:

LM75B 是标准的I2C 从机器件,需要知道LM75B 的从机地址,才能使用I2C 总线读取LM75B 中的温度数据。由于从机地址与LM75 外部引脚电平相关,因此LM75 的地址信息需要由用户根据实际硬件电路设置。将需要由用户提供的设备相关信息存放到一个新的设备信息结构体类型中。比如:

当使用AM824-Core 上板载的LM75B 时,LM75B 的7 位I2C 从机地址为1001A2A1A0,由于A0、A1、A2 均与地连接为低电平,因此可得板载LM75B 的7 位从机地址为1001000,即:0x48。基于此,板载LM75B 对应的设备实例信息可以定义如下:

同理,在设备类中需要维持一个指向设备信息的指针。此外,由于使用I2C 接口从LM75B中读取温度数据时,LM75B 相当于是一个I2C 从设备,为了使用I2C 接口与之通信,需要为LM75B 定义一个与之对应的I2C 从设备,新增两个成员,完整的温度采集设备定义即为:

显然,在使用I2C 接口从LM75B 中读取温度之前,需要完成设备中各成员的赋值,这些工作通常在驱动的初始化函数中完成,定义初始化函数的原型为:

  • p_lm75 为指向am_temp_lm75_t 类型实例的指针;

  • p_devinfo 为指向am_temp_lm75_info_t 类型实例信息的指针。

handle 为I2C 句柄,便于使用I2C 接口读取温度数据,初始化函数的返回值即为温度采集设备句柄,其调用形式如下:

返回值即为温度采集设备的句柄,可以作为温度采集接口的第一个参数(handle)的实参,初始化函数的实现范例详见程序清单8.34。

程序清单8.34 初始化函数实现范例

该程序首先建立了标准的I2C 从设备,便于后续使用I2C 接口读取数据,然后初始化了p_info 成员,接着完成了抽象温度采集设备中p_funcs 和p_cookie 的赋值,最后返回设备地址作为用户操作温度采集设备的句柄。pfuncs 赋值为了&__g_temp_lm75_drv_funcs,其中包含了读取温度抽象方法的具体实现,完整定义详见程序清单8.35。

程序清单8.35 抽象方法的实现

在读取温度的实现函数__temp_lm75_read()中,首先使用I2C 接口从LM75B 中读取出当前的实际温度值,详见程序清单8.35(6);接着对数据进行简单处理,两字节数据整合为一个16 位有符号的温度值temp,详见程序清单8.35(10 ~ 11);最后,确认p_temp 指针有效后,将temp 乘以125,再除以32,最终的结果作为输出的温度值。

为什么将temp 乘以125,然后再除以32 呢?这是因为LM75B 中直接读取的数据时实际温度值的256倍,即:实际温度= temp / 256。

而温度采集接口需要返回的温度值是实际温度的1000 倍,即:

* p _ temp=实际温度*1000 = temp/ 256*1000 = temp*1000/ 256

化简可得:

为了便于查阅,如程序清单8.36 所示展示了具体温度采集设备(LM75B)接口文件(am_temp_lm75.h)的内容。

程序清单8.36 am_temp_lm75.h 文件内容

周立功单片机 技术专区

原文标题:周立功:深入理解AMetal——蜂鸣器接口和温度采集接口

文章出处:【微信号:Zlgmcu7890,微信公众号:周立功单片机】欢迎添加关注!文章转载请注明出处。

关注电子发烧友微信

有趣有料的资讯及技术干货

下载发烧友APP

打造属于您的人脉电子圈

关注发烧友课堂

锁定最新课程活动及技术直播
收藏 人收藏
分享:

评论

相关推荐

组建RS-485总线网络时,终端电阻实战案例

RS-485总线具有结构简单、成本低等优点,但各位工程师在组建RS-485总线网络时,为提升整个网络....

的头像 周立功单片机 发表于 02-08 09:51 次阅读 0条评论
组建RS-485总线网络时,终端电阻实战案例

分析电能质量分析仪一个案例中的测试效果

小到家庭,大到企业,能耗问题一直以来都是大家所关注重视的问题。中国企业的能耗一直很高,国家也努力促使....

的头像 ZLG致远电子 发表于 02-08 09:44 次阅读 0条评论
分析电能质量分析仪一个案例中的测试效果

ZLG致远电子E6000率先支持新国标 电压暂降和短时中断的定义

国家标准2013年第25号批准发布公告,由国网福建电科院负责编制的国家标准《电能质量电压暂降与短时中....

的头像 电子发烧友网工程师 发表于 02-05 11:11 次阅读 0条评论
ZLG致远电子E6000率先支持新国标 电压暂降和短时中断的定义

电子产品性能提升中,如何防止“安全”掉链子

最火手游“王者荣耀”将玩家分成“青铜、白银、黄金...”等段位。笔者从青铜开始打到最强王者。是不是电....

的头像 ZLG致远电子 发表于 02-05 09:44 次阅读 0条评论
电子产品性能提升中,如何防止“安全”掉链子

互联网温控器芯片应用及整体方案

LG致远电子基于NXP的KL16、Semtech的SX1278芯片开发的低功耗、高性能的LoraNe....

的头像 周立功单片机 发表于 02-05 09:19 次阅读 0条评论
互联网温控器芯片应用及整体方案

电压波动与电压闪变对比分析

电压闪变与波动,两个形影不离的兄弟,经常一起出现在我们的视野中。闪变外向,我们可以从外表觉察到它的变....

的头像 电子发烧友网工程师 发表于 02-16 09:40 次阅读 0条评论
电压波动与电压闪变对比分析

如何确保对吸尘器的心脏进行可靠“体检”

人类正是由于心脏不断地跳动才得以生存;吸尘器也是一样,只有心脏安好,才能更好的吸尘。人类为了确保身....

的头像 电子发烧友网工程师 发表于 02-15 03:33 次阅读 0条评论
如何确保对吸尘器的心脏进行可靠“体检”

如何解决照明灯具的测试测量痛点

家用照明灯具在出厂时,都是需要经过测量装备严格的检测,当照明灯在正常工作或特定模式下时,电压、电流和....

的头像 电子发烧友网工程师 发表于 02-15 03:28 次阅读 0条评论
如何解决照明灯具的测试测量痛点

一款优质电源必然具备:启动性设计

一款优质电源必然具备启动性能好、转换效率高等特点,但你有没有想过宽压电源的输入电压范围那么广,而电源....

的头像 ZLG致远电子 发表于 02-02 09:33 次阅读 0条评论
一款优质电源必然具备:启动性设计

几种驱动蜂鸣器的编程示例

介绍几种在S3F9454/9444下驱动蜂鸣器的编程示例,供参考 A.第一种,普通IO高低电平驱动法....

的头像 算法&编程学院 发表于 01-30 18:27 次阅读 0条评论
几种驱动蜂鸣器的编程示例

如何制作柜子开合报警装置 防盗更安全

防盗报警系统就是利用物理方法或电子技术,自动探测监测区域内是否有侵入行为,便自动产生报警信号。如何在....

的头像 人间烟火123 发表于 01-30 08:32 次阅读 0条评论
如何制作柜子开合报警装置 防盗更安全

基于vhdl蜂鸣器程序设计详解

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。蜂鸣器在电路中用字母“H”或“HA”(旧标准用“F....

发表于 01-29 15:08 次阅读 0条评论
基于vhdl蜂鸣器程序设计详解

计数报警器电路设计方案汇总(多款模拟电路设计原理图详解)

本文主要介绍了计数报警器电路设计方案汇总(多款模拟电路设计原理图详解),方案二主要由直流电源电路(整....

发表于 01-29 10:30 次阅读 0条评论
计数报警器电路设计方案汇总(多款模拟电路设计原理图详解)

蜂鸣器报警器电路图大全(五款模拟电路设计原理图详解)

本文主要介绍了蜂鸣器报警器电路图大全(五款模拟电路设计原理图详解)。方案二电路是通过运算放大器进行驱....

发表于 01-29 09:36 次阅读 0条评论
蜂鸣器报警器电路图大全(五款模拟电路设计原理图详解)

为什么你的手机实际内存比标称内存要少很多

现在市面上存在NAND FLASH和eMMC这两种的大容量存储介质,就是各类移动终端及手机的主要存储....

发表于 01-29 07:40 次阅读 0条评论
为什么你的手机实际内存比标称内存要少很多

如何使用RTC实时时钟进行应用场景开发

虽然该程序的逻辑与程序清单6.70 所示的应用程序基本一致,但由于使用的接口是特殊功能控制接口,与具....

的头像 周立功单片机 发表于 01-25 09:15 次阅读 0条评论
如何使用RTC实时时钟进行应用场景开发

13.56MHz读写卡模块通信接口及选型指南

论选择I2C 或UART 通信方式,只要基于实例句柄编程,则应用程序与具体的通信方式无关。

的头像 周立功单片机 发表于 01-25 09:09 次阅读 0条评论
13.56MHz读写卡模块通信接口及选型指南

键盘与数码管接口典型应用电路及寄存器

当矩阵扩大到一定数目时,逐行扫描的方法会显得费时,如果需要对2 个以上的按键“同时”操作时,则处理起....

的头像 周立功单片机 发表于 01-22 09:27 次阅读 0条评论
键盘与数码管接口典型应用电路及寄存器

如何理解软件设计原则和面向接口编程的开发思想

面向通用接口的编程,虽然面向接口的编程简单易懂,但无法做到最大程度上地重用应用程序,这是导致软件开发....

的头像 周立功单片机 发表于 01-22 09:11 次阅读 0条评论
如何理解软件设计原则和面向接口编程的开发思想