Основы микропроцессорной техники

Глава 6. Проектирование устройств на микроконтроллерах


«Структура курса | Глава 1 | Глава 2 | Глава 3 | Глава 4 | Глава 5 | Глава 6 | Раздел 7 | Глава 8 | Дополнения

Раздел 6 - Страницы: « 1 | 2 | 3 | 4 | 5 | 6 | 7

6.3.3. Программирование учебных задач

Начнем программирования учебных задач по написанию программы, считывающий состояние кнопки SB1 и выводит его на индикатор VD2 так, что не нажатой кнопку (высокому уровню сигнала на входе RA4) соответствует свечение светодиода, и наоборот.

; Основная программа
LOOP
CLRWDT
CALL
CALL
GOTO

;
GET_RA

MOVF
MOVWF
RETURN
;
SB1_VD2


BTFSS

GOTO
BSF
P0
BTFSC

GOTO
BCF
P1
RETURN
;


GET_RA
SB1_VD2
LOOP




PORTA, W
TEMPA





TEMPA, 4

P0
VD2

TEMPA, 4

P1
VD2

; Сброс сторожевого таймера
; Вызов подпрограммы GET_RA
; Вызов подпрограммы SB1_VD2
; Переход к метки LOOP для
; Повторение процесса

; Подпрограмма чтения состояния
; Порта A
; Чтение состояния порта A в W
; Пересылка W в TEMPA
Возврат из подпрограммы

; Подпрограмма вывода на светодиод
; VD2 состояния кнопки SB1 (разряда 4
; Регистра TEMPA)
; Пропустить команду, если
; TEMPA, 4 = 1 (кнопка не нажата)
; Перейти на P0
; Зажечь светодиод VD2

; Пропустить команду, если
; TEMPA, 4 = 0 (кнопка нажата)
; Перейти на P1
; Погасить светодиод

Основная программа содержит замкнутый цикл LOOP - GOTO LOOP, необходимый для периодического повторения цикла контроля состояния кнопки и вывода его на индикатор. Команда CLRWDT исключает влияние возможного сброса при переполнении сторожевого таймера на работу программы. Две следующие команды осуществляют вызов подпрограмм GET_RA и SB1_VD2. Первая из них (GET_RA) сначала считывает текущее состояние порта A, содержащейся в рабочем регистре W. Поскольку рабочий регистр может потребоваться при выполнении других команд, его состояние записывается в регистр TEMPA, который используется здесь для временного хранения состояния порта A. Таким образом, после возвращения из подпрограммы GET_RA в разряде 4 регистра TEMPA содержится информация о состоянии кнопки SB1: "1" - не нажата, "0" - нажата.

