学会阅读硬件的原理图、数据手册大全

参考: 郭天祥:https://www.bilibili.com/video/BV1DW411a7mz?p=8
韦东山:https://www.bilibili.com/video/BV1ga4y1Y7PL?p=4
https://www.bilibili.com/video/BV17g411F7oR?spm_id_from=333.999.0.0
洋桃电子:https://www.bilibili.com/video/BV1eW411J7cf?p=2&spm_id_from=pageDriver

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入--------------》跳转接口
在这里插入图片描述

更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入--------------》跳转接口
在这里插入图片描述

目录

  • 硬件接口的四大类
      • 1. GPIO和门电路
      • 2. 协议类
      • 3. 类似内存的接口(ram-like)
      • 4. 模拟电路
  • GPIO与门电路
      • 1. GPIO的应用
      • 2. GPIO引脚操作
        • 2.1 设置引脚为GPIO功能
        • 2.2 设置引脚方向
        • 2.3 设置/读取引脚数值
      • 3. 二极管
      • 4. 三极管
        • 4.1 NPN三极管
        • 4.2 PNP三极管
  • LED电路与操作
      • 1. LED实物
      • 2. LED电路
  • 同步与异步
      • 1. 概念
        • 1.1 同步信号示例
        • 1.2 异步信号示例
      • 2. 差别
  • 使用一线传输双向数据
      • 1. 面临的问题
      • 2. 解决方法
      • 3. 双向传输示例
  • 如何高效阅读英文数据手册?
  • 类似内存的接口(2440开发板为例)
    • SDRAM
    • NOR FLASH
    • 网卡
    • 不同位宽外设的接线
    • 时序的阅读及内存控制器的设置
  • 1602液晶驱动显示
    • 阅读手册
    • LCD1602.h
    • LCD1602.c
  • IIC总线AT24C02芯片实验(E2PROM)
    • IIC总线协议
    • 24C02芯片手册阅读
    • 编写代码

硬件接口的四大类

参考书籍:

  • 《微机原理》:侧重于计算机结构
  • 《数字电子技术基础 》:侧重于门电路

1. GPIO和门电路

GPIO:general peripheral input/ouput,通用的外设输入、输出接口。

这类电路通常只使用一个引脚

  • 可以设置为输出
    • 可以输出高、低电平
    • 比如用来控制LED
  • 也可以设置为输入
    • 可以读取引脚电平,判断当前是高电平还是低电平
    • 比如用来判断按键是否被按下
  • 可以接上各类晶体管(二极管、三极管等)实现逻辑运算

门电路:与门、或门、非门

在这里插入图片描述

2. 协议类

比如:UART、I2C、SPI、Nand、TFT LCD。

如果两个设备之间要传输的数据比较复杂,可以约定一些规则。这类接口被称为"协议类"接口。

当然可以只使用一条GPIO引脚来传输复杂的数据,比如红外遥控器、温度传感器等。也可使用多条线路来传输数据,比如UART、I2C、SPI等。比如TFT LCD的接口线将近30条。

例子:

  • I2C接口

    • 硬件连接

在这里插入图片描述

  • I2C协议
    在这里插入图片描述

3. 类似内存的接口(ram-like)

比如:Nor Flash、SDRAM、DDR、网卡DM9000等。

  • 内存:可以读写某个地址上的数据,所以必定有这些信号
    • 地址总线
    • 数据总线
    • 读/写信号
    • 片选(cs):ram-like接口上可以接多个设备,互相之间不能干扰,选中哪个设备哪个设备才能响应
  • 很多设备也采用类似内存的接口,比如Nor Flash、8080接口的LCD
  • 例子
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3bzfE8tX-1635065935595)(pic/01_预备知识与概述/11_ram_like_interface.png)]

在这里插入图片描述

4. 模拟电路

数字电路上传输的电压值只有2类取值,比如

  • 2.xV到3.3V,抽象为逻辑值1
  • 0V到1.xV,抽象为逻辑值0

模拟电路上传输的电压可以是各种各样的,比如以下两个电路:

  • ADC电路中:可以读取滑动电阻器上的触点电压值
  • DAC电路中:可以输出不同的电压值,用来控制LED的亮度(数字电路里LED只有亮、灭两个状态)

读取滑动电阻器上的触点电压值

  • DAC电路中:可以输出不同的电压值,用来控制LED的亮度(数字电路里LED只有亮、灭两个状态)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-goaiHJno-1635065935597)(pic/01_预备知识与概述/13_analog_circuit.png)]

