阅读下面的引文,然后研究这个术语微控制器看看它和这句话有什么关联
我会让你做这个问题的家庭作业!
这句话不仅有趣,而且令人吃惊,特别是对我们这些出生时家里根本没有电脑,更不用说多台个人电脑的人来说。
我想让学生们研究“微控制器”一词的一点是,我想让他们看到,目前存在的大多数计算机并不是人们通常认为的那种称为“计算机”的品种。那些门把手电脑——以及汽车中的发动机控制电脑、厨房电器、移动电话、生物医学植入物、会说话的生日卡和其他小型设备——比人们在办公桌上用来写文件或上网的“通用”电脑要小得多,也要专业化得多。它们是现代“计算机革命”中无声的、看不见的一面,在许多方面,它们比那些规模更大、用途更广的同行更适合数字电子学的初学者去探索。yabosports官网
A.微控制器单元,或单片机是一种专用的数字计算机,用于提供系统的自动排序或控制。微控制器与普通数字计算机的不同之处在于它非常小(通常是一个集成电路芯片),有几个专门用于数字信号输入和/或输出的引脚,并且内存有限。编入微控制器存储器的指令告诉它如何对输入条件作出反应,以及向输出输出什么类型的信号。
被微控制器“理解”的最简单的信号类型是一个离散的电压水平:在芯片上指定的引脚上测量“高”(约V)或“低”(约地电位)。微控制器内部的晶体管在输出管脚产生这些“高”和“低”信号,为了简单起见,它们的动作被SPDT开关模拟:
|
除了各种组合和多谐振荡器功能外,微控制器还可以通过编程来模拟数字逻辑门(与、或、与非、NOR等)的功能。一个微控制器所能做的唯一真正的限制是内存(一个程序可以存储多大)和MCU芯片上的输入/输出引脚。
然而,微控制器本身是由成千上万(或数百万)逻辑门电路组成的。为什么用一个微控制器来执行一个逻辑功能,而它的组成门的一小部分可以直接完成呢?换句话说,当人们可以用更少的门电路构建所需的逻辑网络时,为什么还要费心给微控制器编程来执行数字功能呢?
易于配置和灵活性!
请注意,我没有费心解释我极其简洁的答案。这是一个我希望学生们长期认真思考的主题,因为这个问题的真正答案是驱动所有可编程数字设备发展的原因。
一个学生决定建立一个闪光电路使用微控制器而不是555定时器或一些其他硬线稳定电路。不幸的是,有些地方出了问题。当第一次通电时,LED灯亮1秒,然后关闭,永不再亮。唯一的LED恢复亮的方式是MCU复位或其电源循环关闭和打开:
|
伪代码清单声明Pin0为输出
开始
设置Pin0高
暂停1秒
将Pin0设置为低
结束
一个同学在被请求帮助时,修改程序列表,并通过编程电缆将其从正在编辑的个人电脑重新发送到微控制器上。程序列表如下所示:
伪代码清单声明Pin0为输出
循环
设置Pin0高
暂停1秒
将Pin0设置为低
ENDLOOP
当MCU用新程序复位时,LED开始闪烁打开和关闭。某种程度上。LED大部分时间处于“开启”状态,但每秒关闭一次,然后立即重新开启。事实上,“关闭”的时间很短,几乎不值得注意。
学生想要的是50%的占空比:“开”1秒,然后“关”1秒,无限重复这个循环。首先,解释同学修改程序的重要性,然后再次修改程序列表,让LED做学生想让它做的事情。
一个“循环”对于MCU重复开/停/关顺序是必要的。现在需要的是循环内的另一个时间延迟:
伪代码清单声明Pin0为输出
循环
设置Pin0高
暂停1秒
将Pin0设置为低
暂停1秒(新代码行)
ENDLOOP
这个问题的目的是让学生认识到,微控制器必须通过指示灯闪烁指令“循环”。实际上,这只是实际环境中循环的一个示例。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
一个学生决定用一个微控制器做一个闪光电路。只有按钮开关被按下时,LED才会闪烁。当开关被释放时,它应该关闭:
|
伪代码清单声明Pin0为输出
声明Pin1为输入
而Pin1是高的
设置Pin0高
暂停0.5秒
将Pin0设置为低
暂停0.5秒
ENDWHILE
当MCU上电或复位时,只要按住按钮开关,LED就可以正常闪烁。一旦开关被释放,LED关闭,永远不会回来。如果在启动过程中没有按下开关,则LED永远不会亮!解释发生了什么,并根据需要修改程序来解决这个问题。
条件式“WHILE”循环需要放在无条件循环中:
伪代码清单声明Pin0为输出
声明Pin1为输入
循环
而Pin1是高的
设置Pin0高
暂停0.5秒
将Pin0设置为低
暂停0.5秒
ENDWHILE
ENDLOOP
后续问题:电阻器R的用途是什么下拉在按钮电路中使用?
这个问题的目的是让学生理解一个“WHILE”循环在实践中代表什么:一个有条件的循环。它还对比了条件循环和无条件循环,并展示了这两种循环在交互系统中是如何发挥作用的。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果Pin1高,则将Pin0设置为高
否则,如果Pin2为高电平,则将Pin0设置为高电平
否则将Pin0设置为低
ENDIF
ENDLOOP
该微控制器实现逻辑OR功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果“Pin1”为“LOW”,则设置“Pin0 LOW”
ELSEIF Pin2为LOW,设置Pin0为LOW
ELSE设置Pin0 HIGH
ENDIF
ENDLOOP
该单片机实现了逻辑与功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果Pin1为LOW,则设置Pin0为HIGH
ELSEIF Pin2为LOW,设Pin0为HIGH
否则将Pin0设置为低
ENDIF
ENDLOOP
该微控制器实现了逻辑与非功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果Pin1高,则将Pin0设置为低
ELSEIF Pin2为HIGH,设Pin0为LOW
ELSE设置Pin0 HIGH
ENDIF
ENDLOOP
该单片机实现了逻辑NOR功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果Pin1和Pin2相同,则将Pin0设置为LOW
ELSE设置Pin0 HIGH
ENDIF
ENDLOOP
该单片机实现了逻辑异或功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
A.微控制器是一种专用的数字计算机,用于提供系统的自动排序或控制。微控制器与普通数字计算机的不同之处在于它非常小(通常是一个集成电路芯片),有几个专门用于数字信号输入和/或输出的引脚,并且内存有限。编入微控制器存储器的指令告诉它如何对输入条件作出反应,以及向输出输出什么类型的信号。
被微控制器“理解”的最简单的信号类型是一个离散的电压水平:在芯片上指定的引脚上测量“高”(约V)或“低”(约地电位)。微控制器内部的晶体管在输出管脚产生这些“高”和“低”信号,为了简单起见,它们的动作被SPDT开关模拟:
|
它不需要太多的想象力来想象微控制器如何在实际系统中使用:根据输入引脚和/或时间条件打开和关闭外部设备。例子包括家用电器控制(烤箱计时器、温度控制器)、汽车发动机控制(喷油器、点火定时、自我诊断系统)和机器人技术(伺服驱动、感觉处理、导航逻辑)。事实上,如果你生活在一个工业化国家,你可能拥有几十个微控制器(嵌入各种设备中),而你甚至没有意识到它!
然而,微控制器的实际限制之一是其低输出驱动电流限制:通常小于50 mA。微控制器内部电路的小型化禁止包含具有任何重要额定功率的输出晶体管,因此我们必须将晶体管连接到输出引脚,以驱动任何重要负载。
假设我们希望有一个微控制器驱动一个直流电磁阀,需要2安培的电流在24伏特。一个简单的解决方案是使用NPN晶体管作为微控制器和电磁阀之间的“插入”设备,就像这样:
|
不幸的是,单个BJT不能提供足够的电流增益来启动电磁阀。微控制器引脚的输出电流为20 mA,β值仅为25(功率晶体管的典型值),这仅为电磁线圈提供约500 mA的电流。
解决这个问题的方法是在一个达灵顿对安排:
|
然而,还有另一种解决方案-用单个MOSFET替换单个BJT,这根本不需要驱动电流。说明如何做到这一点:
|
|
这个冗长的问题的目的不仅仅是让学生弄清楚如何用MOSFET替换BJT,而且还向他们介绍了微控制器的概念,这是现代电子系统中越来越重要的一种设备。
有些学生可能会问这个电路中二极管的用途。向他们解释这是整流二极管,有时称为续流二极管,以防止晶体管因电磁线圈在断电时产生的高压瞬变而过应力(“电感反冲”)。
微控制器用于为交流负载提供自动功率因数校正:
|
检查此示意图,然后回答以下问题:
我将让你和你的同学讨论MCU如何检测功率因数。有不止一个有效的解决方案!
20μF和80μF电容器都将接通:MCU输出DCBA将接通0101(注意,输出必须输出低为各自的继电器通电!)。使用此输出,校正后的功率因数将为0.99939,而不是原来的0.77。
这个问题提出了一些有趣的概念供复习,同时也综合了电子领域的新旧概念供学生思考。yabosports官网一定要留出足够的时间来讨论这个问题,也要留出必要的复习时间来计算功率因数!
该微控制器通过对引脚0的输出进行脉宽调制(PWM)控制来改变LED的感知亮度:
|
伪代码清单声明Pin0为输出
声明X为整型变量
循环
将Pin0设置为低
暂停100 - X微秒
设置Pin0高
暂停X微秒
ENDLOOP
确定X必须将LED的亮度设置为80%,以及PWM信号的频率。
这个问题最好的答案可能是画一个引脚0输出的时序图,并记下输出的时间100 - Xμs与Xμs。
后续问题:鉴于以下情况,此PWM控制的分辨率是多少X是整型变量吗?如何提高PWM控制方案的分辨率?
脉宽调制(PWM)是一种非常常见和有用的方式产生模拟输出的微控制器(或其他数字电子电路)只能“高”和“低”电压水平的输出。对于PWM,时间(或者更具体地说,占空比)是模拟域,而振幅是数字域。这允许我们通过数字(开关)数据通道“偷偷地”发送模拟信号。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
许多微控制器都配备了内置的PWM功能,所以你不必自己编写定制的PWM算法。这一事实表明脉宽调制作为一种控制方案的流行。解释为什么PWM如此流行,并给出几个如何使用它的实际例子。
我让你自己研究这个问题!答案不难找到。
脉宽调制(PWM)是一种非常常见和有用的方式产生模拟输出的微控制器(或其他数字电子电路)只能“高”和“低”电压水平的输出。对于PWM,时间(或者更具体地说,占空比)是模拟域,而振幅是数字域。这允许我们通过数字(开关)数据通道“偷偷地”发送模拟信号。
脉宽调制(PWM)不仅对微控制器产生模拟输出有用,而且对通过只处理开关(高-低)数字电压电平的引脚接收模拟输入也有用。下面的电路将一个模拟电压信号输入比较器,产生PWM,然后将该PWM信号发送到单片机的输入端:
|
伪代码清单声明Pin0为输入
将Last_Pin0声明为布尔变量
声明Time_High为整数变量
声明Time_Low为整数变量
将占空比声明为浮点变量
将Time_High和Time_Low都设置为0
循环
将Last_Pin0设置为Pin0
如果Pin0为HIGH,则Time_High加1
如果Pin0为LOW,则Time_Low加1
如果Last_Pin0不等于Pin0,则转到子程序
ENDLOOP
子例程
将占空比设置为(时间高/(时间高时间低))
将Time_High和Time_Low都设置为0
返回到调用循环
ENDSUBROUTINE
解释这个程序是如何工作的。提示:Last_Pin0布尔变量用于检测状态Pin0已从0更改为1或从1更改为0。
这个计划最棘手的部分是找出Last_Pin0变量的函数,以及它如何决定何时执行子例程。我强烈建议你用缓慢的方波输入信号来做一个“思想实验”,检查微控制器如何Time_High和Time_Low变量随着方波的状态而增加。
脉宽调制(PWM)是一种非常常见和有用的方式产生模拟输出的微控制器(或其他数字电子电路)只能“高”和“低”电压水平的输出。在这里,我们也看到它被用作输入信号调制。对于PWM,时间(或者更具体地说,占空比)是模拟域,而振幅是数字域。这允许我们通过数字(开关)数据通道“偷偷地”发送模拟信号。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
数字计算机通过港口:一组终端,通常按4、8、16或更多的分组排列(4位= 1)奈布尔, 8位= 1字节, 16位= 2字节)。通过为计算机编写程序,向端口发送一个数值,这些终端可以设置为高或低逻辑状态。例如,这里有一个微控制器被指示发送十六进制数的例子F3至A港及2摄氏度到端口B:
|
假设我们希望使用端口A的上四位(引脚7、6、5和4)来驱动步进电机的线圈,按以下八步顺序:
当每个引脚走高,它驱动功率MOSFET,这发送电流通过各自的线圈的步进电机。通过遵循一个“移位”序列,如图所示,电机将为每个周期旋转少量。
写发送到端口A的必要的数字序列,以产生这个特定的位移顺序,十六进制。让端口A的低四位都处于低逻辑状态。
后续问题:用十进制而不是十六进制写相同的序列:
虽然这个问题的根源只是二进制到十六进制的转换,但它也向学生介绍了通过写入十六进制值来控制微机端口位状态的概念。因此,这个问题是非常重要的非常实用!
如果学生问,让他们知道美元符号前缀有时用来表示十六进制数。其他时候,使用前缀0x(例如,$F3和0xF3表示相同的东西)。
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1和Pin2为输入
循环
如果Pin1与Pin2相同,则将Pin0设置为高
否则将Pin0设置为低
ENDIF
ENDLOOP
该单片机实现了逻辑异或功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
数字计算机通过港口:通常按4、8、16或更多分组排列的一组终端。通过为计算机编写程序,向端口发送一个数值,这些终端可以设置为高或低逻辑状态。例如,这里有一个微控制器被指示发送十六进制数的例子2 b至A港及A9到端口B:
|
假设我们希望使用每个端口的前七位(引脚0到6)来驱动两个7段公共阴极显示器,而不是使用BCD到7段解码器IC:
|
写入需要在端口A和端口B上输出的十六进制值,以在两个7段显示单元上生成显示“42”。
端口A = 5B16端口B=6616
请注意,以下答案也是有效的:
端口A = DB16端口B=E616
后续问题:用十进制而不是十六进制写出相同的数值。
这个问题的根源只不过是二进制到十六进制的转换,但它也向学生介绍了通过写十六进制值来控制微机端口中的位状态的概念。因此,这个问题是非常实用!虽然在构建两位数十进制显示器时,不太可能有人会忽略BCD到7段解码器(因为这样做会使用更多珍贵的微控制器I/O引脚),但这肯定是可能的!除此之外,还有许多应用程序需要微控制器输出特定的高、低状态组合,编程的最快方法是将十六进制值输出到端口。
如果学生问,让他们知道美元符号前缀有时用来表示十六进制数。其他时候,使用前缀0x(例如,$F3和0xF3表示相同的东西)。
在基于网格的显示器中驱动像素的一种方法是将像素组织成行和列,然后通过特定行线和特定列线的交点选择用于照明的单个像素。在这个例子中,我们用一个微控制器的两个8位(1字节)端口控制一个8 × 8的led网格:
|
请注意,高在端口B的一个引脚上需要状态才能激活行,而a低因为LED阳极连接到端口A, LED阴极连接到端口B,所以需要在端口A的一个引脚上激活一个柱。
确定我们需要在端口A和B输出的十六进制代码,以激活位于8 × 8网格左下角的LED。
港口一个=
B港=
端口A = $FE
B港= 80美元
检查下面的原理图和程序列表(用“伪代码”而不是正式的程序语言编写的),以确定在这个微控制器单元中实现了什么类型的基本逻辑功能:
|
伪代码清单声明Pin0为输出
声明Pin1、Pin2和Pin3为输入
循环
如果Pin1高,则将Pin0设置为高
否则,如果Pin2为高电平,则将Pin0设置为高电平
ELSEIF Pin3为HIGH,设Pin0为HIGH
否则将Pin0设置为低
ENDIF
ENDLOOP
该微控制器实现3输入逻辑OR功能。
虽然这种逻辑功能在硬接线(门)逻辑中可以更容易、更便宜地实现,但其目的是让学生考虑通过可编程设备(MCU)内的一组顺序指令执行逻辑操作。这是一个概念上的飞跃,基本但非常重要。
如果你想知道我为什么要写伪代码,这里有几个原因:
如果我决定展示将在微控制器中实际运行的代码,我将把问题归结为过时。通过这种方式,我可以传达程序的精神,而不必与实际的编程标准挂钩。唯一的缺点是,学生必须将我的伪代码转换为实际运行在特定MCU硬件上的真实代码,但这对于某些人来说是一个问题,无论我选择哪种真实编程语言。
当然,我可以采用Donald Knuth的方法,发明我自己的(想象的)硬件和指令集。
一个学生构建了一个微控制器电路,输入开关每五个动作就会打开一个LED。电路很简单,微控制器使用条件循环,每次按下开关时增加一个变量:
|
伪代码清单声明Pin0为输出
声明Pin1为输入
声明X为整型变量
循环
而Pin1是高的
把1加到X (X=X 1)
ENDWHILE
如果X等于5,则将Pin0设置为高,并将X设置为0
否则将Pin0设置为低
ENDIF
ENDLOOP
不幸的是,程序没有按照计划执行。不是每五个开关触发一次LED,而是当开关被释放时随机触发。有时,LED在第一次开关启动后就打开了,而其他时候,需要超过5次的推开关才能打开。
经过仔细分析,学生意识到问题在于虽然循环。由于微控制器比人手快得多,当开关被按下时,循环会执行多次,而不是一次,这意味着变量X从0到5多次计数,每个开关驱动。那么,这只是偶然的X将等于5后虽然循环出口。
学生需要的是开关仅在开关从断开到接通转换时增加1:在积极的边缘输入脉冲。问题是如何使用编程来做到这一点。
另一个学生在面对同样的问题时,选择了这种方法,而且效果很好:
伪代码清单声明Pin0为输出
声明Pin1为输入
将开关声明为布尔(0或1)变量
将Last_Switch声明为布尔(0或1)变量
声明X为整型变量
循环
将Last_Switch设置为Switch
设置Switch = Pin1
如果开关=1且最后一个开关=0,则将1添加到X(X=X 1)
否则对X什么都不做
ENDIF
如果X等于5,则将Pin0设置为高,并将X设置为0
否则将Pin0设置为低
ENDIF
ENDLOOP
解释这个程序是如何成功递增的X当其他程序递增时,仅打开按钮开关的每个off到on转换X在整个持续时间内,按钮开关被迅速地按下。
理解这种算法如何工作的关键是实现变量Last_Switch总是一个扫描(循环执行)后面的变量开关.
挑战问题:以下两行在程序中的位置重要吗?它们必须放在IF/THEN条件语句之前吗?
将Last_Switch设置为Switch
设置Switch = Pin1
这种脉冲检测算法在处理实际开关输入的程序中非常常用。它在软件中执行的功能就像脉冲检测网络在边缘触发触发器内部所做的一样,具有相同的效果:只在脉冲信号的边缘启动某种动作。