简介

binary_leds

我们经常听到“数字化”时代这个词,它是什么意思?事实上,在电脑上、在网络上、在单片机上,它们只用到两个数字,也就是 0 和 1,我们所看到的一切都是 0 和 1 的组合。本次工作坊,我来一起来探求编码的奥秘。

用一个实验引出我们的话题

尝试下面的程序:

#include "avr/io.h"   // 包含 I/O 头文件
#define F_CPU 12000000UL
#include "util/delay.h"   // 包含头文件,延时要用到它

int main(void)
{
    DDRC = 0b11111111;  // 数据方向是控制,是输出,还是输入

    // PORTC = 0b00010101;  // 观察 LED 的显示
    // PORTC = 0x15;        // 用这条语句代替上面的语句,再观察效果
    PORTC = 21;             // 用这条语句代替上面的语句,再观察效果

    while (1) // 死循环
    {
    }
}

我们可以观察到,三个数字让 LED 显示出一样的排列,并没有发生任何变化,这说明这三个数字指的是同一个数!就是我们的十进制 21.

数字是什么?

刻木相会

进制之间的转换

那进制之间如何转换?

权重这个词怎么理解?

权重在英语里是 weight,就是重量,砝码,称的意思。

我们举个例子,比如今年的年份是 2013,我们看看这个数字包含了什么样的信息:

2*1000 + 0*100 + 1*10 + 3*1

换一种表示方法:

2 x 103 + 0 x 102 + 1 x 101 + 3 x 100

我们有十个手指

我们现在普遍使用 10 进制的一个重要原因在于我们的双手一共有 10 个手指(当然,有些极少数的人有 11 个或 12 个手指,但那是另一回事,那是基因“编码”出了点问题所导致的)。

二进制转十六进制

方法非常简单,从右到左,每四个二进制数字转换成一个 16 进制数字。

比如二进年数 10101111 转成 16 进制数就是 AF,因为后面四位 1111 对应于 16 进制的 F, 左边 4 位 1010 对应于 16 进制的 A

十六进制转二进制

十进制 二进制 16 进制
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
10 1010 A
11 1011 B
12 1100 C
13 1101 D
14 1110 E
15 1111 F

表格: 各种进制之间的对应关系

十六进制转十进制

十进制转二进制

我受够了,请问有简便方法吗 :)

进制 有多少个数字 数字
10 进制 10 个 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
2 进制 2 个 0, 1
8 进制 8 个 0, 1, 2, 3, 4, 5, 6, 7
16 进制 16 个 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F

表格: 各种进制和它们的数字

一个简单时钟

#include <avr/io.h>
#define F_CPU 12000000UL  // 12 MHz
#include <util/delay.h>

void init(void)
{
    DDRC = 0xFF; // 将 PORTC 设置成输出模式
    PORTC = 0x00;
}

int main(void)
{
    int i = 0;

    init();

    while (1)
    {
        PORTC = i++;   // 移位操作
        _delay_ms(1000);
    }
}

二进制时钟,用三个端口作输出,接 LED,AVR 输出的电流考虑。

#include "avr/io.h"   // 包含 I/O 头文件
#define F_CPU 12000000UL
#include "util/delay.h"   // 包含头文件,延时要用到它

int main(void)
{
    int i = 0; // 讲变量的概念

    DDRC = 0b11111111;  // 数据方向是控制,是输出,还是输入

    for (i=0; i <= 255; i++)
    {
        PORTC = i;
        _delay_ms(1000);
    }

    while (1) // 永远循环
    {
    }
}

游乐场

SOS

如果你用过老旧的 Nokia 手机,可能听到过它收到短信时会发出一种“特殊”的铃声:“嘀嘀嘀,嗒嗒,嘀嘀嘀”,也就是短响三次,长响两次,再短响三次。这实际上是摩斯密码的“SMS”(短信服务)的意思。如果你没有听到过这种铃声,可以从这里下载听一听。

下面是几个简单的莫尔斯码:

我们可以用单片机写一个 quick and dirty 的程序以莫尔斯码的方式来发送 SOS 信号。

Nokia 的短信息铃声 MP3.

POV(视频暂留)

输入与输出

用拨动开关还是用电阻来做实验,从一个 PORT 读数据,然后写到另一个 PORT 上显示。

把这些字形数据保存在内存里是不好的做法,我们将会有更好的方法(后面会使用这种方法),但这个笨办法在这里达到了我们的目的。

参考资料