GPIO与门电路

1. GPIO的应用

GPIO可以设置为输出、输入:

  • 输出功能

    • LED

    • 发射红外信号

    • 控制电机

    • 蜂鸣器

    • 数码管

  • 输入功能

    • 按键
    • 接收红外信号
    • 人体感应
  • 实现各类协议

    • 读取温湿度传感器数据
    • 其实UART等也是使用GPIO来实现的

2. GPIO引脚操作

怎么用一个GPIO来控制LED?换句话说,怎么让一个GPIO输出高、低电平?

2.1 设置引脚为GPIO功能

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-26Zt0s4j-1635134136129)(pic/02_GPIO类电路/09_gpio_block.png)]

芯片内部有很多模块,比如GPIO、UART(串口)。
一个引脚,可以接到模块A,也可以接到模块B,比如上图中的引脚gpio0_0,可以接到GPIO group 0,也可以接到UART。
可以设置某些寄存器(比如io_mux),选择引脚的功能。

2.2 设置引脚方向

假设一个引脚被设置成了GPIO功能,那么它是用作输出,还是输入?
在GPIO模块内部,一般都有一个方向选择寄存器,里面每一位用来控制一个引脚的方向。
比如GPIO group 0中有一个gpio0_dir_reg寄存器,

  • 它的bit 0写入1,表示gpio0_0被设置为输出
  • 它的bit 0写入0,表示gpio0_0被设置为输入

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dy5iEZfH-1635134136133)(pic/02_GPIO类电路/10_gpio_dir_reg.png)]

2.3 设置/读取引脚数值

一个GPIO引脚被设置成输出,那么怎样设置它的输出电平?
一个GPIO引脚被设置成输入,那么怎样读取它的输入电平?
在GPIO模块内部,一般都有一个数据寄存器,里面每一位用来控制一个引脚的输出电平。
比如GPIO group 0中有一个gpio0_data_reg寄存器,

  • 写数据
    • 它的bit 0写入1,表示gpio0_0输出高电平
    • 它的bit 0写入0,表示gpio0_0输出低电平
  • 读数据
    • 如果bit 0等于1,表示gpio0_0为高电平
    • 如果bit 0等于0,表示gpio0_0为低 电平

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PtiplIM7-1635134136136)(pic/02_GPIO类电路/11_gpio_data_reg.png)]

3. 二极管

参考资料:图文详解二极管原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jkbgqSTd-1635134136140)(pic/02_GPIO类电路/03_diode.png)]

  • 二极管的箭头表示正向电流的方向

  • 二极管的电流具有单向性

  • 假设正极、负极之间的电压为V

    • 当V大于某个阈值(比如0.7V),二极管就导通,导通时电阻约等于0
    • 当V<0,二极管不会导通,电阻无穷大
  • 内部结构:由PN节组成,P代表正极(positive),N代表负极(negative)

  • 二极管中流动的是电子,电流方向是从正极到负极,电子流动的方向是从负极到正极

  • 使用二极管

    • 比如:使用二极管防止电源接反是烧坏电路

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wGpizgy5-1635134136144)(pic/02_GPIO类电路/07_use_diode.png)]

4. 三极管

参考资料:三极管工作原理分析精辟透彻看后你就懂

可以使用二极管的特性制作成三极管,组成开关电路。

三极管实物图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hg5lvGIL-1635134136146)(pic/02_GPIO类电路/24_triode_pic.png)]

三极管可以分为:NPN三极管、PNP三极管。

4.1 NPN三极管

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYNGN87I-1635134136148)(pic/02_GPIO类电路/05_triode_internal.png)]

  • 扩散
    • 物质会从浓度大的地方扩散到浓度低的地方
    • 比如墨水滴入水中,墨水会四处散开
    • 比如臭味会四处散开
    • 电子也会有扩散作用
  • 三极管原理
    • 当be之间的PN节加上正向电压,电子从e极的’N’大量往‘P’移动(所以e被称为发射极)
    • 电子在’P’大量聚集,一部分通过b极流走,另一部分通过c极扩散出去(c起收集作用,所以被称为集电极)
      • 电子流动方向如图中红色箭头所示
      • 电流方向与电子流动方向相反:be之间电流从b到e,ce之间电流从c到e
  • 三极管的使用
    • 当Vcon等于0.7V左右,be之间的PN节打通,c极相当于直接连接e,V2=0
    • 当Vcon等于0V,be之间的PN节没打通,c极相当于断开,V2=V
    • 所以,可以用Vcon来控制V2