Подпрограмма SB1_VD2 анализирует состояние разряда 4 регистры TEMPA и, в зависимости от него, зажигает или гасит светодиод. В системе команд МК PIC16F84 нет команд условного перехода, поэтому для организации проверки той или иной условия используются команды, позволяющие пропустить выполнение следующей команды программы, в зависимости от состояния определенного бита в заданном регистре (BTFSS и BTFSC. В частности, команда BTFSS TEMP, 4 пропускает выполнения команды GOTO P0, если TEMP, 4 = 1 (кнопка не нажата. Тем самым реализуется команда BSF VD2, что зажигает светодиод VD2. Затем анализируется условие TEMP, 4 = 0 (кнопка нажата) и, если оно имеет место, светодиод гасится.

Возможна более простая реализация заданного алгоритма, поскольку нажатой кнопку исключает не нажат (и наоборот), но приведенный вариант более нагляден.

Рассмотрим более сложный вариант программы, предусматривающий зажигания светодиода VD2 только при следующем состоянии тумблеров и кнопок макета: SA1 = 1, SA2 = 1, SB1 = 1 и SB2 = 0.

; Основная программа
LOOP
CLRWDT
CALL
CALL
CALL
GOTO

;
GET_RB

MOVF
MOVWF
RETURN
;
ZAG_1110



BTFSS
GOTO
BTFSS
GOTO
BTFSS
GOTO
BTFSC
GOTO
BSF
GOTO
P0
BCF
P1
RETURN
;
INCLUDE
;


GET_RA
GET_RB
ZAG_1110
LOOP




PORTB, W
TEMPB






TEMPA, 2
P0
TEMPA, 3
P0
TEMPA, 4
P0
TEMPB, 0
P0
VD2
P1

VD2



GET_RA.ASM

; Сброс сторожевого таймера
; Вызов подпрограммы GET_RA
; Вызов подпрограммы GET_RB
; Вызов подпрограммы ZAG_1110
; Переход к метки LOOP для
; Повторение процесса

; Подпрограмма чтения состояния
; Порта B
; Чтение состояния порта B в W
; Пересылка W в TEMPB


; Зажигает светодиод VD2 только при
; Следующем состоянии тумблеров и
; Кнопок макета:
; SA1 = SA2 = SB1 = 1 и SB2 = 0
; Пропустить команду, если
; TEMPA, 2 = 1
; Пропустить команду, если
; TEMPA, 3 = 1
; Пропустить команду, если
; TEMPA, 4 = 1
; Пропустить команду, если
; TEMPB, 0 = 0
; Зажечь светодиод VD2


; Погасить светодиод VD2

Подпрограммы GET_RA и GET_RB помещают в регистры TEMPA и TEMPB текущие состояния портов A и B, соответственно. Подпрограмма ZAG_1110 анализирует состояния разрядов 2,3 и 4 регистра TEMPA и разряда 0 регистра TEMPB, и при условии TEMPA, 2,3,4 = 1,1,1 и TEMPB, 0 = 0, зажигает светодиод VD2. При невыполнении хотя бы одного из этих условий светодиод гасится.

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

Попробуем теперь использовать семисегментний индикатор для контроля состояния тумблеров макета. Сначала напишем программу, которая выводит на индикатор HL семисегментне изображения любого двоичного числа от 0b к 1111b в шиснадцятковому представлении.

; Основная программа
LOOP
CLRWDT
MOVLW
CALL
MOVWF
GOTO

;
SEV_SEG

ANDLW

ADDWF

RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
RETLW
;


0x0A
SEV_SEG
PORTB
LOOP




0x0F

PCL, F

0x80
0xF2
0x48
0x60
0x32
0x25
0x04
0xF0
0x00
0x20
0x10
0x06
0x8C
0x42
0x0C
0x1C

; Сброс сторожевого таймера
; Пересылка константы 0A в W
; Вызов подпрограммы SEVEN_SEG
; Пересылка W в PORTB
; Переход к метки LOOP для
; Повторение процесса

; Подпрограмма обслуживания
; Семисегментного индикатора
; Маскировки 4-х младших разрядов
; W и обнуление 4-х старших
; Добавление W с PCL и пересылки
; Результата в PCL
Возврат из подпрограммы с 80 в W
Возврат из подпрограммы с F2 в W
Возврат из подпрограммы с 48 в W
Возврат из подпрограммы с 60 в W
Возврат из подпрограммы с 32 в W
Возврат из подпрограммы с 25 в W
Возврат из подпрограммы с 04 в W
Возврат из подпрограммы с F0 в W
Возврат из подпрограммы с 00 в W
Возврат из подпрограммы с 20 в W
Возврат из подпрограммы с 10 в W
Возврат из подпрограммы с 06 в W
Возврат из подпрограммы с 8C в W
Возврат из подпрограммы с 42 в W
Возврат из подпрограммы с 0C в W
Возврат из подпрограммы с 1C в W

Программа начинает свою работу по пересылке константы 0x0A в рабочее регистр W. Затем происходит вызов подпрограммы обслуживания семисегментного индикатора SEV_SEG. Работа подпрограммы SEV_SEG начинается с маскировки 4-х младших разрядов W и обнуление 4-х старших. Тем самым из анализа исключаются старшие разряды переданного из рабочего регистра W числа. Затем маскирующихся содержимое регистра W добавляется к текущему состоянию младшего байта счетчика команд PCL, и результат помещается в PCL. Таким образом, происходит дополнительное смещение счетчика команд на величину, которая была передана в рабочем регистре. Например, если было W = 0, то содержимое счетчика команд не изменится, и будет выполнена следующая команда RETLW 0x80, вызывающий возвращения из подпрограммы с записью 0x80 = Вь1000000 'в регистр W. Если, как было в приведенной программе, W = 0A, то к содержимому PCL будет добавлено число 0x0A, и состоится дополнительный сдвиг на 10 шагов. В результате будет выполнена команда RETLW 0x10, вызывающий возвращения из подпрограммы с записью 0x10 = B'0001000 'в регистр W.

После возвращения из подпрограммы происходит пересылка W в PORTB и отражение его состояния на семисегментному индикаторе HL. В частности, если W = 0, то при выводе 1000000b на порт B семисегментний индикатор покажет , А при W = A покажет Таким образом, может быть отражен любое 4-разрядное двоичное число.

Метод прямого управления счетчиком команд, использованная в подпрограмме SEV_SEG, может применяться для реализации табличной конвертации чисел. При этом необход имо иметь в виду, что данный метод не позволяет конвертировать более 256 значений в одной таблице. Кроме того, программа табличной конвертации должна полностью располагаться внутри 256-байтного блока во избежание переполнения младшего байта счетчика команд.

Используя подпрограмму SEV_SEG, напишем теперь программу, которая читает состояния тумблеров SA1 и SA2 и выводит на индикатор соответствующее число.

; Основная программа
LOOP
CLRWDT
CALL
RRF

RRF

ANDLW
CALL
MOVWF
GOTO

;
INCLUDE
INCLUDE
;


GET_RA
TEMPA, F

TEMPA, W

0x03
SEV_SEG
PORTB
LOOP


GET_RA.ASM
SEV_SEG.ASM


; Сброс сторожевого таймера
; Вызов подпрограммы GET_RA
; Сдвиг вправо на один разряд
; Через перенос
; Сдвиг вправо на один разряд
; Через перенос
; Маска на два младших разряда
; Вызов подпрограммы SEVEN_SEG
; Пересылка W в PORTB
; Переход к метки LOOP для
; Повторение процесса

Подпрограмма GET_RA помещает в регистр TEMPA текущее состояние порта A. Таким образом, в разрядах 2 и 3 регистра TEMPA сохраняется текущее состояние тумблеров SA1 и SA2. Для того чтобы биты состояния тумблеров заняли позиции 0 и 1 регистра TEMPA, происходит два сдвиги вправо через перенос, причем результат второго сдвига содержится в регистр W. Затем накладывается маска на два младших разряда рабочего регистра и происходит вызов подпрограммы SEV_SEG. После выхода из подпрограммы результат подается на порт B и отображается на индикаторе.

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

; Основная программа
MOVLW
CALL
;
DELAY

MOVWF
LOOPD
DECFSZ
GOTO
RETURN
;
0xL
DELAY



COUNT1

COUNT1, F
LOOPD
; Пересылка константы H'L 'в W
; Вызов подпрограммы DELAY

; Подпрограмма формирования
; Задержки времени
; Загрузки W в регистр COUNT1

; Декремент COUNT1
; Повторение цикла H'L 'раз
Возврат из подпрограммы

Основная программа проводит вызов подпрограммы DELAY с некоторой константой L в рабочем регистре W, определяющий количество внутренних циклов подпрограммы. Подпрограмма DELAY начинает свою работу по загрузке содержимого рабочего регистра в регистр пользователя COUNT1. Команда DECFSZ COUNT1, F уменьшает на единицу содержимое регистра COUNT1 и проверяет его на равенство нулю. Нулевой состояние регистра COUNT1 приводит к выходу из цикла и возвращению из подпрограммы. Для выполнения каждого внутреннего цикла нужно три машинных цикла МК (1 цикл на выполнение команды DECFSZ при ненулевом результате и 2 цикла на каждую команду GOTO. Выход из подпрограммы DELAY требует 4-х циклов (2 циклы на выполнение команды DECFSZ при нулевом результате и 2 цикла на RETURN. Если добавить к этому еще 4 цикла, необходимых для загрузки константы в рабочее регистр, вызова подпрограммы и загрузки регистра пользователя COUNT1, то общее время выполнения подпрограммы DELAY (задержка) составит:

T D = 4 + 3 * (L - 1) + 4 = 5 + 3 * L циклов,

где L - константа, передано через рабочий регистр в подпрограмму DELAY.

При тактовой частоте fosc = 2МГц время цикла равна t ц = 2 мкс, поэтому при загрузке L = H'00 '= .0 максимальный сформирован интервал времени составит 1,55 мс. Такой результат связан с тем, что команда DECFSZ сначала декрементуе содержимое регистра (H'00 '- 1 = H'FF'), а потом уже анализирует результат.

Минимальный формируемый интервал времени составит при тех же условиях 5 циклов или 10 мкс. Для получения такого интервала необходимо перед вызовом подпрограммы DELAY загрузить в рабочий регистр число 0x01.

Для расширения верхней границы формируемых временных интервалов, а также с целью повышения удобства работы с подпрограммой, можно добавить в цикл LOOPD одну или несколько дополнительных команд, в качестве которых чаще всего используется команда NOP. Для примера рассмотрим подпрограмму формирования задержки времени DELAY_C:

;
DELAY_C

MOVWF
LOOPD
NOP
DECFSZ
GOTO
RETURN
;



MOVWF COUNT1


COUNT1, F
LOOPD


; Подпрограмма формирования
; Задержки времени (вариант C)
; Загрузки W в регистр COUNT1

; Пустая команда
; Декремент COUNT1
; Повторение цикла H'L 'раз
Возврат из подпрограммы

Общее время выполнения подпрограммы DELAY_C, включая ее вызов, составит:

T D = 4 + 4 * (L - 1) + 4 = 4 + 4 * L циклов.

При тактовой частоте fosc = 2МГц и загрузке константы L = H'9 '= .249 формируемый интервал времени составит ровно 2 мс. Уменьшение константы на единицу уменьшает формируемый временной интервал на 8 мкс. В частности, при L = .124 образуется задержка в 1 мс.

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

; Основная программа
MOVLW
CALL
;
DELAY_D

MOVWF
CLRF
LOOPD
DECFSZ
GOTO
CLRWDT
DECFSZ
GOTO
RETURN
;
0xL
DELAY_D



COUNT2
COUNT1

COUNT1, F
LOOPD

COUNT2, F
LOOPD
; Пересылка константы H'L 'в W
; Вызов подпрограммы DELAY_D

; Подпрограмма формирования
; Большой задержки времени (вариант D)
; Загрузки W в регистр COUNT2
; Сброс содержимого регистра COUNT1

; Декремент COUNT1
; Повторение цикла 256 раз
; Сброс сторожевого таймера
; Декремент COUNT2
; Повторение цикла H'L 'раз
Возврат из подпрограммы

Время выполнения внутреннего цикла подпрограммы DELAY_D составляет 3 * 256 + 4 машинных циклов МК, поэтому общая задержка составит:

T D = 5 + (3 * 256 + 4) * L циклов.

При тактовой частоте f osc = 2МГц время цикла равна t ц = 2 мкс, поэтому при загрузке L = H'00 '= .0 максимальный формируемый интервал времени составит около 0,4 с.

Поскольку формируемый интервал времени достаточно велик, во внешней цикл включена команда сброса сторожевого таймера.

Интервал времени 0,4 с не совсем удобен для получения задержек времени, кратных секунде, поэтому рассмотрим еще один вариант подпрограммы формирования больших задержек времени с дополнительной командой NOP во внутреннем цикле:

;
DELAY_E

MOVWF
CLRF
LOOPD
NOP
DECFSZ
GOTO
CLRWDT
DECFSZ
GOTO
RETURN
;



COUNT2
COUNT1


COUNT1, F
LOOPD

COUNT2, F
LOOPD

; Подпрограмма формирования
; Большой задержки времени (вариант E)
; Загрузки W в регистр COUNT2
; Сброс содержимого регистра COUNT1

; Пустая команда
; Декремент COUNT1
; Повторение цикла 256 раз
; Сброс сторожевого таймера
; Декремент COUNT2
; Повторение цикла H'L 'раз
Возврат из подпрограммы

Вре я выполнения внутреннего цикла подпрограммы DELAY_E составляет 4 * 256 + 4 машинных циклов МК, поэтому общая задержка составит:

T D = 5 + (4 * 256 + 4) * L циклов.

При тактовой частоте fosc = 2МГц и при загрузке L = H'3 '= .243 формируемый интервал времени составит около 0,5 с при погрешности не более 0,2%. Если необходима более высокая точность, можно вставить необходимое количество пустых операций во внешней цикл формирования задержки.

Рассмотрим далее несколько программ с использованием подпрограмм формирования задержки времени. Начнем с написания программы, подающий сигнал на динамик BA1 при нажатии на кнопку SB1. Динамик будет звучать только в том случае, если на выходе RA0 будет подан периодически переменный сигнал. Для того чтобы звук был хорошо слышен, его частота должна находиться вблизи максимума чувствительности человеческого уха. Выберем частоту звучания равной 1 КГц, что соответствует периоду следования импульсов сигнала 1 мс.

; Основная программа
LOOP
CLRWDT
CALL
CALL
GOTO

;
SB1_BA1


BTFSC

GOTO
BSF
MOVLW

CALL
BCF
MOVLW

CALL
B0
RETURN
;
INCLUDE
INCLUDE
;


GET_RA
SB1_BA1
LOOP





TEMPA, 4

B0
BA1
0x3E

DELAY_C
BA1
0x3E

DELAY_C



GET_RA.ASM
DELAY_C.ASM

; Сброс сторожевого таймера
; Вызов подпрограммы GET_PORTA
; Вызов подпрограммы SB1_BA1
; Переход к метки LOOP для
; Повторение процесса

; Подпрограмма подачи звука на
; Динамик BA1 при нажатии на кнопку
; SB1
; Пропустить команду, если
; TEMPA, 4 = 0 (кнопка нажата)
; Перейти на B0
; Подача высокого уровня на RA0
; Пересылка константы
; H'3E '= .62 в W
; Вызов подпрограммы DELAY_C
; Подача низкого уровня на RA0
; Пересылка константы
; H'3E '= .62 в W
; Вызов подпрограммы DELAY_C

Прежнему подпрограмма GET_RA считывает текущее состояние порта A, затем передается в регистр TEMPA. Подпрограмма SB1_BA1 анализирует состояние разряда 4 регистра TEMPA и, в зависимости от результата, озвучивает динамик BA1 или нет. Необходима выдержка линии RA0 в единичном и нулевом состояниях обеспечивается подпрограммой DELAY_C с параметром L = Hь3Е '= .62. Это с ответствует времени задержки около 0,5 мс, что и дает в результате требуемую частоту прохождения сигнала 1кГц.

Рассмотрим далее программу, заставляет моргать светодиод VD2 при нажатии на кнопку SB1. Для того чтобы мигание были хорошо видны, выберем их частоту равной 1Гц.

; Основная программа
LOOP
CLRWDT
CALL
CALL

GOTO

;
SB1_VD2M

BTFSC

GOTO
BSF
MOVLW

CALL
BCF
MOVLW

CALL
V0
BTFSS

GOTO
BCF
V1
RETURN
;
INCLUDE
INCLUDE
;


GET_RA
SB1_VD2M

LOOP




TEMPA, 4

V0
VD2
0xF3

DELAY_E
VD2
0xF3

DELAY_E

TEMPA, 4

V1
VD2



GET_RA.ASM
DELAY_E.ASM

; Сброс сторожевого таймера
; Вызов подпрограммы GET_RA
; Вызов подпрограммы
; SB1_VD2M
; Переход к метки LOOP для
; Повторение процесса

; Подпрограмма моргание светодиода
; VD2 при нажатии на кнопку SB1
; Пропустить команду, если
; TEMPA, 4 = 0 (кнопка нажата)
; Перейти на V0
; Зажечь светодиод VD2
; Пересылка константы
; H'3 '= .243 в W
; Вызов подпрограммы DELAY_E
; Погасить светодиод
; Пересылка константы
; H'3 '= .243 в W
; Вызов подпрограммы DELAY_E

; Пропустить команду, если
; TEMPA, 4 = 1 (кнопка не нажата)
; Перейти на V1
; Погасить светодиод

Программа работает почти так же, как и предыдущая. Первое отличие заключается в том, что светодиод принудительно гасится при не нажатой кнопки. Второе отличие заключается в величине интервала времени, составляет здесь 0,5 с и формируется подпрограммой DELAY_E.

Подпрограммы формирования задержки времени могут быть также полезны при работе с такими внешними источниками сигналов, как тумблеры, кнопки, переключатели и т.п. Дело в том, что все механические коммутаторы имеют одну негативную свойство, известное как "дребезжание" контактов, что обусловлено механическими колебаниями контактов при их замыкании и размыкании. Продолжительность к лебаний обычно составляет несколько миллисекунд, в течение которых на вход МК может поступать пачка импульсов вместо идеального перепада.

Аппаратные способы борьбы с "дребезжание" контактов основанные на использовании RS-триггеров, одновибраторив или триггеров Шмитт. В устройствах на основе МК подавления "дребезжание" контактов обычно осуществляется программными способами, основанными на повторном считывании состояния линии порта через определенное время.

В качестве примера рассмотрим следующий вариант подпрограммы чтения состояния порта A:

;
GET_RAD


DD
MOVF
ANDLW

MOVWF
CLRWDT
MOVLW

CALL
MOVF
ANDLW
SUBWF
BTFSS

GOTO
RETURN
;
INCLUDE
;





PORTA, W
0x1C

TEMPA

0x0A

DELAY_E
PORTA, W
0x1C
TEMPA, W
Z

DD


DELAY_E.ASM

; Подпрограмма чтения состояния
; Порта A в регистр TEMPA
; С подавлением "дребезжание"

; Чтение состояния порта A в W
; Наложение маски b'00011100 '
; На неиспользуемые биты W
; Пересылка W в TEMPA
; Сброс сторожевого таймера WDT
; Пересылка константы
; H'0A '= .10 в W
; Вызов подпрограммы DELAY_E
; Чтение состояния порта A в W
; Наложение на W маски b'00011100 '
; Вычитания W с ТЕМРA
; Пропустить команду, если результат
; Нулевой
; Перейти на метку DD

Суть работы подпрограммы заключается в повторном чтении состояния порта A через некоторое время после предварительного и сравнении его с бывшим значением. Константа Hь0А '= .10, пересылаемой в регистр W перед вызовом подпрограммы DELAY_E, обеспечивает значение задержки времени около 20 мс. - Этого, как правило, достаточно для завершения переходных процессов при переключении механических коммутаторов. Маскировка неиспользуемых разрядов порта повышает надежность работы подпрограммы. Сброс сторожевого таймера перед вызовом подпрограммы задержки нужно для выключения сброса МК между двумя процедурами опроса порта A.

Розглянемо тепер роботу програми, що використовує деякі з розроблених раніше підпрограм. Нехай метою роботи програми є підрахунок кількості натискань на кнопку SB1 з виводом результату на семисегментний індикатор у шіснадцятковому коді:

;основна програма
CLRF
LOOP
CLRWDT
CALL
BTFSC
GOTO

INCF
MOVF

CALL
MOVWF
TEST
CALL
BTFSS
GOTO

GOTO
;
INCLUDE
INCLUDE
;
COUNT3


GET_RAD
TEMPA,4
LOOP

COUNT3,F
COUNT3,W

SEV_SEG
PORTB

GET_RAD
TEMPA,4
TEST

LOOP

GET_RAD.ASM
SEV_SEG.ASM
;скидання лічильника натискань

;скидання сторожового таймера
;виклик підпрограми GET_RAD
;перевірка натискання SB1
;якщо не натиснута - повернення
;на мітку LOOP
;інкремент лічильника
;пересилання вмісту
;лічильника в робочий регістр
;виклик підпрограми SEVEN_SEG
;пересилання W у PORTB

;виклик підпрограми GET_RAD
;перевірка натискання SB1
;якщо ще натиснута - повернення
;на мітку TEST
;повернення на мітку LOOP

Приведені в розділі програми не охоплюють і малої частки можливостей, які надає навіть такий простий макет, як зображений на Рис. 6.3. Однак їх освоєння, сподіваюся, буде корисним для починаючих користувачів PIC-контролерів.


« Структура курсу Розділ 6 - Сторінки: « 1 | 2 | 3 | 4 | 5 | 6 | 7