索引
一、 回顾
首先回顾一下我们的板子———
看完了Part 1的部分,是不是对我们即将开展的实验充满期待?那话不多说,实验立刻开始!
二、做实验!
2.1、Exercise 1
首先看一下实验要求:
Exercise 1 - Switching on and off a pair of LEDs
a. Select two LEDs from the parts available in the lab – one should be a red LED and the other should be a green LED.
b. Use the breadboard to connect the mbed and the LEDs. Connect the anode of the red LED to digital-pin 5 (D5) on the mbed and the cathode to ground. The anode of the LED has the longer leg while the cathode has the shorter leg. Connect the anode of the green LED to digital-pin 6 of the mbed board and the cathode to ground.
c. Based on what you have learned above, and with reference to the DigitalOut page on the mbed website, generate code that will cause the LEDs to switch on and off, where the red LED is ON while the green LED is off and visa versa. The duration of illumination of each LED should be 1 second.
简单来讲就是让我们用mbed控制绿色和红色的二极管轮流点亮,每个持续时间为一秒。
在MS中,物理功能的实现主要靠各种头文件下的函数(包括自定义的)来实现。下面让我们来学习一下实验一中用到的各种部分。
代码 | 功能 |
---|---|
#include “mbed.h” | 头文件,内置许多已经定义好的库函数,作用等同之前所学<stdio.h> |
DigitalOut "variablename”(“pin number”); | DigitalOut表示数字输出,用于定义一个向外进行数字输出数据的引脚。如DigitalOut myled(D5),表示定义了一个名为myled的可以输出数字信号的引脚,位置在D5;DigitalOut myled(LED1)表示定义了一个名为myled的可以输出数字信号的引脚,若输出高电平则LD3亮 |
int main() { | main函数,作用同C语言中的int main(void) |
while(1) { | 同C语言,表示无限循环 |
myled=1&myled=0; | 让之前定义的引脚myled输出高电平(3.3V)或低电平(0V) |
wait(“time”); | 保持此刻状态,维持time时长(单位:秒),如wait(0.2);表示持续0.2秒 |
话不多说,直接上代码:
#include "mbed.h"
// main() runs in its own thread in the OS;
DigitalOut red_led(D5); //定义红灯引脚
DigitalOut green_led(D6); //定义绿灯引脚
int main()
{
while (1)
{
red_led = 1; //将红灯点亮,拉至高电平
green_led = 0; //将绿灯熄灭,保持低电平
thread_sleep_for(1000); //维持当前状态1000ms
red_led = 0;
green_led = 1;
thread_sleep_for(1000);
}
}
有的同学在使用wait函数时可能会报错,这里建议直接使用thread_sleep_for函数
void thread_sleep_for(std::uint32_t millisec) //单位为毫秒
//Sleep for a specified time period in millisec:
这里将D5、D6作为两个二极管供电的来源,接阳极;同时阴极接GND(二极管长脚为阳极,短脚为阴极)。
2.2、Exercise 2
首先题目给出了一段代码:
#include "mbed.h"
DigitalOut redled(D3);
DigitalOut greenled(D4);
DigitalIn switchinput(D5);
int main()
{
while (1)
{
if (switchinput == 1)
{ // test value of switch input
// execute following block of code if switch input is 1
greenled = 0; // green LED is off
redled = 1; // flash red LED
wait(1.0);
redled = 0;
wait(1.0);
} // end of if
else
{
// execute this block of code if switchinput is 0
redled = 0; // redled is off
greenled = 1; // flash green LED
wait(1.0);
greenled = 0;
wait(1.0);
} // end of else
} // end of while(1)
} // end of main
这里出现了一个新的函数
代码 | 功能 |
---|---|
DigitalIn switchinput(“pin number”); | 类似DigitalOut,只不过为读取输入的电平值 |
class DigitalIn {}: A digital input, used for reading the state of a pin
代码很简单,就是通过判断switchinput上的电平情况来输出。
PWM方波
题目中还要求输出Pwm方波,这里需要使用PwmOut函数:PwmOut switchinput(“pin number”);‘
这里需要我们找到支持Pwm的针脚(如D5)接入;
PwmOut test(D5);
...
test.period_ms(1); //频率1kHz
test.write(0.5); //占空比50%
...
这里的period_ms和write函数分别设置方波的周期和占空比。来看声明:
public: void period_ms(int ms):Set the PWM period, specified in milliseconds (int), keeping the duty cycle the same.
public: void write(float value):Set the output duty-cycle, specified as a percentage (float). The value should lie between 0.0f (representing on 0%) and 1.0f (representing on 100%). Values outside this range will be saturated to 0.0f or 1.0f.
这里介绍一下占空比:占空比(Duty Ratio)是指在一个脉冲循环内,通电时间(高电平)相对于总时间所占的比例。比如说这里设置频率1kHz,占空比为50%,则高电平所占时间就为1ms*50%=0.5ms。
2.3、Exercise 3
第三个实验需要我们使用74HC4066。先来看看题干:
Exercise 3 - Create a square wave whose frequency depends on the position of a switch
The 74HC4066 is a quad (4) SPST analog switch. Each switch features input pin (Y) and output pin (Z) and an active HIGH enable input (E). For instance, for switch 1, input pin is labelled as 1Y, output pin is labelled as 1Z and the enable pin is labelled as 1E. After connecting Vcc and GND to the power supply, when enable pin E is LOW, the analog switch is turned off. By contrast, when enable pin E is HIGH, the analog switch works as a normal switch. Please refer to the truth table above for all the possible configurations.
Modify Program 2 above so that it will output one of two possible frequencies, 200 Hz and 500 Hz depending on the position of a switch (ON or OFF), which you will wire to one of the input pins on your mbed.
查阅4066的datasheet以及真值表
Input | Input | Input | Output |
---|---|---|---|
Vcc | E(1,4,8,11) | Y(13,5,6,12) | Z(2,3,9,10) |
0 | x | x | 0 |
1 | 0 | x | 0 |
1 | 1 | 0 | 0 |
1 | 1 | 1 | 1 |
不难发现整个元件由4个与门(AND)构成,只有Vcc,E,Y全为高电平,输出端Z才输出高电平。
因此我们可以选取一组,将其中2个接入3V3,就可以只控制余下一个来控制输出了。随后结合Exercise 2,分别写一个输出200Hz和500Hz的波即可完成。
2.4、Exercise 4
先看题目
Exercise 4 – Multiplexing/Demultiplexing
a. Connect the anodes of 4 LEDs to the outputs of the 2 x 4 demultiplexer.
b. Connect the cathodes of the LEDs to ground.
c. Connect the power and ground to the demultiplexer.
d. Write a program to use the output from 2 pins on the microcontroller to turn ON and OFF the LEDs in a sequence.
在实验4中,我们要用到MAX4628多路选择器(demultiplexer)。先来看引脚:
其中X0-X3,Y0-Y3为输出引脚;ENABLE为使能引脚(使之开始工作);A、B为输入引脚,控制输出;X 、Y、Vcc接3V3,GND接地,其余不用管~~
参考datasheet,再来看看它是怎么控制哒
*注[1]:L表示低电平(Low),H表示高电平(High);
[2]:MAX4618上没有C,不用管;
A、B各有两种情况,由排列组合知识可知排列后一共有2*2=4种对应。如果使用X0-X3,便有如下对应
A | B | pin for high |
---|---|---|
0 | 0 | X0 |
1 | 0 | X1 |
0 | 1 | X2 |
1 | 1 | X3 |
将X0-X3分别接入四个二极管,这样只需控制A、B两个引脚便可控制二极管的亮灭。
2.5、Exercise 5
这是一个颇为有意思的实验,题目要求我们使用七段数码管显示相应数字或字符。
Exercise 5 - Drive a seven-segment display to display 0-9 and a word H E L P repeatedly
In program 1 you switched ON and OFF a pair of LEDs. LEDs are often packaged together to form patterns, digits, alphanumeric characters etc. A number of standard groupings of LEDs are available including a seven-segment display, which is composed of seven individual LEDs that can be used to display all numerical digits along with quite a few letters from the English alphabet by lighting different combinations of the seven LED segments.
首先介绍一下数码管。
整个数码管由8段LED组成,每个LED由一个引脚控制(见右图);同时引脚3和8为接地引脚。引脚1-5位于下方,引脚6-10位于上方。
BusOut函数
同时在这里我们使用了一个新的函数BusOut。它就相当于DigitalOut的升级版,可以一次性定义一组引脚。
//class BusOut: A digital output bus, used for setting the state of a collection of pins
//Example:
BusOut display(D2, D3, D4, D5, D6, D9, D10, D11); //集体定义8个变量
可以通过给该变量赋值,转化为2进制数字后分别赋给该集合中的每个变量,但要注意,BusOut中定义的顺序与实际相反。如:
//欲给8个变量分别赋值1,0,0,1,0,1,1,0;写入顺序为0,1,1,0,1,0,0,1;转换为16进制数字后为69;
//便有如下写法:
BusOut display(D2, D3, D4, D5, D6, D9, D10, D11);
display = 0x69;
以此类推,便可以写出显示出所有阿拉伯数字对应的16进制值。
通常来说,为方便起见,BusOut中定义的顺序为A-B-C-D-E-F-G-DP;例如,按照上述声明方式,A灯由mbed上D2控制,查阅可知A灯由数码管上pin-7控制,因此将D2与pin-7相连。在复杂的插线及调试代码之后,便可以让数码管显示所有数字啦!(H E L P 四个字母同理)。
当然这里可以有适当拓展,比如我就使用了两个数码管,制作了1分钟倒计时。
展示代码:
#include "mbed.h"
// main() runs in its own thread in the OS
BusOut leds1(A1, A2, A3, D11, D12, A6, A7, D10); // 对应 A数码管的 A,B,C,D,E,F,G,DP
BusOut leds2(D3, D13, D9, D5, D4, D2, D1, D10); // 对应 B数码管的 A,B,C,D,E,F,G,DP
int number[10] = {0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x7, 0x7F, 0x6F}; // 对应数字 0,1,2,3,4,5,6,7,8,9
int main()
{
while (1)
{
int i, j;
leds1 = number[6]; //初始化为6
leds2 = number[0]; //初始化为0
thread_sleep_for(1000);
for (i = 5; i >= 0; i--) //十位上(A数码管)循环6至0循环
{
leds1 = number[i];
for (j = 9; j >= 0; j--) //个位上(B数码管)循环9至0循环
{
leds2 = number[j];
thread_sleep_for(1000); //持续1秒
}
}
};
};
三、参考资料
1、微信公众号:格院生存指南 / MS LAB | Part 1