4.2 PNP三极管

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JnOmnIJE-1635134136149)(pic/02_GPIO类电路/06_pnp_triode_internal.png)]

  • 扩散
    • 物质会从浓度大的地方扩散到浓度低的地方
    • 比如墨水滴入水中,墨水会四处散开
    • 比如臭味会四处散开
    • 电子也会有扩散作用
  • 三极管原理
    • 当eb之间的PN节加上正向电压,空穴从e极的’N’大量往‘P’移动(所以e被称为发射极)
    • 空穴在’P’大量聚集,一部分通过b极流走,另一部分通过c极扩散出去(c起收集作用,所以被称为集电极)
      • 空穴流动方向如图中红色箭头所示
      • 电流方向与空穴流动方向相同:eb之间电流从e到b,ec之间电流从e到c
  • 三极管的使用
    • 当Vcon为高电压(比如3.3V),eb之间的PN节打通,c极相当于直接连接e,V2=Vcon
    • 当Vcon等于0V,eb之间的PN节没打通,c极相当于断开,V2=0
    • 所以,可以用Vcon来控制V2

流从e到b,ec之间电流从e到c

  • 三极管的使用
    • 当Vcon为高电压(比如3.3V),eb之间的PN节打通,c极相当于直接连接e,V2=Vcon
    • 当Vcon等于0V,eb之间的PN节没打通,c极相当于断开,V2=0
    • 所以,可以用Vcon来控制V2

LED电路与操作

1. LED实物

在这里插入图片描述

2. LED电路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fR1dbIaz-1635134906237)(pic/02_GPIO类电路/08_led_sch.png)]

  • 方式1
    • 芯片引脚输出高电平,LED被点亮
    • 芯片引脚输出低电平,LED被熄灭
    • 缺点:芯片引脚的驱动能力可能不够,LED亮度低
  • 方式2
    • 芯片引脚输出低电平,LED被点亮
    • 芯片引脚输出高电平,LED被熄灭
    • 缺点:电流进入芯片过大时,可能烧毁芯片
  • 方式3
    • 芯片引脚输出高电平,三极管导通,LED被点亮
    • 芯片引脚输出低电平,三极管不导通,LED被熄灭
  • 方式4
    • 芯片引脚输出低电平,第一个三极管不导通,第二个三极管导通,LED被点亮
    • 芯片引脚输出高电平,第一个三极管导通,第二个三极管不导通,LED被熄灭

三极管导通,第二个三极管不导通,LED被熄灭

同步与异步

1. 概念

同步(synchronous)、异步(asynchronous),使用生活例子来说就是:

  • 同步:朋友打电话说到我家吃饭,我在家里等他们
  • 异步:朋友没有提前打招呼,突然就到我家来了

1.1 同步信号示例

在电子产品中,使用同步信号进行传输时,一般涉及两个信号:

  • 时钟信号:用来通知对方要读取数据了
  • 数据信号:用来传输数据

比如:

  • 时钟信号:打电话,起约定作用
  • 数据信号:传输数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbgF7UEC-1635135693064)(pic/03_one_wire/01_syn_signal.png)]

1.2 异步信号示例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GGSoiPTK-1635135693077)(pic/03_one_wire/02_asyn_signal.png)]

使用异步信号传输数据时,双方遵守相同的约定:

  • 起始信号:发送方可以通知接收方"注意了,我要开始传输数据了"

  • 数据的表示

    • 怎么表示逻辑1
    • 怎么表示逻辑0

以红外遥控器解码器为例,它向单片机发出的数据格式如下:

  • 起始信号:解码器发出一个9ms的低电平、4.5ms的高电平,用来同时对方说"开始了"
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-febDEXtg-1635135693080)(pic/03_one_wire/03_dht11_start.png)]

  • 表示一位数据

    • 逻辑1:0.56ms的低电平+1.69ms的高电平
    • 逻辑0:0.56ms的低电平+0.56ms的高电平

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Px4crktm-1635135693085)(pic/03_one_wire/04_dht11_bit_data.png)]

  • 接收方、发送方都遵守这样的约定,就可以使用一条线传输数据

