Мой первый проект на PIC микроконтроллере


David Tait, david.tait@man.ac.uk
PIC16C84 (или PIC16F84) фирмы "Microchip" - миниатюрный, но мощный микроконтроллер. Он основан на EEPROM или "FLASH" технологии, позволяющей перепрограммировать его буквально за секунды. Типовое количество циклов перезаписи - около 1000. Из его 18-ти выводов 13 могут использоваться как разряды ввода/вывода общего назначения. Когда они программируются на вывод, то допускают ток "1" до 20мА и ток "0" до 25мА (более чем достаточный для подключения, например, светодиодов). Это позволяет разрабатывать на данном микроконтроллере простые и недорогие электронные устройства и делает его идеальным для желающих изучить принципы работы микроконтроллеров.

Этот короткое руководство предназначено для людей, которые только что собрали или купили программатор для PIC микроконтроллера и хотят убедиться, что оба, программатор и микроконтроллер, работают. Для этого сначала необходимо обладать некоторыми знаниями о структуре и функционировании PIC микроконтроллера. Это цоколевка выводов (см.рис.):

Схема PIC

Выводы RA* и RB* - это контакты ввода/вывода, связанные с регистрами микроконтроллера PORTA и PORTB соответственно (RA4 также может быть использоваться как вход внутреннего таймера, а RB0 может быть использован как источник прерываний). VDD и VSS - выводы питания (+Uпит и GND соответственно). Серия 16x84 работает в широком диапазоне питающих напряжений, но обычно VSS подключен к 0В, а VDD подключен +5В. Вывод основного сброса /MCLR обычно подключен к VDD (напрямую или через резистор), потому что микроконтроллер содержит надежную схему сброса при включении питания - все, что вам надо, микроконтроллер выполнит сам. Выводы OSC1 и OSC2 подключаются к генератору тактовой частоты и могут быть сконфигурированы для различных его типов, включая режимы кварца и RC-генератора. Простая схема, которая используется как база для проекта с использованием PIC16C84 представлена на рисунке:

Тест-схема

Более наглядная схема:

Тест-схема
Схема содержит RC-генератор и один вывод (RB4) подключен к индикатору. Это - все, что необходимо для работы микроконтроллера. Charles Manning (Electronics Australia, April 1996) написал изумительно короткую (6 слов) программу для мигания индикатора, которую вы можете использовать с этой схемой:

LIST    P=16C84
;
MOVLW   0
TRIS    6
OPTION
LOOP    SLEEP
INCF    6,F
GOTO    LOOP
END

