понедельник, 2 декабря 2013 г.

Числа

Эта статья о том как микроконтроллеры AVR видят числа, о том что они из себя представляют для восьмибитной вычислительной машины.


Но, я начну с небольшого лирического отступления. Люди придумали много языков. Для одних людей родным языком является русский, для других - финский. Первым проще общаться на русском. И для того, чтобы понять значение финского слова им нужно прилагать больше усилий. Не смотря на это, стол останется столом не зависимо от того на каком языке будет произнесено название этого предмета.

Нечто похожее имеет место быть и в мире чисел. Одно и тоже число может быть записано множеством различных способов. Эти способы называются системами счисления.

Всем с детства известна десятичная система счисления. Людям удобно ей пользоваться. Они привыкли к ней.

Вот только для вычислительных машин эта система, как для людей иностранный язык. Она совершенно не отражает те процессы которые протекают внутри таких машин.

Родной для микроконтроллеров является двоичная система счисления. Для того, чтобы увидеть числа такими какими их видит микроконтроллер нужно собрать не сложную схему.


Это та же схема, что и в статье про бегущий огонь. Только нарисована немного иначе.

Программа для Arduino Uno:

////////////////////////
//
// Arduino UNO
//
////////////////////////
//
// Sketch: 8 LED
//

// Arduino   ATmega328
//
// D13 --- Port B Pin 5
// D12 --- Port B Pin 4
// D11 --- Port B Pin 3
// D10 --- Port B Pin 2
// D9 --- Port B Pin 1
// D8 --- Port B Pin 0
//
// D7 --- Port D Pin 7
// D6 --- Port D Pin 6
// D5 --- Port D Pin 5
// D4 --- Port D Pin 4
// D3 --- Port D Pin 3
// D2 --- Port D Pin 2
// D1 --- Port D Pin 1
// D0 --- Port D Pin 0
//
// A5 --- Port C Pin 5
// A4 --- Port C Pin 4
// A3 --- Port C Pin 3
// A2 --- Port C Pin 2
// A1 --- Port C Pin 1
// A0 --- Port C Pin 0

unsigned char data = 0;

void setup()
{
    DDRD = 0b11111111;
}

void loop()
{
    PORTD = data;
    data += 1;
    delay(1000);
}

//
// End
//
////////////////////////

Получился бинарный таймер. Чтобы было понятно все происходящее, ниже приводится таблица чисел от 0 до 255 записанных в разных системах счисления.