2. 差别

同步传输异步传输
信号线多:时钟信号、数据信号少:只需要数据信号
速率可变,提高时钟信号频率即可双方提前约定
抗干扰能力

使用一线传输双向数据

1. 面临的问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixMezwbr-1635138868378)(pic/03_one_wire/21_one_write_conflict.png)]

两个设备之间,只使用一条数据线,能否传输双向的数据?

  • A发出高电平,B发出低电平
    • 电路可能被损坏
    • 电路上到底是高电平还是低电平?不能确定
  • 问题在于:有两个设备试图同时驱动电路

2. 解决方法

不让双方同时驱动电路,或者即使同时驱动也没关系:

  • 不让双方同时驱动电路:双方无法约定时间,此方法不可行
  • 即使同时驱动也没关系:可行,电路如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ogYSza6-1635138868380)(pic/03_one_wire/22_one_write_bidir.png)]

真值表如下:

ABDATA
001(由上拉电阻决定)
010
100
110

从真值表和电路图我们可以知道:

  • 当某一个芯片不想影响SDA线时,那就不驱动这个三极管
  • 想让DATA输出高电平,双方都不驱动三极管(SDA通过上拉电阻变为高电平)
  • 想让DATA输出低电平,就驱动三极管

芯片内部的三极管,被称为open collector,开集,也就是在芯片内部三极管的集电极是开放的。
芯片内部不驱动三极管是,集电极的电平由外面的上拉电阻决定。

这种电路实现了:

  • 双方设备即使同时想输出不同的电平:
    • 电路也不会被损坏
    • 电平也是确定的

3. 双向传输示例

  • 初始状态:一开始,双方都不驱动三极管,DATA为高

  • 起始信号和回应:A想传输数据给B,发出开始信号、得到回应信号

    • A检测DATA线,高表示对方没有占用数据线
    • A驱动三极管,使得DATA为低,用来通知B:我就要传输数据了
    • A释放三极管,DATA变为高
    • B驱动三极管,使得DATA为低,用来通知A:好的,我准备好了(这是一个回应信号)
    • B释放三极管,DATA变为高
  • 传输:A发送数据给B,比如传输2位数据0、1

    • 双方都使用同一套数据表示方法,比如使用60US来传输一位数据,数值由DATA电平决定
    • 在第1个60us,A设置DATA为低;在同一时间,B读取DATA电平得到数据0
    • 在第2个60us,A设置DATA为高;在同一时间,B读取DATA电平得到数据1
  • 结束:A释放三极管,DATA变为高电平

    • 在第2个60us,A设置DATA为高;在同一时间,B读取DATA电平得到数据1
  • 结束:A释放三极管,DATA变为高电平

  • 这时候,B也可以使用一样的方法给A传输数据

如何高效阅读英文数据手册?

博文参照链接

全英文的数据手册少则十几页,多则上百页也有,加上我们又是如此的爱国(英文水平差的借口),所以在阅读全英文数据手册的时候,根本做不到面面俱到,当然也是完全没有必要,学会善用Ctrl+F搜索关键词,按需所取,阅读我们关注的部分即可。

我以一个DC-DC BUCK芯片举例,列出了很多关键词,其他的数据手册也是同样的道理。

▉ Title

首先是Title,这也是厂家秀肌肉的地方,会告诉你一些最重要的芯片信息,比如TPS56120x系列、输入电压范围4.5~17V、最大输出电流1A、同步降压、封装是6Pin的SOT-23等。
在这里插入图片描述

▉ Feature

如果你是选型,以上参数符合要求,你就会接着往下去看,feature展示了更多的参数,比如输出电压范围、静态功耗、关闭功耗、精度和频率等。

在这里插入图片描述

▉ Description description

可以让我们对这个芯片有个大概的了解。

在这里插入图片描述

▉ Table of Contents

有的数据手册会有目录,可以先了解大致有那些内容,帮助我们寻找关键字。
在这里插入图片描述

▉Pin Configuration and Functions

可以了解芯片的管脚排布,每个管脚对应的信号名,建立原理图封装时需要参考下方这个图。

在这里插入图片描述

通过pin functions了解每个管脚的功能描述,以及设计电路时有什么需要注意的。
在这里插入图片描述

▉ Absolute Maximum

Absolute Maximum即绝对最大值,加在芯片上的参数(电压、温度、ESD等级等)绝对不能超过这个值,否则芯片会损坏。