Эта программа написана для MPASM (бесплатный ассемблер от Microchip, доступный по адресу
http://www.microchip.com). Для использования программы вы должны извлечь ее из этого файла любым редактором, сохранить в другой файл (например LIGHTS.ASM), затем проассемблировать с помощью MPASM (используйте команду "MPASM LIGHTS.ASM") для получения HEX файла LIGHTS.HEX, который может быть загружен в микроконтроллер с помощью программатора. Не обращайте внимания на замечания MPASM о том, что использование регистров TRIS и OPTION "не рекомендуется". Убедитесь в том, что сторожевой таймер "watchdog" включен и выбран RC-генератор. Если у вас еще нет MPASM, то здесь представлен HEX-вариант приведенной выше программы:

:0C0000000030660062006300860A0328DE
:00000001FF

Вы можете записать эти две строки в файл LIGHTS.HEX без использования MPASM. Если вы используете один из моих PIC программаторов (например TOPIC или PP), вы можете можете загрузить этот файл с корректной конфигурацией с помощью следующей команды:

PP -RW8 LIGHTS.HEX (PP V-0.3)
PP -RW LIGHTS.HEX (PP V-0.4)
TOPIC -RWG LIGHTS.HEX (TOPIC V-0.2)

Программа использует таймаут "watchdog" таймера как как источник синхронизации для определения моментов включения и выключения светодиода; в результате вы можете заставить светодиод вспыхивать с различной частотой, подключая его к различным разрядам порта PORTB (RB0-RB7, выводы 6-13). Это необычное использование "watchdog" таймера. Обычно "watchdog" таймер используется, чтобы удостовериться, что PIC ведет себя в соответствии с заданной программой, и, если ваша программа специально не сконфигурирована для использования "watchdog" таймера, активизировать его было бы большой ошибкой. Простая программа LIGHTS использует его для выхода из режима "SLEEP" (т.е. режима "засыпания"); при выходе из этого режима PIC увеличивает содержимое регистра PORTB, что изменяет состояние RB0-RB7 и опять переходит в режим "засыпания" до следующего таймаута "watchdog" таймера. "Watchdog" таймер синхронизирован внутренним RC генератором, который имеет одинаковый период на всех PIC микроконтроллерах, следовательно, использование "watchdog" таймера для операций со временем гарантирует, что временные задержки будут измеряться стабильно независимо от конфигурации задающего генератора микроконтроллера или используемой частоты (желательно, чтобы частота составляла хотя бы несколько кГц). Это свойство делает программу LIGHTS очень удобной для начального тестирования большинства макетных плат для PIC. Схема может быть изменена для получения значительно большего количества эффектов путем добавления сведодиодов. Подключите первый из них к выводу RB0 (контакт 6), второй - к RB1 (контакт 7), третий - к RB2 (контакт 8) и т.д. Наилучшим вариантом является использование как минимум четырех светодиодов с увеличением до восьми (последний подключить к RB7, т.е. контакт 13). Каждый сведодиод подключается через резистор 470 Ом между ножкой микроконтроллера и "землей" (см. схему). Следующая программа реализует эффект "бегущего огня":

; WALKLEDS.ASM

        LIST P=16C84
;    
PORTB   EQU     6 
TRISB   EQU     86H
OPTREG  EQU     81H
STATUS  EQU     3
CARRY   EQU     0
RP0     EQU     5
MSB     EQU     3               ;номер бита для крайнего слева светодиода
;
        CLRF    PORTB           ;погасить все светодиды
        BSF     STATUS,RP0      ;выбрать регистровый банк 1
        CLRF    TRISB^80H       ;установить все разряды PORTB на вывод информации
        MOVLW   0AH
        MOVWF   OPTREG^80H      ;настроить предварительный делитель в WDT на (1:4)
        BCF     STATUS,RP0      ;выбрать регистровый банк 0
        INCF    PORTB,F         ;включить крайний справа светодиод
        BCF     STATUS,CARRY    ;очистить флаг CARRY
LEFT    SLEEP                   ;подождать таймаута WDT ("watchdog" таймера)
        RLF     PORTB,F         ;сдвинуть содержимое индикатора влево
        BTFSS   PORTB,MSB       ;достигли крайней левой позиции?
        GOTO    LEFT            ;если нет - цикл
RIGHT   SLEEP                   ;подождать таймаута WDT
        RRF     PORTB,F         ;сдвинуть содержимое индикатора вправо
        BTFSS   PORTB,0         ;достигли крайней левой позиции?
        GOTO    RIGHT           ;если нет - цикл
        GOTO    LEFT            ;начать новый цикл
        END

Проассемблируйте эту программу с помощью MPASM для получения ее HEX представления:

:100000008601831686010A3081008312860A031056
:100010006300860D861D08286300860C061C0C28CC
:020020000828AE
:00000001FF

Снова вы должны с указать программатору включить "watchdog" таймер и RC генератор. Если вы запишете указанные выше четыре HEX строки в файл (например, WALKLEDS.HEX), вы можете загрузить программу, используя программатор, указав ему следующие параметры:

PP -RW8 WALKLEDS.HEX (PP V-0.3)
PP -RW WALKLEDS.HEX (PP V-0.4)
TOPIC -RWG WALKLEDS.HEX (TOPIC V-0.2)

Программа "бегущий огонь" предназначена для использования четырех светодиодов, но вы можете изменять значение MSB для использования большего количества светодиодов: для количества светодиодов 5, 6, 7 и 8 значения MSB должны быть 4, 5, 6 и 7 соответственно.

В программе не используются команды TRIS и OPTIONS, не рекомендованные к применению фирмой "MicroChip", т.к. они могут не поддерживаться в будущих микроконтроллерах. Таким образом, в отличие от предыдущей программы, во время ассемблирования не будут генерироваться предупреждения Для предотвращения генерации MPASM'мом сообщений о корректном использовании регистровых банков необходимо инвертировать старший значащий бит в любом адресе, приходящемся на банк 1 (например, использовать TRISB^80H вместо обычного TRISB, где оператор "^" означает битовое "исключающее ИЛИ"). Это - одна из уловок, которые используются для подавления вывода предупреждающих сообщений MPASM.

В качестве заключительного примера рассмотрим программу, когорая демонстрирует такие же эффекты, как и программа WALKLEDS на 4-х светодиодах. Вы обратите внимание на то, что она значительно больше по объему и ее нельзя назвать примеров эффективного программирования. Она всего лишь предназначена для демонстрации нескольких ключевых идиом и технологий PIC микропроцессоров. Кроме прочего, она содержит обработчик прерываний, процедуры записи и чтения данных встроенного FLASH EEPROM и демонстрирует, как в PIC реализован принцип табличного поиска. Программа содержит примеры одной из наиболее удобных особенностей MPASM, такой как два вида макрокоманд. Она также показывает, как отменить заданное по умолчанию основание системы счисления (шестнадцатеричное) для чисел и как внедрить информацию о конфигурации микроконтроллера. По крайней мере, по стилю она больше напоминает "настоящую" программу для микроконтроллера.

; PATTERN.ASM

; Программа разработана для демонстрации процедур чтения/записи данных EEPROM и обработки
; прерываний таймера. Таблица значений записана в EEPROM процессор выполняет "холостой"
; цикл. Когда таймер переполняется, происходит прерывание работы процессора и следующее
; значение таблицы считывается из EEPROM и записывается в порт B, т.е. отображается на
; светодиодах. С помощью изменений в таблице может быть изображен любой образец длиной до
; 64 значений.
;

; Copyright (C) 1997 David Tait (david.tait@man.ac.uk)


	PROCESSOR 16C84
	__CONFIG  03FF3                 ; RC генератор
	
PCL     equ     2
STATUS  equ     3                       ; адреса стандартных регистров
PORTB   equ     6
EEDATA  equ     8
EEADR   equ     9
INTCON  equ     0BH
OPTREG  equ     081H
TRISB   equ     086H
EECON1  equ     088H
EECON2  equ     089H

RP0     equ     5
Z       equ     2
GIE     equ     7
T0IE    equ     5
T0IF    equ     2
WREN    equ     2
WR      equ     1
RD      equ     0

#define bank0   bcf STATUS,RP0          ;выбрать Bank 0
#define bank1   bsf STATUS,RP0          ;выбрать bank 1

magic   macro                           ;"магическая" последовательность записи в EEPROM
	movlw   55H            
	movwf   EECON2^80H
	movlw   0AAH
	movwf   EECON2^80H
	endm

	cblock  0CH                     ;блок переменных
	n_vals
	n_tmp
	endc

	;**********************************;
	; Основная точка входа в программу ;
	;**********************************; 

	org     0
	goto    start


	;**************************;
	; Точка входа в прерывание ;
	;**************************;

	org     4

; Обычно содержимое необходимо сохранять перед процедурой обработки прерывания и 
; восстанавливать после нее, но в данной программе в этом нет необходимости, т.к.
; процессор ничего не делает между прерываниями. Смотрите PIC datasheet для 
; рекомендуемой процедуры.
 
	movf    EEADR,w
	xorwf   n_vals,w
	btfsc   STATUS,Z                ;EEADR == n_vals?            
	clrf    EEADR                   ;если да, то начать с нуля
	call    ee_rd                   
	movf    EEDATA,w                ;читать EEPROM
	movwf   PORTB                   ;отобразить байт
	incf    EEADR,f                 ;новый адрес
	bcf     INTCON,T0IF             ;очистить флаг прерывания
	retfie


start   clrf    PORTB
	bank1
	clrf    TRISB^80H               ;все разряды порта B на вывод
	movlw   B'00000111'
	movwf   OPTREG^80H              ;таймер 0 предварительный делитель 256:1
	bsf     EECON1^80,WREN          ;разрешить запись в EEPROM
	bank0
	call    ee_init                 ;пересылка таблицы в EEPROM
	bank1
	bcf     EECON1^80H,WREN         ;запретить запись в EEPROM
	bank0
	bsf     INTCON,T0IE             ;разрешить прерывания от таймера
	bsf     INTCON,GIE              ;разрешить все прерывания

loop    goto    loop                    ;"холостой" цикл


; ee_init
;
; инициализация EEPROM из таблицы

ee_init clrw 
	call    lut                     ;получить кол-во элементов в таблице
	movwf   n_vals                  ;и сохранить
	movwf   n_tmp                   ;сохранить еще раз
	clrf    EEADR
	decf    EEADR,f                 ;EEADR = -1
ee_in1  incf    EEADR,f                 ;следующий адрес
	movf    EEADR,w
	addlw   1
	call    lut                     ;получить соответствующее значение таблицы
	movwf   EEDATA
	call    ee_wr                   ;запись в EEPROM
	decfsz  n_tmp,f                 ;есть еще?
	goto    ee_in1                  ;да
	clrf    EEADR                   ;нет, завершить
	return
	

; lut
;
; просмотр таблицы

lut     addwf   PCL,f                   ;добавить W к PCL для получ. адреса эл-та таблицы
	retlw   D'12'                   ;число элементов в таблице
	retlw   B'1000'                 ;первый элемент
	retlw   B'1000'
	retlw   B'0100'
	retlw   B'0100'
	retlw   B'0010'
	retlw   B'0010'
	retlw   B'0001'
	retlw   B'0001'
	retlw   B'0010'
	retlw   B'0010'
	retlw   B'0100'
	retlw   B'0100'                 ;последний элемент
	

; ee_wr
;
; Записать байт из EEDATA в EEPROM по адресу в EEADR. Прерывания
; должны быть запрещены перед вызовом ee_wr.

ee_wr   bank1
	magic				;вызов "волшебной" последовательности
	bsf     EECON1^80H,WR           ;начать запись
ee_wr1  btfsc   EECON1^80H,WR           ;запись завершена?
	goto    ee_wr1                  ;нет
	bank0
	return


; ee_rd 
; 
; Прочитать байт EEPROM из EEPROM по адресу EEADR в EEDATA

ee_rd   bank1
	bsf     EECON1^80H,RD           ;начать запись
	bank0
	return                          ;при возвращении чтение должно быть завершено
	
	end


Это HEX файл, сформированный MPASM (запишите его как PATTERN.HEX):

:020000000E28C8
:0800080009080C060319890127
:10001000442008088600890A0B110900860183160E
:10002000860107308100081583121C2083160811F1
:1000300083128B168B171B2800012C208C008D003F
:1000400089018903890A0908013E2C2088003A2089
:100050008D0B22288901080082070C3408340834EB
:1000600004340434023402340134013402340234DE
:1000700004340434831655308900AA30890088146A
:100080008818402883120800831608148312080079
:02400E00F33F7E
:00000001FF



При использовании моего программатора это может быть выполнено с помощью следующей 
команды:

PP PATTERN.HEX                               (PP V-0.4)

TOPIC -G PATTERN.HEX                         (TOPIC V-0.2)

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

2nd Edition 4/Feb/97

Оригинал статьи на английском языке


Перевод Юрия Лысенкова (yl2@mail.ru)



Более подробное описание функционирования PIC микроконтроллеров серий 16C5x, 16C71, 16C84 на русском языке, программаторы для PIC микроконтроллеров, ATMEL, FLASH EEPROM и не только, а также много другой полезной информации Вы найдете на сайте "PIC микроконтроллеры и их программирование".