0 0x00 0b00000000 0
1 0x01 0b00000001 1
2 0x02 0b00000010 2
3 0x03 0b00000011 3
4 0x04 0b00000100 4
5 0x05 0b00000101 5
6 0x06 0b00000110 6
7 0x07 0b00000111 7
8 0x08 0b00001000 8
9 0x09 0b00001001 9
10 0x0a 0b00001010 10
11 0x0b 0b00001011 11
12 0x0c 0b00001100 12
13 0x0d 0b00001101 13
14 0x0e 0b00001110 14
15 0x0f 0b00001111 15
16 0x10 0b00010000 16
17 0x11 0b00010001 17
18 0x12 0b00010010 18
19 0x13 0b00010011 19
20 0x14 0b00010100 20
21 0x15 0b00010101 21
22 0x16 0b00010110 22
23 0x17 0b00010111 23
24 0x18 0b00011000 24
25 0x19 0b00011001 25
26 0x1a 0b00011010 26
27 0x1b 0b00011011 27
28 0x1c 0b00011100 28
29 0x1d 0b00011101 29
30 0x1e 0b00011110 30
31 0x1f 0b00011111 31
32 0x20 0b00100000 32
33 0x21 0b00100001 33
34 0x22 0b00100010 34
35 0x23 0b00100011 35
36 0x24 0b00100100 36
37 0x25 0b00100101 37
38 0x26 0b00100110 38
39 0x27 0b00100111 39
40 0x28 0b00101000 40
41 0x29 0b00101001 41
42 0x2a 0b00101010 42
43 0x2b 0b00101011 43
44 0x2c 0b00101100 44
45 0x2d 0b00101101 45
46 0x2e 0b00101110 46
47 0x2f 0b00101111 47
48 0x30 0b00110000 48
49 0x31 0b00110001 49
50 0x32 0b00110010 50
51 0x33 0b00110011 51
52 0x34 0b00110100 52
53 0x35 0b00110101 53
54 0x36 0b00110110 54
55 0x37 0b00110111 55
56 0x38 0b00111000 56
57 0x39 0b00111001 57
58 0x3a 0b00111010 58
59 0x3b 0b00111011 59
60 0x3c 0b00111100 60
61 0x3d 0b00111101 61
62 0x3e 0b00111110 62
63 0x3f 0b00111111 63
64 0x40 0b01000000 64
65 0x41 0b01000001 65
66 0x42 0b01000010 66
67 0x43 0b01000011 67
68 0x44 0b01000100 68
69 0x45 0b01000101 69
70 0x46 0b01000110 70
71 0x47 0b01000111 71
72 0x48 0b01001000 72
73 0x49 0b01001001 73
74 0x4a 0b01001010 74
75 0x4b 0b01001011 75
76 0x4c 0b01001100 76
77 0x4d 0b01001101 77
78 0x4e 0b01001110 78
79 0x4f 0b01001111 79
80 0x50 0b01010000 80
81 0x51 0b01010001 81
82 0x52 0b01010010 82
83 0x53 0b01010011 83
84 0x54 0b01010100 84
85 0x55 0b01010101 85
86 0x56 0b01010110 86
87 0x57 0b01010111 87
88 0x58 0b01011000 88
89 0x59 0b01011001 89
90 0x5a 0b01011010 90
91 0x5b 0b01011011 91
92 0x5c 0b01011100 92
93 0x5d 0b01011101 93
94 0x5e 0b01011110 94
95 0x5f 0b01011111 95
96 0x60 0b01100000 96
97 0x61 0b01100001 97
98 0x62 0b01100010 98
99 0x63 0b01100011 99
100 0x64 0b01100100 100
101 0x65 0b01100101 101
102 0x66 0b01100110 102
103 0x67 0b01100111 103
104 0x68 0b01101000 104
105 0x69 0b01101001 105
106 0x6a 0b01101010 106
107 0x6b 0b01101011 107
108 0x6c 0b01101100 108
109 0x6d 0b01101101 109
110 0x6e 0b01101110 110
111 0x6f 0b01101111 111
112 0x70 0b01110000 112
113 0x71 0b01110001 113
114 0x72 0b01110010 114
115 0x73 0b01110011 115
116 0x74 0b01110100 116
117 0x75 0b01110101 117
118 0x76 0b01110110 118
119 0x77 0b01110111 119
120 0x78 0b01111000 120
121 0x79 0b01111001 121
122 0x7a 0b01111010 122
123 0x7b 0b01111011 123
124 0x7c 0b01111100 124
125 0x7d 0b01111101 125
126 0x7e 0b01111110 126
127 0x7f 0b01111111 127
128 0x80 0b10000000 -128
129 0x81 0b10000001 -127
130 0x82 0b10000010 -126
131 0x83 0b10000011 -125
132 0x84 0b10000100 -124
133 0x85 0b10000101 -123
134 0x86 0b10000110 -122
135 0x87 0b10000111 -121
136 0x88 0b10001000 -120
137 0x89 0b10001001 -119
138 0x8a 0b10001010 -118
139 0x8b 0b10001011 -117
140 0x8c 0b10001100 -116
141 0x8d 0b10001101 -115
142 0x8e 0b10001110 -114
143 0x8f 0b10001111 -113
144 0x90 0b10010000 -112
145 0x91 0b10010001 -111
146 0x92 0b10010010 -110
147 0x93 0b10010011 -109
148 0x94 0b10010100 -108
149 0x95 0b10010101 -107
150 0x96 0b10010110 -106
151 0x97 0b10010111 -105
152 0x98 0b10011000 -104
153 0x99 0b10011001 -103
154 0x9a 0b10011010 -102
155 0x9b 0b10011011 -101
156 0x9c 0b10011100 -100
157 0x9d 0b10011101 -99
158 0x9e 0b10011110 -98
159 0x9f 0b10011111 -97
160 0xa0 0b10100000 -96
161 0xa1 0b10100001 -95
162 0xa2 0b10100010 -94
163 0xa3 0b10100011 -93
164 0xa4 0b10100100 -92
165 0xa5 0b10100101 -91
166 0xa6 0b10100110 -90
167 0xa7 0b10100111 -89
168 0xa8 0b10101000 -88
169 0xa9 0b10101001 -87
170 0xaa 0b10101010 -86
171 0xab 0b10101011 -85
172 0xac 0b10101100 -84
173 0xad 0b10101101 -83
174 0xae 0b10101110 -82
175 0xaf 0b10101111 -81
176 0xb0 0b10110000 -80
177 0xb1 0b10110001 -79
178 0xb2 0b10110010 -78
179 0xb3 0b10110011 -77
180 0xb4 0b10110100 -76
181 0xb5 0b10110101 -75
182 0xb6 0b10110110 -74
183 0xb7 0b10110111 -73
184 0xb8 0b10111000 -72
185 0xb9 0b10111001 -71
186 0xba 0b10111010 -70
187 0xbb 0b10111011 -69
188 0xbc 0b10111100 -68
189 0xbd 0b10111101 -67
190 0xbe 0b10111110 -66
191 0xbf 0b10111111 -65
192 0xc0 0b11000000 -64
193 0xc1 0b11000001 -63
194 0xc2 0b11000010 -62
195 0xc3 0b11000011 -61
196 0xc4 0b11000100 -60
197 0xc5 0b11000101 -59
198 0xc6 0b11000110 -58
199 0xc7 0b11000111 -57
200 0xc8 0b11001000 -56
201 0xc9 0b11001001 -55
202 0xca 0b11001010 -54
203 0xcb 0b11001011 -53
204 0xcc 0b11001100 -52
205 0xcd 0b11001101 -51
206 0xce 0b11001110 -50
207 0xcf 0b11001111 -49
208 0xd0 0b11010000 -48
209 0xd1 0b11010001 -47
210 0xd2 0b11010010 -46
211 0xd3 0b11010011 -45
212 0xd4 0b11010100 -44
213 0xd5 0b11010101 -43
214 0xd6 0b11010110 -42
215 0xd7 0b11010111 -41
216 0xd8 0b11011000 -40
217 0xd9 0b11011001 -39
218 0xda 0b11011010 -38
219 0xdb 0b11011011 -37
220 0xdc 0b11011100 -36
221 0xdd 0b11011101 -35
222 0xde 0b11011110 -34
223 0xdf 0b11011111 -33
224 0xe0 0b11100000 -32
225 0xe1 0b11100001 -31
226 0xe2 0b11100010 -30
227 0xe3 0b11100011 -29
228 0xe4 0b11100100 -28
229 0xe5 0b11100101 -27
230 0xe6 0b11100110 -26
231 0xe7 0b11100111 -25
232 0xe8 0b11101000 -24
233 0xe9 0b11101001 -23
234 0xea 0b11101010 -22
235 0xeb 0b11101011 -21
236 0xec 0b11101100 -20
237 0xed 0b11101101 -19
238 0xee 0b11101110 -18
239 0xef 0b11101111 -17
240 0xf0 0b11110000 -16
241 0xf1 0b11110001 -15
242 0xf2 0b11110010 -14
243 0xf3 0b11110011 -13
244 0xf4 0b11110100 -12
245 0xf5 0b11110101 -11
246 0xf6 0b11110110 -10
247 0xf7 0b11110111 -9
248 0xf8 0b11111000 -8
249 0xf9 0b11111001 -7
250 0xfa 0b11111010 -6
251 0xfb 0b11111011 -5
252 0xfc 0b11111100 -4
253 0xfd 0b11111101 -3
254 0xfe 0b11111110 -2
255 0xff 0b11111111 -1