在这里插入图片描述

▉ Electrical Characteristics

硬件工程师必关注的电气参数,每个芯片的电气参数也是不尽相同的。

在这里插入图片描述

▉ Typical Characteristics

典型的参数,指的是芯片厂商在特定的参数下,测量得出的一些芯片特性,比如下面的不同输出电压和开关频率之间的关系,DC-DC效率和输出电流之间的关系等等,这个是为了让我们更好的了解芯片的性能。

在这里插入图片描述

▉ Functional Block Diagram

功能框图非常重要,透过外部的管脚了解内部的组成,可以更好的理解芯片,如SW管脚接了两个MOS管,这是为什么能输出占空比的原因?OVP和UVP都是通过比较器来实现的等等。

在这里插入图片描述

▉ Feature Description

对芯片的某一些特性进行描述,让我们更好的理解这个芯片的相关特性,如下DC-DC的如软启动、电流保护、UVLO等功能都有详细的描述。
在这里插入图片描述

▉ Typical Application

对于芯片类的数据手册来说,典型应用就是参考电路图。

在这里插入图片描述

▉ Layout Guide

对于芯片类如DC-DC,还有layout指导。

在这里插入图片描述

▉ Packaging Information

package信息,指的是一盒里面的数量,如下可以看见QTY3000和QTY250的型号是不一样的。
在这里插入图片描述

一个系列不同的型号多在后缀有差别,可能是封装不同、package QTY的不同等,所以在order的时候需要写完整的芯片型号。

▉ Package Outline

封装尺寸信息,在建立PCB封装时会用到。

在这里插入图片描述

▉ Example Layout

根据提供的参考layout建立我们自己的PCB封装。

在这里插入图片描述

列了这么多关键词,并不是教大家如何阅读DC-DC数据手册,而是在阐明一个点:不同的人看数据手册的侧重点是不一样的,硬件工程师更关注电气参数、封装信息、参考设计等,软件工程师更关注寄存器、协议等,提取关键字,高效的阅读数据手册,找到对我们有帮助的内容才是最重要的。

类似内存的接口(2440开发板为例)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

SDRAM

在这里插入图片描述
2440芯片手册讲到片选地址映射图:

在这里插入图片描述

NOR FLASH

在这里插入图片描述

网卡

在这里插入图片描述

不同位宽外设的接线

为什么NOR FLASH地址线从ADDR1开始?SDARM地址是从ADDR2开始的?

在这里插入图片描述
在这里插入图片描述
如果CPU要读取32位数据,那么内存控制器会去读两次16位数据存起来,一次性交给CPU。

时序的阅读及内存控制器的设置

在这里插入图片描述

在这里插入图片描述

例如查询2440芯片手册内存控制配置方法:
在这里插入图片描述

再查询相应的外设手册:
在这里插入图片描述

1602液晶驱动显示

阅读手册

1602代表:显示16个字符,可以显示两行。如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
发现使用上表中的数值芯片不能正常驱动,查看原厂家芯片英文资料,实践可以正常使用,具体数值如下图所示:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif

LCD1602.c

#include <REGX52.H>//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0//main函数入口
void main()
{LCD_Init();while(1);}//函数定义:
/*** @brief  LCD1602延时函数,12MHz调用可延时1ms* @param  无* @retval 无*/
void LCD_Delay()
{unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);
}/*** @brief  LCD1602写命令* @param  Command 要写入的命令* @retval 无*/
void LCD_WriteCommand(unsigned char Command)
{LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602写数据* @param  Data 要写入的数据* @retval 无*/
void LCD_WriteData(unsigned char Data)
{LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay();
}/*** @brief  LCD1602设置光标位置* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @retval 无*/
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));}
}/*** @brief  LCD1602初始化函数* @param  无* @retval 无*/
void LCD_Init()
{LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动LCD_WriteCommand(0x01);//光标复位,清屏
}/*** @brief  在LCD1602指定位置上显示一个字符* @param  Line 行位置,范围:1~2* @param  Column 列位置,范围:1~16* @param  Char 要显示的字符* @retval 无*/
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{LCD_SetCursor(Line,Column);LCD_WriteData(Char);
}/*** @brief  在LCD1602指定位置开始显示所给字符串* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  String 要显示的字符串* @retval 无*/
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);}
}/*** @brief  返回值=X的Y次方*/
int LCD_Pow(int X,int Y)
{unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result;
}/*** @brief  在LCD1602指定位置开始显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~65535* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置开始以有符号十进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:-32768~32767* @param  Length 要显示数字的长度,范围:1~5* @retval 无*/
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');}
}/*** @brief  在LCD1602指定位置开始以十六进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~0xFFFF* @param  Length 要显示数字的长度,范围:1~4* @retval 无*/
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i,SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData(SingleNumber+'0');}else{LCD_WriteData(SingleNumber-10+'A');}}
}/*** @brief  在LCD1602指定位置开始以二进制显示所给数字* @param  Line 起始行位置,范围:1~2* @param  Column 起始列位置,范围:1~16* @param  Number 要显示的数字,范围:0~1111 1111 1111 1111* @param  Length 要显示数字的长度,范围:1~16* @retval 无*/
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');}
}

