FMBomb - 初学者硬件编程方法
使用PIC微控制器的一个入门级硬件项目。
最新更新
只是一个简单但有趣的更新。添加了一个带前置放大器的驻极体麦克风,直接连接到FM发射器。现在你可以通过无线电波广播你的声音。无需固件更改。
引言
在这篇文章中,我想带你了解创建自己的硬件项目的过程。我希望它可以作为一个例子,说明硬件开发对于那些足够聪明、已经懂得如何编程的人来说,可以是一个平易近人且有趣的爱好。
免责声明:这是一篇入门文章,因此,我没有使用或解释一些硬件构建的最佳实践,因为它们超出了本文的范围。我追求的是快速和简单。
消除硬件恐惧
所以,我马上想解决一些人们不愿将硬件作为爱好的主要原因,并希望能说服你。通过与人们交流,我发现软件从业者不接触硬件主要有五个原因。
- 缺乏所有电气知识
- 成本
- 令人畏惧的汇编和C语言编程
- 害怕触电或烧毁东西
- 缺乏兴趣
让我简要分享一下我对每个问题的看法,然后我们再进入正题。如果你不想听我关于这些问题的啰嗦,请随时跳到正题。我不会介意。
缺乏所有电气知识
我拥有电气工程学士学位,所以我对此略知一二,但我大部分学位都是在解决傅里叶变换、创建PID控制器以及从头构建运算放大器。当然,这些知识很有帮助,但我大学里从未接触过微控制器。我所有的微控制器知识都是在地下室工作时自学的。这只需要一些努力和一点耐心。你足够聪明,可以弄明白这些。相信我。
成本
好的,我们都知道一旦有了电脑,编写软件基本上是免费的(顺便问一下,电脑花了多少钱?)。软件工具对业余爱好者免费,而且你可以在不花钱的情况下完成很多事情。在这方面我们无能为力。硬件零件需要花钱,但大多数固件开发工具是免费的,而且零件的价格比你想象的要便宜。而且请记住,在许多情况下,你可以从你阁楼里积满灰尘的旧电子设备中拆卸零件,赋予它们新的生命。
令人畏惧的汇编和C语言编程
你可以跳过汇编,但如果你想编写任何固件,你还是需要了解一些C语言。你不是学过Java吗?或者C#或Ruby?如果你是一个不错的程序员,你就可以学会为微控制器编写C语言代码。这并没有那么难,你甚至可能学到一些可以应用到你其他喜欢的语言的宝贵技能。有一些平台支持.NET Framework,但大多数仍然使用C语言。就个人而言,如果我在 tinkering 时犯了错误,我宁愿烧掉一个2美元的PIC,而不是一个更贵的.NET开发板。
害怕触电或烧毁东西
好的,我在此声明,您应自行承担风险。玩弄电力和烙铁会造成伤害,损坏您和您的物品,物品可能着火,以及您已经听过的所有法律声明,我不想对您烧毁任何东西负责。但是,我将大胆地忽略法律条文一秒钟,并建议在大多数小型电子项目中,我们处理的是无害的低电压和低电流。如果您不小心,最坏的情况可能会受到一点点电击,仅此而已。至于烧毁东西,我们处理的是一个2美元的芯片。如果烧毁了,再拿一个。我们都至少会经历一次。我做这个已经很多年了,可以告诉你,如果你运用常识和谨慎,如果不确定就去谷歌一下,你就能保住你的手指、脚趾和眉毛。话虽如此,请小心,但请尽量享受乐趣。
缺乏兴趣
这方面我帮不了你。也许你点错了文章链接。
要点
那么我的主要观点是什么?学习创建硬件项目就像学习编程一样;它需要耐心、大量的努力和时间,并且有一个学习曲线。然而,与生活中大多数需要这些先决条件的事情一样,当你能够制作出半成品并展示给你的朋友看时,这是非常有成就感的。他们可能不在乎,但那只是因为他们嫉妒你高超的硬件技能。
项目是什么?
每个人都做LED闪烁的事情,但这很无聊,而且对我来说太初级了。我猜没有多少人蜂拥到硬件领域来让LED闪烁。当然,第一次看到那个闪烁得刚刚好时,会让人兴奋不已,但我们也想做一些酷炫的事情。希望这篇文章能向你展示,即使不是电气工程师,你也能做出酷炫的东西。
那么FMBomb是什么?基本上,它就像你的iPod车载插孔,让你可以在车内收音机上收听音乐,通过在一个你的收音机可以接收的FM频道上广播声音,只不过你是在构建硬件。为什么叫FMBomb?不确定,这是我第一个想到的名字。请记住,这个项目中使用的方法和原理可以应用于更广泛的想法。那些在你脑海中盘旋的想法,所以尽量看到大局。我会尽力帮助你。
告诉我需要什么
所以这个项目的材料清单非常简单,而且相当实惠。
零件 | 注释 |
PIC16F688 | 可从Microchip获取样品 |
NS73M breakout板 | 可从Sparkfun获取 |
连接线 | 用于连接所有东西 |
4.7KΩ电阻 | |
1.0KΩ电阻 | |
LED | 任何颜色都可以 |
现在,关于工具,我们将使用以下工具
- MPLAB IDE (免费)
- HI-TECH C 编译器 (免费)
- Pickit3 编程器 (~45美元)。拥有一个之后,您可以编程任何PIC。
- 面包板
- 基本的硬件用品,如剥线钳(或牙齿)、钳子、连接线等。
注意:本文并非Microchip产品的推广。我使用Microchip微控制器和工具是因为我熟悉它们。您可以使用任何品牌的微控制器和相应的工具。基本概念都是相同的。
项目的“大脑”
我决定在此项目中使用PIC 16F688微控制器,原因是我抽屉里有很多。你们大多数人可能没有,但它们非常便宜。事实上,如果你有兴趣购买几个,16F688可以从Microchip获取样品。我在我的另一篇文章中略微提到了微控制器,所以请移步那里获取一些背景知识,这样我就不必在这里重复了。基本上,微控制器将是我们项目的“大脑”。固件在那里运行,并且所有其他组件都连接到它。
重要硬件概念#1:数据手册是你的朋友。任何关于任何组件的你需要知道的一切都会在它的数据手册中写明。16F688(下称PIC)的数据手册有204页。不要害怕,我们不需要全部读完,只需读我们关心的部分。对于几乎任何微控制器,你总是需要知道的第一件事是如何设置配置寄存器。它们类似于电脑的BIOS设置。它们告诉微控制器在启动时如何工作。例如,时钟信号来自哪里,某些引脚在默认情况下应如何工作等。如果你没有正确设置这些,你将花费大量时间猜测为什么东西不起作用。我在代码中详细记录了这些设置。接下来要记住的是,每个引脚都有不同的功能,你可以选择每个引脚的功能,例如,输入引脚、输出引脚、外部时钟信号、比较器输入等。所有这些都在数据手册中,并且非常容易配置。好了,这不是微控制器讲座,我们继续。
步骤1:硬件设置
在软件中,当我们想创建一个新项目时,我们必须执行文件->新建或其他类似操作来开始。在硬件中,在我们编写任何固件之前,必须进行一些基本的硬件组装。微控制器运行需要两样东西:
- 电源,和
- 时钟源。
从PIC数据手册中,我们知道有一个内部振荡器(时钟源)可以作为时钟,并且根据数据手册(第144页),PIC的电源可以在2V到5.5V之间。串联2节AA电池(3.0V)就可以工作,或者使用旧电子设备的DC电源适配器。我使用的是一个输出3.3V的电源适配器。所以,让我们设置一下我们目前拥有的东西。(我还包含了Pickit3编程器的连接。这些仅用于将固件映像传输到设备上。这包括连接在引脚1和4之间的4.7K电阻。)
很简单,是吧?现在,我们如何知道我们的固件是否正确加载?我们需要一个可以从固件控制的指示器,以告知我们一切是否正常工作。LED怎么样?现在这需要一些电气知识。我们可以用微控制器的某个引脚(配置为输出)为LED供电,但我们需要串联一个电阻,以免烧毁LED。电阻“抵抗”电流的流动,这样就不会有太大的电流流过LED并将其烧毁。重要硬件概念#2:不知道就谷歌。我搜索了“连接LED”,排名第一的结果告诉了您连接LED到电源所需的一切。在我们的例子中,电源将是PIC的输出引脚。所以现在我们的原理图看起来是这样的
步骤2:编写一些固件
任何PIC项目的首要任务是在MPLAB中创建一个新项目,就像你在<在此插入您最喜欢的IDE>中做的那样。我不想用IDE说明来稀释这篇文章,所以请阅读它的快速入门指南。基本上,我们是创建一个新项目,并告诉IDE我们的设备是PIC16F688。
就像你在电脑上编写C程序一样,固件将在main()
函数中开始执行。不过,在此之前,我们需要如上所述设置配置寄存器。数据手册的第111页告诉我们配置数据两个字节中每个位代表什么。我们以此为指南进行设置。有关更多详细信息,请参见注释掉的代码,但这就是_CONFIG()
宏的样子
__CONFIG(FCMDIS & IESODIS & BORDIS & UNPROTECT & MCLREN & PWRTDIS & WDTDIS & INTIO);
现在我们准备编写主函数了。让我们从一个简单的东西开始,用LED来测试我们的设置。
void main(void)
{
// Wait for the power supply to settle. This is always a good idea to do
// at startup.
__delay_ms(10);
// From the datasheet we know that if we want certain pins to be
// digital inputs instead of analog inputs that we need to set the
// ANSEL and CMCON0 registers. The following settings make all
// pins digital.
ANSEL = 0;
CMCON0 = 0x07;
// The internal oscillator we're using defaults to 4MHz on startup
// You can confirm this on page 22 of the datasheet. If we wanted
// we could change the frequency here to something else. For our
// purposes we'll just leave it.
// Setup pin 7 (RC3) to be an output so we can drive the LED with it.
// Remember, setting the TRIS bit to a 1 makes a pin an input and a 0 sets
// it as an output. Think 1 is like I so Input. 0 is like an O so Output.
TRISC3 = 0; // This tells the pin to be an output
RC3 = 0; // This sets the initial state to 0V.
while(1)
{
RC3 = 1; // Turn the LED on
_delay_ms(1000); // Delay for a second
RC3 = 0; // Turn the LED off
_delay_ms(1000); // Delay for a second
}
}
这真的很简单。项目除了HI-TECH编译器安装提供的标准htc.h文件外,没有其他文件。我没有隐藏任何东西。这就是全部。我们将一个引脚设置为数字输出,然后在无限的while(1)
循环中将其打开和关闭,以闪烁LED。我们使用MPLAB将编译器创建的.hex文件编程到我们的设备中,我们就得到了一个闪烁的LED。因此,我们知道微控制器已正确连接,并且正在接收我们发送给它的固件。现在我们准备添加主要功能了。
步骤3:让你的FM节奏飞起来
在这个项目中,我们将使用NS73M FM发射器。Sparkfun Electronics销售该组件及其breakout板版本,因此很容易在面包板上进行原型开发。我使用了breakout板,因为它已经焊接了使发射器工作的两个外部组件。重要硬件概念#3:预封装组件太棒了。当然,我们可以从头开始构建一个FM发射器,但既然可以插入一个别人已经构建和测试过的模块,为什么还要费力呢?这就像编写软件一样。当然,你可以为.NET编写自己的日志框架,但除非你真的需要特定的功能,否则在大多数情况下,像NLog或log4net这样的预封装库都能很好地工作。用计算机的术语来说,可以把这些模块看作是你需要为其编写驱动程序的外围设备。听起来很难,但你会发现这真的不是那么糟糕。连接它,供电,然后开始与之通信。我们将用于连接FM发射器的概念适用于连接几乎任何外部模块,如Wi-Fi、LCD、传感器。所有这些都可以作为外部模块连接到你的微控制器上,添加到你的项目中。
连接起来
我们装有发射器的breakout板有很多连接需要做。一切都已在数据手册中说明。从NS73M数据手册(第4页)可以看出,模块能承受的最大供电电压是3.7V。这在我们PIC的供电范围内(2-5.5V),所以我们可以共享3.3V电源适配器的电源给PIC和发射器模块。一旦所有东西都连接好,就剩下编写固件来与模块通信并使其开始传输了。我们的硬件组装完成了,最终的样子是这样的
与发射器模块通信
在NS73M数据手册中,我们学到了两件重要的事情。第一,所有与模块的通信都是以命令包的形式进行的,第二,这些包可以通过两种方式发送:3线SPI,或I2C协议。许多微控制器内置了I2C外设,但我们的PIC没有,所以我们将使用SPI方法。幸运的是,NS73M数据手册也精确地说明了该协议应如何实现。发送给模块的每个数据包由4位组成,指定一个寄存器地址,然后是存储在该地址的数据字节。模块的操作由所有寄存器中的值决定。数据手册的第8页显示了SPI通信协议的样子。
我详细注释了本文附带的固件源代码,以便您在那里获得更多细节,但基本上,当信号线为高电平时,我们在固件中将其引脚设置为1。当它为低电平时,我们将其设置为0。所以,让我们在固件中添加一个例程来处理向模块发送数据包。(出于篇幅原因,我删除了部分注释。您可以在代码中找到完整版本。)
void SendCommand(char address, char data)
{
char x;
// The clocking diagram shows that the LA pin needs to be
// low until the data has all been sent so lets set it to
// zero here.
LA = 0;
// The first thing we need to send is the 4 address bits
for(x = 0 ; x < 4 ; x++)
{
CK = 0;
DA = address & 0x01;
// This is a trick for getting the value of the LSB
// Rotate 1 bit to the right. This rolls the LSB to the right
// and makes the second bit the LSB
address >>= 1;
CK = 1;
}
// Now that the address bits have been sent let's send the data
for(x = 0 ; x < 8 ; x++)
{
// We'll follow the exact same pattern as seen with the
// address bits
CK = 0;
DA = data & 0x01;
data >>= 1;
CK = 1;
}
// From the diagram we see that once all bits have been
// sent we need to latch the transfer by setting LA
// high. From the table on page 9 we see that we need
// to hold that line high for a minimum of 250 ns so
// we'll use a 1 ms delay for good measure before setting
// LA back to zero.
LA = 1;
__delay_ms(1);
LA = 0;
}
有了这个,我们就可以设置寄存器中的值,让发射器听从我们的指挥。我如何知道要向寄存器写入什么?对了,看看NS73M数据手册。你可以在代码中找到我的示例设置。一旦你完成了这些,你就完成了。给它供电,将你的收音机调到你在固件中设置的FM频道,然后惊叹于你的能力。
添加语音
在收音机上播放你的iPod音乐很有趣,但广播你的声音更有趣。给电路添加语音功能是一个很好的例子,说明了如何轻松地为嵌入式项目添加功能。无需固件更改,整个升级过程,包括将 breakaway header 焊接到麦克风breakout板上,我花了大约20分钟。我立刻将家里所有的收音机调到我的预设传输频率,然后开始从我的地下室巢穴对着家人说话。用一根简单的30英寸连接线天线,传输范围相当不错。为了再次强调数据手册的原则,我在数据手册的第3页发现,运算放大器可以用2.7V至5.5V供电,这在我们供电范围内。接下来该添加什么?
结论
就这样。我知道这篇文章有点长,感谢您能坚持到最后。如果有什么不清楚的地方,或者您有一般性问题,请在下面的评论中提交。我试图证明,通过一些简单的硬件和相当简单的固件,我们可以实现一些非常不错的东西。我详细注释了代码,所以我鼓励您仔细查看。从这里开始,您可以根据自己的需要修改固件。也许你可以添加一个按钮,按下时可以调到下一个FM频道,或者添加一个LCD来显示你正在传输的频率信息。添加一个实时时钟和日历模块,并编程您的设备在每天的特定时间开始广播,并在稍晚的时间停止广播。任何你能想到的。
如果您觉得这篇文章很有趣,并希望看到一些改进或后续文章,请告诉我。我维护着Embedded Fun博客,我时不时会在那里发布内容。它包含指向GitHub上此项目源代码的链接。您可以在那里或本文底部发表评论。我会尽力做出回应。
这就来到了重要硬件概念#4:你确实可以搞定这些。试一试,玩得开心。你很快就能建造出钢铁侠的战甲。
历史
- 2011/1/11 - 原始文章。
- 2011/3/24 - 在电路中添加了带前置放大器的麦克风。