В первом столбике представлены десятичные числа. И это все возможные значения переменной типа unsigned char. Во втором столбике приведены шестнадцатеричные числа. В третьем столбике показаны двоичные числа. В последнем столбике, в десятичной системе счисления, записаны числа соответствующие бинарным числам переменной типа signed char. Этот столбик добавлен для того, чтобы Вы смогли получить представление о том как для микроконтроллера выглядят отрицательные числа.

Если некоторое время помедитировать глядя на эту табличку, то можно заметить некоторые закономерности. Все числа десятичной системы счисления состоят из десяти цифр: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Все числа шестнадцатеричной системы счисления состоят из шестнадцати цифр: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f. Все числа двоичной системы счисления состоят из двух цифр: 0, 1. Это так называемое основание этих систем счисления. И еще, если к 9 прибавить 1 получится 10. Переход к следующему разряду. И если к 0xf прибавить 0x1 получится 0x10. Также происходит переход к следующему разряду. Наконец, если к 0b1 прибавить 0b1 получится 0b10. Тот же самый переход к следующему разряду.

Перечисленные системы счисления отличаются друг от друга, но у них много схожего. Вообще то, у них аналогично все, кроме основания.

Если у Вас хватить терпения, то Вы увидите как все светящиеся светодиоды ранее описанного устройства погаснут. Это происходит потому, что в переменную типа unsigned char помещается только один байт (восемь бит). Если к 0b11111111 (255) прибавить 0b1 (1) получится 0b100000000 (256). Это называется переполнение. Информация об этом событии будет сохранена в специальном регистре микроконтроллера (SREG), но в переменной будет 0b00000000. Ноль.

Итак. Как бы Вы не записывали числа в своих программах, для микроконтроллера это всего лишь последовательность битов. Двоичная система счисления является самой подходящей для отражения всех манипуляций, которые выполняются с числами внутри микроконтроллера.