IIC总线AT24C02芯片实验(E2PROM)

IIC总线协议

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

24C02芯片手册阅读

在这里插入图片描述
前面讲了,器件前四位地址固定为1010,后三位在开发板里全部接地,因此器件地址确定为:0X1010 000.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

编写代码

IIC.h

#ifndef __I2C_H__
#define __I2C_H__void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte(void);
void I2C_SendAck(unsigned char AckBit);
unsigned char I2C_ReceiveAck(void);#endif

IIC.c

#include <REGX52.H>sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;/*** @brief  I2C开始* @param  无* @retval 无*/
void I2C_Start(void)
{I2C_SDA=1;I2C_SCL=1;//前后要保证间隔4.7us,郭天祥老师在这里写了个delay空函数(下同)I2C_SDA=0;I2C_SCL=0;
}/*** @brief  I2C停止* @param  无* @retval 无*/
void I2C_Stop(void)
{I2C_SDA=0;I2C_SCL=1;I2C_SDA=1;
}/*** @brief  I2C发送一个字节* @param  Byte 要发送的字节* @retval 无*/
void I2C_SendByte(unsigned char Byte)
{unsigned char i;//单片机节省空间 不用inttemp = Byte;for(i=0;i<8;i++){temp = temp<<1;I2C_SDA = CY;//溢出位//I2C_SDA=Byte&(0x80>>i); 这种方法没看懂I2C_SCL=1;I2C_SCL=0;//低电平可改变数据 下一循环送入新的数据}
}/*** @brief  I2C接收一个字节* @param  无* @retval 接收到的一个字节数据*/
unsigned char I2C_ReceiveByte(void)
{unsigned char i,k,Byte=0x00;I2C_SDA=1;for(i=0;i<8;i++){I2C_SCL=1;j = I2C_SDA;k = (k<<1)|j;//if(I2C_SDA){Byte|=(0x80>>i);}I2C_SCL=0;}return k;
}/*** @brief  I2C发送应答* @param  AckBit 应答位,0为应答,1为非应答* @retval 无*/
void I2C_SendAck(unsigned char AckBit)
{I2C_SDA=AckBit;I2C_SCL=1;I2C_SCL=0;
}/*** @brief  I2C接收应答位* @param  无* @retval 接收到的应答位,0为应答,1为非应答*/
unsigned char I2C_ReceiveAck(void)
{unsigned char AckBit;I2C_SDA=1;I2C_SCL=1;AckBit=I2C_SDA;I2C_SCL=0;return AckBit;
}

AT24C02.h

#ifndef __AT24C02_H__
#define __AT24C02_H__void AT24C02_WriteByte(unsigned char WordAddress,Data);
unsigned char AT24C02_ReadByte(unsigned char WordAddress);#endif

AT24C02.c

#include <REGX52.H>
#include "I2C.h"#define AT24C02_ADDRESS		0xA0//地址高四位固定是1010为a 后三位为000 写位为0/*** @brief  AT24C02写入一个字节* @param  WordAddress 要写入字节的地址* @param  Data 要写入的数据* @retval 无*/
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{I2C_Start();I2C_SendByte(AT24C02_ADDRESS);//发送器件地址写I2C_ReceiveAck();             //收到应答I2C_SendByte(WordAddress);    //要写入字节的地址 自己随便定I2C_ReceiveAck();             //收到应答I2C_SendByte(Data);           //发送(写入)数据I2C_ReceiveAck();             //收到应答I2C_Stop();
}/*** @brief  AT24C02读取一个字节* @param  WordAddress 要读出字节的地址* @retval 读出的数据*/
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{unsigned char Data;I2C_Start();I2C_SendByte(AT24C02_ADDRESS);//伪写I2C_ReceiveAck();I2C_SendByte(WordAddress);I2C_ReceiveAck();I2C_Start();I2C_SendByte(AT24C02_ADDRESS|0x01);//代表要读数据I2C_ReceiveAck();Data=I2C_ReceiveByte();            //读到数据I2C_SendAck(1);I2C_Stop();return Data;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265183.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决替换weblogic的commons-fileupload.jar后引发的问题

为什么80%的码农都做不了架构师&#xff1f;>>> 上一篇博文中提到通过替换weblogic自带的commons-fileupload.jar来解决FileUpload类的NoSuchMethodError问题。在完成替换后&#xff0c;该问题得到顺利解决&#xff0c;但是也会引发其他的一些问题&#xff0c;下面…

Python for Data Analysis 学习心得(二) - pandas介绍

一、pandas介绍 本篇程序上篇内容&#xff0c;在numpy下面继续介绍pandas&#xff0c;本书的作者是pandas的作者之一。pandas是非常好用的数据预处理工具&#xff0c;pandas下面有两个数据结构&#xff0c;分别为Series和DataFrame&#xff0c;DataFrame之前我在一些实战案例中…

Euler:欧拉函数&素数筛

一、欧拉函数 欧拉函数是小于x的整数中与x互质的数的个数&#xff0c;一般用φ(x)表示。 通式&#xff1a; 其中p1, p2……pn为x的所有质因数&#xff0c;x是不为0的整数。比如x12&#xff0c;拆成质因数为122*2*3&#xff0c;12以内有1/2的数是2的倍数&#xff0c;那么有1-1/2…

大小端字节序

想起以前在汇编语言和数字逻辑的时候也有接触到一些这个概念&#xff0c;已经有点模糊了&#xff0c;搞不清楚哪个是低位在前哪个是高位在前。后来在Wiki和Google的帮助下也算摸清楚了一些Endianness的概念。 一、字节序的起源 在计算机中&#xff0c;字节序&#xff08;Endian…

docker 部署nginx 使用keepalived 部署高可用

一&#xff0e;体系架构 在Keepalived Nginx高可用负载均衡架构中&#xff0c;keepalived负责实现High-availability (HA) 功能控制前端机VIP&#xff08;虚拟网络地址&#xff09;&#xff0c;当有设备发生故障时&#xff0c;热备服务器可以瞬间将VIP自动切换过来&#xff0c…

虚拟字符设备驱动开发步骤

目录前言字符设备驱动简介内核驱动操作函数集合(file_operations结构体)字符设备驱动开发步骤.ko驱动模块的加载和卸载(module_init驱动入口、insmod驱动加载)字符设备注册与注销到内核register_chrdev(设备号、设备名) -- 很少用了实现设备的具体操作函数添加LICENSE 和作者信…

设计模式20——Mediator设计模式

2019独角兽企业重金招聘Python工程师标准>>> Mediator中介者设计模式是通过一个中介对象封装一系列关于对象交互行为. Mediator中介者设计模式中的角色如下&#xff1a; (1).中介者&#xff08;Mediator&#xff09;&#xff1a;抽象定义了“同事”&#xff08;co…

Linux LED驱动开发实验(直接操作寄存器 -- 实际开发很少这样做)

目录Linux 下LED 灯驱动原理地址映射(ioremap映射、iounmap释放)I/O 内存访问函数硬件原理图分析实验程序编写LED 灯驱动程序编写APP测试程序编写运行测试编译驱动程序和测试APP拷贝led.ko 和ledApp到指定目录加载led.ko 驱动模块到内核创建应用层“/dev/led”设备节点运行测试…

Strange Words 4

2019独角兽企业重金招聘Python工程师标准>>> abnormality 英[ˌbnɔːmləti] 美[ˌbnɔːrmləti] n.变态&#xff1b;反常&#xff1b;异常&#xff1b;畸形 tenor 英 [tenə(r)]  美 [tenər] n.大意&#xff1b;要旨&#xff1b;常规&#xff1b;男高音&…

新字符设备驱动实验(自动分配设备号、自动创建应用层设备节点、新字符设备注册到内核的结构体)

目录自动分配和释放设备号示例代码新的字符设备注册到内核方法字符设备结构体(前面的设备号也放进来)cdev_init结构体初始化函数cdev_add 添加到linux内核cdev_del内核注销函数自动创建应用层设备节点mdev 机制创建和删除类创建删除设备(生成/dev/xxx设备)参考示例(先删除设备再…

$Django importlib与dir知识,手写配置文件, 配置查找顺序 drf分页器drf版本控制

1 importlib与dir知识 # importlib简介动态导入字符串模块 # 常规导入 from ss.aa import b from ss import a print(b,type(b)) #<module ss.aa.b from F:\\python37\\pythonfiles\\ss\\aa\\b.py> #<class module># importlib动态导入py文件模块 import importli…

springMVC_07乱码及restful风格

乱码的解决 通过过滤器解决乱码问题:CharacterEncodingFilter 配置web.xml文件 <filter><filter-name>encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><para…

[转】HTTP请求流程(二)----Telnet模拟HTTP请求

转自&#xff1a; http://www.cnblogs.com/stg609/archive/2008/07/06/1237000.html 上一部分"流程简介"&#xff0c; 我们大致了解了下HTTP请求的流程&#xff0c;这一篇我向大家介绍下如何利用Telnet来模拟Http请求---访问百度。 我们直接开始吧&#xff01; …

设备树下的LED驱动实验

目录设备树LED驱动原理硬件原理图分析实验程序编写修改设备树文件(根节点下添加好区分)LED灯驱动程序编写编写测试APP运行测试编译驱动程序和测试APP运行测试上一章我们详细的讲解了设备树语法以及在驱动开发中常用的OF 函数&#xff0c;本章我们就开始第一个基于设备树的Linux…

《现代操作系统》精读与思考笔记 第七章 多媒体

第七章部分内容与前几章内容关联很大&#xff0c;比如进程调度、磁盘调度、文件系统&#xff0c;而且多为实现细节&#xff0c;这里不详述。 1.帧数与闪烁&#xff08;P476&#xff09; 画面动作的平滑性不是完全由每秒的帧数决定的&#xff0c;而是由每秒不同画面的数目决定的…

pinctrl和gpio子系统实验(芯片原厂做的,类似STM32的HAL库,我们只需调用API来直接操作GPIO)

目录pinctrl子系统pinctrl子系统简介(半导体厂商写的)I.MX6ULL的pinctrl子系统驱动分析0、通过compatbile属性查找对应驱动文件1、PIN配置信息详解(获取寄存器地址)2、PIN 驱动程序流程讲解(流程图&#xff0c;了解)设备树中添加pinctrl节点模板(半导体厂商瑞芯微、海思厂商写的…

成为你自己

2019独角兽企业重金招聘Python工程师标准>>> 一个看过许多国家、民族以及世界许多地方的旅行家&#xff0c;若有人问他&#xff0c;他在各处发现人们具有什么相同的特征&#xff0c;他或许会回答∶他们有懒惰的倾向。有些人会觉得&#xff0c;如 果他说他们全是怯懦…

网络知识梳理--OSI七层网络与TCP/IP五层网络架构及二层/三层网络

作为一个合格的运维人员&#xff0c;一定要熟悉掌握OSI七层网络和TCP/IP五层网络结构知识。 废话不多说&#xff01;下面就逐一展开对这两个网络架构知识的说明&#xff1a;一、OSI七层网络协议OSI是Open System Interconnect的缩写&#xff0c;意为开放式系统互联。 OSI参考模…

Linux蜂鸣器实验(使用上一节子系统思想,摈弃了自己配置寄存器的繁琐操作)

目录子系统思想的蜂鸣器驱动流程硬件原理图分析实验程序编写修改设备树文件蜂鸣器驱动程序编写编写测试APP运行测试编译驱动程序和测试APP运行测试上一章实验中我们借助pinctrl 和gpio 子系统编写了LED 灯驱动&#xff0c;I.MX6U-ALPHA 开发板上还有一个蜂鸣器&#xff0c;从软…

gitbash如何修改可恶的蓝色字体

1、问题 这完全看不清啊&#xff01;&#xff01; 2、环境 git version 2.19.0 3、解决 1&#xff09;编辑/etc/bash.bashrc # Uncomment to use the terminal colours set in DIR_COLORS eval "$(dircolors -b /etc/DIR_COLORS)" 2&#xff09;编辑/etc/DIR…