本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整。
以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅)
一些内容涉及前面的知识点,可能需要提前了解(可以翻看本人之前的文章或者去B站看UP主的视频)
文章目录
16-1 AD/DA
AD/DA介绍
-
AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可操作的数字信号。
(如单片机只能识别0与5V数字信号,当输入为2.5V——模拟信号时,就需要转化为单片机所能读取的数字信号)
-
DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号。
(如单片机需要通过转换,才能发送除0、5V外的模拟信号)
-
AD/DA转换打开了计算机与模拟信号的大门,极大的提高了计算机系统的应用范围,也为模拟信号数字化处理提供了可能。
光敏电阻:
运行原理如上,当感光变化后,光敏电阻阻值变化,使得高电平另一端的电压(图中黑点)发生变化(模拟信号);经过AD转化为数字信号从而读取信息。
热敏电阻:
原理同上,将光敏电阻替换为热敏电阻即可。
麦克风:
将说话的声音转化为数字信号(一连串的),然后通过AD采集,转换为计算机可读取的数字信号(因为不是所有的数字信号计算机都可以采集)。
扬声器:
通过将音乐对应的数字信号通过DA转换为实际电压(连续的电压波形),通过麦克风处理即可听到存储的音乐。
硬件电路
硬件电路模型
-
PS:上图的模拟量与数字量呈正比关系。(即255对应5V,0对应0V,255/2对应2.5V,以此类推)。
-
AD转换通常有多个输入通道,用多路选择开关连接至AD转换器,以实现AD多路复用的目的,提高硬件利用率。
(即一个AD可接多个模拟量检测,通过切换进行选择模拟量检测)
-
AD/DA与单片机数据传送可使用并口(速度快、原理简单),也可使用串口(接线少、使用方便)。
——这里的串口不是之前沟通两个设备的串口。
-
可将AD/DA模块直接集成在单片机内,这样直接写入/读出寄存器就可进行AD/DA转换,单片机的IO口可直接复用为AD/DA的通道。
-
补充:AD一般多个通道,而DA一般只有一个通道(因为需要输出连续的信号,多个通道容易错乱);且DA一般可以用PWM进行替代。
实际硬件电路
单片机上原理图:
有时AD/DA会在后面加上C,但也代表AD/DA模块。
ADC模块封装在触摸屏芯片上(有兴趣可以了解触摸屏部分知识),利用的是SPI总线通信,
DAC模块约等于PWM部分(PWM模块加上一个低通滤波即可与DA效果相同)
来自搜索:低通滤波器是容许低于截止频率的信号通过, 但高于 截止频率 的信号不能通过的电子滤波装置。
芯片原理介绍(以旧版的较为经典的芯片为例):
ADC芯片:
-
DB0~DB7为输出的八个数据;
-
IN0~IN7为输入的八个通道(8路),通过8路模拟开关进入A/D转换;
-
ADDA~ADDC负责控制8路模拟开关的操作,选择读取哪一路的数值;
-
A/D转换上方的三个引脚控制A/D转换,
其中START控制A/D开始转换,
EOC为转换结束和时钟信号,可以将输出的电压转换为一定的信号,并通过锁存器进行输出缓存,
CLOCK负责锁存器的输出控制,
OE负责输出使能,将数据输出出去。
-
右边的图为其实际的芯片图。
DAC芯片:
- D0~D7为其输入数据,存储于8位输入寄存器中;
- 8位DAC寄存器用于多路同步输出,可以将两次数据分别放于8位输入与DAC寄存器中,然后同时给输出信号进行输出;
- 其中CS、WR1、WR2、XFER(上方均有一横线)负责控制8位输入与DAC寄存器输出。
运算放大器
-
运算放大器(简称“运放”)是具有很高放大倍数的放大电路单元(不是像电阻那样的单独元件)。
内部集成了差分放大器、电压放大器、功率放大器三级放大电路,是一个性能完备、功能强大的通用放大电路单元,
由于其应用十分广泛,现已作为基本的电路元件出现在电路图中。
-
运算放大器可构成的电路有:电压比较器、反相放大器、同相放大器、电压跟随器、加法器、积分器、微分器等。
-
运算放大器电路的分析方法:虚短、虚断(负反馈条件下)。
放大器符号:
正号为同相输出端,负号为反相输出端;
有时会加上集成电路的电源(即在输出端与三角形交点处上面接一个电源,下面接一个电源),也可省略(即默认有电源)。
LM358信号放大电路:
运算放大器的特性:
-
输入阻抗非常大(同相、反向输入端几乎不流入与流出电流),以避免对前面电路产生影响。
-
内部有功率输出部分,因此输出端具有驱动能力。
-
因为集成化之后无法调节放大倍速,
所以为了能调节,这里将内部放大倍数设置很大(理想情况可以想象为无穷大),
并利用深度负反馈规则的知识,来进行动态调节放大倍数(模电部分知识,有兴趣可以去了解)
深度负反馈部分说明(简略):
- 因为放大倍数非常大,因此很容易到达深度负反馈;
- 通过在外部接上负反馈,使得能利用外部调节放大倍数(此时放大倍数不由内部电路决定),从而实现动态调节;
- 利用这个特性,可以不同组合负反馈部分电路来实现不同功能。
四个运算放大器的经典电路
一、电压比较器
作用:比较同相输入端与反相输入端两个信号的电压值,并以高低电平的形式输出结果。
该电路状态处于没有连接负反馈的情况下使用(开环状态)。
作用公式:Vout=A∞(V+ - V-),其中A为放大倍数。
二、反向放大器
作用公式:Vout=A×VIN,其中A=-R2/R1。
作用原理:
放大器部分:
假设IN端传入0.1V,那么反相输入端就为0.1V,经过放大器到达OUT时就为负电压(此时电压为放大后的状态),
而此时该状态又会通过R2的部分将反相输入端拉低到小于0V(负电压大于0.1V),再次经过放大器就会使得OUT端变为正电压(此时电压为放大后的状态),
同样该状态也会通过R2部分将反向输入端拉高到大于0V(因为正电压大于负电压),使得OUT又变为负电压,
以此反复(负反馈过程),最终达到稳态(即正电压与负电压相等时,影响结束)。
最终的稳态就为虚短状态(负反馈状态下,负极电压与正极电压相等)。
——虚断状态下,反相输入端(其他情况同理)电流既不流入也不流出(因为输入阻抗大)。
外部负反馈部分:
因为放大器部分的反相输入端最终因为稳态变为0V,且此时为虚断,因此电流只能流经R2,
所以R2部分的电流与R1部分电流相等,而R2的+端电压为0V,-端电压可以利用U=IR,计算为VOUT= 0-(0.1V÷R1)×R2。——这里VIN假设为0.1V。
因此,VOUT端电压为(-R2/R1)×VIN。
反向名称原因:因为输入的为正电压,反为负电压,因此得名。
三、同向放大器
作用原理:
因为放大器部分会变为虚短状态,因此反向输入端就会变为VIN电压值,
而R1另一端接地,因此利用U=IR,可计算出此时的电流 I 为(VIN - 0)÷ R1,
因为放大器部分会变为虚断状态,因此电流只流过R2,所以R2处的电流与R1相等,
因此可以计算出R2连接OUT部分的电压VOUT= I × R2-(-VIN),其中 I = VIN / R1。
作用公式:
VOUT = VIN / R1 × R2 +VIN
=(1+R2/R1)×VIN
= A×VIN(其中A为放大倍速)
PS:较反向放大器而言,输出电压与输入电压同向(均为正或均为负),且输出为正电压时,无需双电源(反向放大器需要双电源才能输出正电压)。
四、电压跟随器
该电压跟随器相当于同向放大器的特殊情况(保持原倍数)。
利用电压跟随器能提高信号的驱动能力(虽然没有电压放大特性,但具有功率放大特性),可将没有驱动能力的信号变为相同的有驱动能力的信号。
AD/DA原理
DA原理
T型电阻网络DA转换器:
说明:
- 由上图可知,最下端I01与I02对应两根线由于放大器虚短特性,使得电压均为0V,因此电阻无论接0还是1,均为接GND。(为了不影响前面电阻网络的分压分流)
- 根据上方电阻分析,可知等效总电阻为R,因此最上方干路线上的 I =VREF / R。
- 对于支路上的 I0 ~ I7 而言,I1=2×I0,I2 = 2×I1 ,以此类推(左边电流为右边电流二倍),以此来表达二进制的位权。
- 因此 I0 = I /256 = VREF /(256×R)。—— I = 2× I7。
- 从而通过调节电阻下方开关来汇聚 I0 电流,最终利用反向放大器原理,实现输出电压。
好处:数据输出稳定。
坏处:①占用I/O口多(可以封装起来利用串行总线进行解决);②精度限制为256,不可调节。
PWM型DA转换器:
该转换器为本单片机开发板上的DA转换器。
说明:
-
其中一个电阻加一个电容接GND构成一个低通滤波器(如图中R1、C1与GND构成RC滤波器),
-
而图中接两根低通滤波器,称为二阶低通滤波器。
-
PWM信号加上加上低通滤波器可以变为稳定的直流信号。(通过滤掉变化时的交流信号,仅保持直流信号实现过滤)
-
因为前面的分压结构产生的电压驱动能力弱,因此加上电压跟随器使得驱动能力增强。
好处:①节省I/O口;②精度高(调节PWM占空比即可实现精度提高)。
坏处:①比较消耗单片机内部资源,需要输出PWM波形;②低通滤波器输出性能较差时,会出现一定的纹波(没过滤完的交流信号)。
AD原理
- DA可以通过数字量控制开关,开关输出模拟信号;而AD无法将模拟量进行量化输出,因此需要借助DAC。
- 这里的比较器可以使用运算放大器的电压比较器。
- 通过比较器,将传入的模拟信号与DAC产生的信号进行对比,并不断修改DAC的信号值(DAC偏大改小,偏小改大),直到逼近传入的信号,这样间接的将未知的模拟量转换为确定的数字量。——二分法比较修改DAC的值进行查找。
- 最终得出的高低电平传入逐次逼近寄存器中,检测DAC与传入的模拟信号大小进行运作(如果偏大或偏小,就返回继续DAC产生信号;如果趋近相等,就送入下面的锁存缓冲器中)——中间可以有定时跟控制等操作。
补充:AD/DA性能指标(部分)
- 分辨率:指AD/DA数字量的精细程度,通常用位数表示。例如,对于5V电源系统来说,8位的AD可将5V等分为256份,即数字量变化最小一个单位时,模拟量变化5V/256=0.01953125V,所以,8位AD的电压分辨率为0.01953125V,AD/DA的位数越高,分辨率就越高。
- 转换速度:表示AD/DA的最大采样/建立频率,通常用转换频率或者转换时间来表示,对于采样/输出高速信号,应注意AD/DA的转换速度。
XPT2046
本单片机原理图:
XPT2046介绍
购买时附带资料(XPT2046):
XPT2046时序
-
该时序使用的是SPI通信。
-
CS(上方一横线,片选)、DCLK(时钟)、DIN(数据输入)、DOUT(数据输出)为SPI中基本的信号线。
-
除CS线外的三根线可进行复用(多个芯片共用三根线),每个芯片都有单独的CS线(片选)可供选择来运行(同一时刻只运行一个芯片,否则容易出错)。
-
有时可以进行替换:
DIN——>MISO(主设备输入,从设备输出),
DOUT——>MOSI(主设备输出,从设备输入)。
运行方式:
①选择CS线(拉低开始通信);
②调节DCLK,上升沿输入数据,下降沿输出数据;
③通过DIN与DOUT线进行数据传输;(当DIN进行时,DOUT空闲,此时可以进行其他芯片输出。反过来同理)
④当经过一个周期(八位)后,主从机内部数据进行一次交换;
⑤结束后将CS线拉高完成通信。
补充:
①发送字节时高位在前,低位在后(接收同理);
②发送的第一个字节定义为控制字;
③控制字前三位负责表达控制哪一路(多路选择),后面的位负责表达控制模式(8位/12位模式,单端模式,差分模式等),参考电压,低功耗等。
④发送完一个字节后可进行读出AD值(一个字节或连续两个字节);
⑤当读出连续两个字节时,因为为12位,因此剩余的位用0填充。
⑥通过调用时序即可将AD值读出。
PS:
滑动变阻器、热敏电阻、光敏电阻产生的模拟信号通过AIN0~AIN2将数据输入给芯片进行处理。
16-2 AD模数转换&DA数模转换
代码一
实现效果:在LCD1602液晶屏上显示电位器、热敏电阻、光敏电阻的AD值。
Ⅰ、新建工程与main.c
Ⅱ、添加已模块化的代码文件
其中LCD1602文件为液晶屏显示文件,Delay文件为延时函数文件。
Ⅲ、编写XPT2046文件
XPT2046.c
ADC模块原理图:
XPT2046时序图:
一、定义I/O口
二、编写读取AD函数
XPT2046.h
Ⅳ、编写主函数文件
手册中控制字节部分:
PS:
一、SER/DFR(DFR上方一横线)部分
本单片机硬件模式为单端模式。
(差分模式指的是读取两个值的AD,求其差值;单端模式指的是一端接 地,只读取一个值的AD)
由下图可见,X-与Y-均接地,因此为单端模式。
ADC模块原理图:
二、PD1部分
对于PD1而言,当为1时,为内部电源模式(2.5V),此时精度较高,但会损失2.5~5V的电压表达;当为0时,为外部电源模式(下图VREF正上方的VCC,5V)。
——这里不需要太高精度,因此选用外部电源,PD1给0。
内部参考电压手册图:
三、地址部分(A2~A0)
可通过配置地址部分,读取对应的AD值。
①下方图中的VBAT为电池电压,
②AUXIN为辅助输入电压,
因此按照手册图选取对应地址即可检测对应AD值。
单端模式地址部分手册图:
目标测试的原理图(画圈部分):
对命令字添加定义
更改XPT2046.h部分
更改XPT2046.c部分
添加读取
Ⅴ、烧录程序
烧录后即可看到预期效果。
单片机开发板部分:
代码二
实现效果:第二个LED灯实现呼吸灯效果。
Ⅰ、将之前直流电机文件复制粘贴一份
Ⅱ、更改定义的I/O口
Ⅲ、替换对应名称
一、点击替换的图标。
二、填入需要替代的名称与替代的名称,点击[Replace All],完成全部替换。
Ⅳ、编写主函数文件
划蓝线部分为更改部分。
Ⅴ、烧录程序
烧录后即可看到预期效果。
且可以看到AD/DA部分的LED灯也呈现呼吸灯效果,因为DA转换部分为二倍放大效果,因此可见该LED亮度低于LED模块的LED亮度。
17-1 红外遥控(外部中断)
Ⅰ、红外遥控简介
- 红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出
- 通信方式:单工,异步
- 红外LED波长:940nm
- 通信协议标准:NEC标准
红外LED:
红外接收头:
红外遥控器:
Ⅱ、硬件电路
发送部分:
类型一:
PS:本单片机并没有发送部分,只接受遥控器发出的红外信号。
说明:
①这里连接了两个三极管开关;
②R1所在电路输入端为38KHZ的方波;
③IN口输入为波形;对应的三极管开关(PHP型)为低电平导通(高电平不导通);
④利用两个三极管开关,组合成IN口传出的波形,波形每段对应38KHZ的波形(对应控制红外LED的闪烁)
——原因是为了抗干扰,加入38KHZ的波形闪烁,使得该红外波形成为特有的类型,不会受到外界干扰(比如太阳光)
截自up主:
类型二:
该类型电路相较于类型一,简化了38KHZ部分,因此IN输入端需要自行利用程序产生最后一段的抖动波形。
接受部分:
接受的红外接收头需要将调制的波形进行解调,使得其恢复原来的波形(如类型一中,最终的传出红外波,需要将38KHZ的方波抖动去除,变回IN传入的波形)
PS:
①利用一体化红外接收头(集成有解调电路),就可以直接帮助解调,无需自行处理。
②因为产生的波形抖动速度快,因此不能利用if语句进行判断,需要利用外部中断进行接收OUT产生的波形数据。
基本发送与接收
- 空闲状态:红外LED不亮,接收头输出高电平
- 发送低电平:红外LED以38KHz频率闪烁发光,接收头输出低电平
- 发送高电平:红外LED不亮,接收头输出高电平
Ⅲ、NEC编码
PS:
①地址码反码对地址取反,用于对地址码进行验证;命令反码同理。
②数据红外接收部分,560us的下降沿与560us的上升沿组成数据0;560us的下降沿与1600us的上升沿组成数据1。
③一帧数据时间长度为110ms,采集完后接下来进行分析解调。
④后面的Repeat部分为按住按键不放时,连续发送数据的意思。
示波器实际采样图:
上面虚线的一个格子对应2ms。
每个下降沿既是上一个上升沿的结束(截止时间),又是下一个下降沿的开始(开始计时)。
当发完所有数据后,会多出一个下降沿,代表上一个上升沿结束,最后上升恢复高电平。
Ⅳ、遥控器键码
Ⅴ、51单片机的外部中断
外部中断固定接在INT0与INT1两部分(即固定接在P3_2与P3_3这两个引脚上)
外部中断寄存器
说明:
①这里的外部中断INT0与INT1直接连接I/O口。(区别于T0之类的定时器中断)
②这里的触发方式由IT0与IT1决定(等于1时下降沿触发,等于0时低电平触发)。
③IE0与IE1为中断标志位。
④剩余的部分与定时器中断电路类通。
上方的表格中,红线框内容与外部中断有关,其余的与定时器有关。
17-2 红外遥控&红外遥控电机调速
代码一
实现效果:
在LCD1602液晶屏上第一部分显示遥控器的地址码,
第二部分显示遥控器的控制码(或者叫命令码,即键码),
第三部分当按下VOL+与VOL-时,该部分数字进行加减,且长按能一直加减。
Ⅰ、新建工程与main.c
Ⅱ、添加需要的已模块化的文件
其中Delay文件为延时函数文件,LCD1602文件为液晶屏显示函数文件。
Ⅲ、配置外部中断部分
一、配置电路
二、写入中断函数模板
三、测试外部中断是否有效
添加蓝线部分,进行测试。
显示效果:
独立按键原理图:
由独立按键原理图可知,触发外部中断的P3_2引脚与独立按键K3引脚相同,因此可以通过按动K3来触发中断。
按下后,数字增加,说明外部中断有效;
且按住按键数字无反应。
补充:可以配置为低电平触发,进行测试。
此状态下,按住K3按键不放时,可以看到数字一直增加,
因此可以说明低电平触发与下降沿触发的区别。
四、封装外部中断部分
①建立Int0.c与Int0.h文件,进行封装
②处理Int0.c部分
③处理Int0.h部分
PS:
建议不要用外部中断检测按键部分(因为存在消抖问题,且无法处理松手的情况)。
Ⅳ、改造定时器0模块为计数模式
一、添加定时器0模块化文件
二、改造初始化部分
三、添加计数部分
四、添加计数值返回部分
五、添加计数器启动部分
Timer0.c文件
Timer0.h文件
六、测试效果
烧录后,在LCD1602液晶屏上显示Delay后的延时时间。(可能存在误差,本单片机11.0592MHZ显示延时值为09295,因为对于up主的12MHZ晶振速度更快一点)
Ⅴ、编写红外解码文件
利用红外解码文件封装定时器0文件与外部中断文件,并对波形进行处理,这样主函数只需要调用该红外解码文件即可。
一、添加初始化部分
二、定义需要的变量
补充:
①其中之所以利用数组unsigned char IR_Data[4],而不用unsigned long类型存储,是因为后面的类型变量,在高位存储时会出错,因此采用数组。
②利用IR_Address与IR_Command这两个变量存储最终值,而将数组作为中间的暂存数据,是为了将输入与处理进行区分,避免产生混乱。
三、写入外部中断函数
①编写空闲状态部分
②编写触发读取部分
PS:这里的时间判断与上图时间不一样,是因为本单片机为11.0592MHZ的,因此需要进行**(本单片机晶振/up主单片机晶振)×up主所给时间数据**来进行时间处理。
可见需要将时间乘以0.9216,因此这里时间与NEC的范围时间不同。
③编写开始解码状态
PS:这里将数组单元特定位赋1与赋0对应的关系运算符不一样,出错可能会导致遥控时有问题。(本单片机会出现问题,up主的似乎不会)
四、添加接收数据与命令部分
五、添加返回数据与命令部分(封装)
IR.c文件
IR.h文件
Ⅳ、添加对应键码值的宏定义
添加宏定义后,之后就不需要去查键码值,直接调用即可。
Ⅴ、编写主函数部分
PS:这里检测的键码值为按键1与2来实现效果,而不是VOL-与VOL+的原因是因为需要对前面的键码搜索时长进行调整,否则该按键检测无效(因为还没测试到该按键的检测区间,因此暂时用按键1与按键2替代)
——第二天再测试,发现可正常检测所有按键。
Ⅵ、烧录程序
烧录后即可看到预期效果。
代码二
实现效果:利用遥控器的0~3按键控制直流电机的转速。
Ⅰ、将之前直流电机调速的文件复制粘贴一份
Ⅱ、调整Timer0文件部分为定时器Timer1。
其他文件部分把所有Timer0的全部换为Timer1即可。
(最后别忘了将文件名也更改掉)
Ⅲ、添加代码一模块化的文件
Ⅳ、将电机部分的代码模块化
Motor.c文件
Motor.h文件
Ⅴ、编写主函数部分
Ⅵ、烧录程序
烧录后即可看到预期效果。