Один байт, как правило, состоит из 8 бит (в протоколе RS-232, например, байт может быть длиной от 7 до 9 бит). Нумерация бит в байте идёт справа налево, младший бит (справа) имеет номер 0, старший бит (слева) - номер 7. Бит - это двоичная величина, может принимать только два значения: 0 и 1. В программах, написанных на C для МК, используются следующие приставки для обозначения систем счисления: 0b - двоичная (0b01100001), 0x - шестнадцатеричная (0x61), 0 - восьмеричная (0141). Во всех этих примерах записано десятичное число 97. Удобный конвертер величин можно найти
здесь. Рассмотрим байт 0b01100001.
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
Каждый его бит определяет одно из двух логических состояний (уровней): логический 0 (нет, false) и логическая 1 (да, true). При этом, в зависимости от используемого МК, логический 0 может быть выражен напряжением 0 В (земля, GND), а логическая 1 - напряжением +5 В. Значения 0 В и +5 В стали стандартом де-факто для микроконтроллеров, а вот протокол RS-232 соотносит логические уровни с напряжениями -12 В и +12 В соответственно.
На
первом этапе, посылая на ножку МК 0 или 1, мы посылали 1 бит. При этом, пин МК или замыкался на землю, и светодиод гас, или выдавал напряжение +5 В, и светодиод светился. Впрочем, от 5 В диод просто сгорел бы, поэтому мы подсоединяли его через токоограничительный резистор. Значит, за один раз на один пин МК можно послать только один бит. Кстати, МК pic12f675 имеет только 6 портов ввода-вывода (GPIO0 - GPIO5), то есть может одновременно адресовать только 6 бит, что даже меньше байта. Однако, при помощи этого микроконтроллера можно передавать не только байты, а даже целые слова (слово - 16 бит, двойное слово - 32 бита). Впрочем, машинное слово не стандартизовано, и у того же pic12f675 в даташите принято равным 14 битам. Объём программной памяти этого МК составляет 1024 слова по 14 бит в слове, итого 14336 бит, или 1792 байт (1.75 Кб).
Для того, чтобы через один пин передавать целые байты, используют сдвиговый регистр. Подробно принцип действия сдвигового регистра описан в
этой работе.
ИнформацияКомпилятор SDCC, программатор EXTRA-PIC, программа-программатор IC-Prog. Схема собиралась на беспаечной макетной плате. Настройки битов конфигурации, равно как и весь процесс компиляции и прошивки МК, аналогичны первому этапу.
Даташит на сдвиговый регистр 74HC595Радиокомпоненты и приборы- микроконтроллер pic12f675
- регистр сдвига 74HC595
- источник стабилизированного питания напряжением +5 В
Электрическая принципиальная схемаИсходный код прошивки на языке CНиже представлено два варианта исходного кода. В первом все необходимые команды для передачи байта выполяются последовательно, во втором эти операции заключены в функцию. По результату своей работы оба варианта равноценны.
Файл pic.c, компилятор SDCC
#include <pic12f675.h>
main(){
OSCCAL = 0x80; //Установить внутренний осциллятор на среднюю частоту
TRISIO = 0b11111000; //Установить GPIO0, GPIO1, GPIO2 на выход, остальные - на вход
GPIO = 0b00000000; //На всех GPIO установить логический ноль
CMCON = 0b00000111; //Отключить компаратор
ADCON0 = 0b00000000; //Отключить АЦП
ANSEL = 0b00000000; //Отключить аналоговые входы, все ножки установить как цифровые входы-выходы
#define sh_cp GPIO0 //Определить GP0 как sh_cp
#define ds GPIO1
#define st_cp GPIO2
while(1){
//Отправим байт 0b10011010
st_cp = 0; //Сигнал защёлки. Ожидаем байт
ds = 1; //7-й бит данных
sh_cp = 0; //тактовый сигнал
sh_cp = 1;
ds = 0; //6-й бит данных
sh_cp = 0;
sh_cp = 1;
ds = 0;
sh_cp = 0;
sh_cp = 1;
ds = 1;
sh_cp = 0;
sh_cp = 1;
ds = 1;
sh_cp = 0;
sh_cp = 1;
ds = 0;
sh_cp = 0;
sh_cp = 1;
ds = 1;
sh_cp = 0;
sh_cp = 1;
ds = 0; //0-й бит данных
sh_cp = 0;
sh_cp = 1;
st_cp = 1; //Защёлкнули байт
}
}
А теперь отправим этот же байт при помощи функции.
Файл picf.c, компилятор SDCC
#include <pic12f675.h>
#define SHCP GPIO0
#define DS GPIO1
#define STCP GPIO2
//Функция для отправки байта
void shift(unsigned char c){
int i;
STCP = 0;
//Побитно читаем байт c, начиная со старшего бита
for(i=7;i>=0;i--){
DS = (c >> i) & 1; //Для получения очередного бита используем побитовый сдвиг и маску
SHCP = 0;
SHCP = 1;
}
STCP = 1;
}
main(){
OSCCAL = 0x80; //Установить внутренний осциллятор на среднюю частоту
TRISIO = 0b11111000; //Установить GPIO0, GPIO1, GPIO2 на выход, остальные - на вход
GPIO = 0b00000000; //На всех GPIO установить логический ноль
CMCON = 0b00000111; //Отключить компаратор
ADCON0 = 0b00000000; //Отключить АЦП
ANSEL = 0b00000000; //Отключить аналоговые входы, все ножки установить как цифровые входы-выходы
while(1){
shift(0b10011010); //Применяем функцию - отправляем байт 0b10011010
}
}
В результате работы этого кода на выводах Q0...Q7 сдвигового регистра 74HC595 появится байт, отправленный через одну-единственную дата-ножку GP1 микроконтроллера. Убедиться в этом можно при помощи бытового вольтметра: на ножках 1, 3, 4 и 7 микросхемы 74HC595 должно быть напряжение +5 В (логическая единица), а на ножках 2, 5, 6 и 15 - напряжение 0 В (логический ноль). Причём, нумерация выводов сдвигового регистра будет соответствовать нумерации битов в байте: bit7...bit0 = Q7...Q0. Для наглядного представления полученного результата к ножкам Q7...Q0 сдвигового ргистра можно подключить светодиодны через токоограничительные резисторы, однако нам в дальнейшем такой "ветвитель" ножек МК понадобится для более практической задачи: подключения LCD-дисплея.