Страница 1 из 1

Помогите с PIC16F84А пожалуста

Добавлено: Вс июл 19, 2009 00:02:12
zaman
Решил сделать обычные часы, для начала без кнопок. Подключил к контроллеру кварц на 10,000 МГц и семи сегментный индикатор (с точкой) на 5 знакомест, ноги сегментов индикатора соединены параллельно и подключены на PORTB, а управляющие ноги сегментов на PORTA (через КТ315Б). Написал программу бесконечного вывода 12345 - работает отлично. Начал делать часы, как я понял, таймер работающий от внутреннего сигнала тактирования (можно и от внешнего, но занята нога, и непонятка с кварцем) прерывается 1 раз в секунду и добавляет к регистру счетчика секунд 1, и проделует вычисления времени (типа было 0 час 5 мин 60 сек +1 = 0 час 6 мин 0 сек и в таком духе) затем прерывание заканчивается и выполнение возвращается в основную программу где бесконечно производится вывод регистров часов, минут, секунд на индикатор.

Проблемы начались с малого, уже этот код не компилируется, причем MPASM и MPLAB выдают совершенно разные ошибки.

Код: Выделить всё

        LIST P=16F84A
   
;----------
PORTA   EQU     5
PORTB   EQU     6
TRISB   EQU     86H
TRISA   EQU   85H
OPTREG  EQU     81H
STATUS  EQU     3
CARRY   EQU     0
RP0     EQU     5
PCL   EQU   2
INTCON   EQU   0BH
TMR0   EQU   01H

FSR   EQU   04H
FSR_B   EQU   0FH
;----------
SEC   EQU   0CH
MIN   EQU   0DH
HOUR   EQU   0EH
;----------
D_CH1   EQU   10H
D_CH2   EQU   11H
D_CH3   EQU   12H
D_CH4   EQU   13H
D_CH5   EQU   14H
;----------
   CLRF   PORTA
   CLRF   PORTB
;----------
   BSF   STATUS,5
   CLRF    TRISA
   CLRF   TRISB
   BCF     STATUS,5
;----------
   BCF   OPTREG,5
   BSF   INTCON,5
   BSF   INTCON,7
   CLRF   TMR0
;----------
;----------
   ORG   0
   GOTO   MAIN
;----------
   ORG   4
   GOTO   INT
;----------
INT   MOVF   FSR,0
   MOVWF   FSR_B

   CLRF   TMR0
   INCF   SEC,1
   
   MOVF   FSR_B,0
   MOVWF   FSR
   RETFIE
;----------
MAIN   CALL   MOD

   MOVLW   B'00000001'
   MOVWF   PORTA
   MOVLW   D_CH1
   MOVWF   PORTB

   MOVLW   B'00000010'
   MOVWF   PORTA
   MOVLW   D_CH2
   MOVWF   PORTB

   MOVLW   B'00000100'
   MOVWF   PORTA
   MOVLW   D_CH3
   MOVWF   PORTB

   MOVLW   B'00001000'
   MOVWF   PORTA
   MOVLW   D_CH4
   MOVWF   PORTB

   MOVLW   B'00010000'
   MOVWF   PORTA
   MOVLW   D_CH5
   MOVWF   PORTB

   GOTO   MAIN
;----------
MOD   MOVF   SEC,0
   MOVWF   D_CH1
   RETURN
;----------
END   

Процедура MAIN будет переделываться и особо обращать на неё внимание не нужно, мне интересно почему код не компилируется и как с моим кварцем отсчитать точно 1сек?
Прочитал даташит по контролеру, самоучитель Корабельникова, несколько исходников часов и таймеров, но запутался ещё больше, нигде не нашёл как таймером отмерять 1 сек.

Добавлено: Вс июл 19, 2009 13:42:38
Pahan
Ругаецо, потому что у тя директивы org 0 и org 4 идут гдето в середине текста. А компилятор автоматически уже подставил на эти адреса команды, которые идут до этих директив. Он же пишет причину ошибки - читать надо

Error[118] .......... 44 : Overwriting previous address contents (0000)
Error[118] .......... 47 : Overwriting previous address contents (0004)

Когда я отмерял секунды, то таймер настраивал на несколько килогерц, а в основном цикле считал кол-во прерываний, нужных для отсчета 1 секунды.

Да, кстати конструкция
ORG 4
GOTO INT
INT ......

в данном случае абсолютно бессмыслена. GOTO не нужен. Он будет нужен только если подпрограмма прерывания находицо в другом месте. А у тебя она идет сразу за goto.

Добавлено: Вс июл 19, 2009 15:42:52
zaman
Pahan писал(а):Да, кстати конструкция
ORG 4
GOTO INT
INT ......

в данном случае абсолютно бессмыслена. GOTO не нужен. Он будет нужен только если подпрограмма прерывания находицо в другом месте. А у тебя она идет сразу за goto.


Понимаю что не нужно, с начало не было, думал без этого не компилируется...
Исправил - компилируется, а как правильно организовать прерывание раз в секунду, так и не понял... помогите можалуста

Добавлено: Пн июл 20, 2009 20:59:01
yaroslav
Для часов вообще лучше применять часовой кварц на 32768 Гц
Вот, например, почитайте: http://pic.borda.ru/?1-2-40-00000042-000-0-0

Добавлено: Пн июл 20, 2009 23:00:36
zaman
Вот теперь понял.
Нужно поставить кварц на 32,768МГц и предделитель на 128, таймер посчитает до 256 - значит прошла секунда, но ведь у меня контроллер PIC16F84A-04/P , а это значит что он расчитан всеголиш на 4МГц (итак боюсь что работает на 10МГц) Можно ли ставить часовой кварц как тактирующий на весь контроллер? А то мне пятой ноги на порте А жалко :(

Добавлено: Пн июл 20, 2009 23:40:22
бгкот
Можно поставить кварц на 4,096 МГц, тоже часто встречаются.

Добавлено: Вс июл 26, 2009 11:45:31
Chettuser
Привет Уважаемые Форумчане!
Чем отличается:
1) incf c1,f
movlw c1

2) incf c1,w

- чем отличаются эти команды (по конечному результату)? Вроде бы одно и то же, а почему то 1) не работает (не сохраняет в с1)... :( Три часа бьюсь :cry:

Кто-нить поможет? Спасибо.

Выкладываю листинг и схемку (может пригодятся?). Простите за "сырой" код - только учусь, решил попробовать :))

Код: Выделить всё

list   p=16f84
#include   <p16f84a>
   cblock
         c1
         c2
   endc

org   0x000         

;***ИНИЦИАЛИЗАЦИЯ ПОРТОВ A и B***


      bcf      STATUS,RP0   ;включаем банк 0 (PORT)
      clrf   PORTA      ;чистим выводы портов A
      clrf   PORTB      ;--//--B

      bsf      STATUS,RP0   ;включаем банк 1 (TRIS)
      clrf   PORTA      ;чистим выходные защелки портов A
      clrf   PORTB      ;--//--B

;      bsf      STATUS,RP0   ;включаем банк 1 (TRIS)
      movlw   b'11111111'   
      movwf   PORTA      ;выводы порта А на вход
      movlw   b'00000000'   
      movwf   PORTB      ;выводы порта B на выход

      bcf      STATUS,RP0   ;включили банк 0 (PORT)

;***собственно сама программа***

Begin
      
      btfss   PORTA, 0   ;проверка нажатия кнопки "+"
      incf   c1,f      ;увеличиваем значение с1
   movlw   .10               ;*
   subwf   c1,w            ;*
   btfsc   STATUS,C         ;проверяем на переполнение
   clrf   c1               ;*
;      clrw
      movlw   c1
;      call   delay      ;задерживаем время на нажатие

      btfss   PORTA, 4   ;проверка нажатия кнопки "-"
      decf   c1,f      ;уменьшаем значение с1
   btfsc   STATUS,C         ;проверяем на с1 = 0
   clrf   c1               ;*
;      clrw
      movlw   c1
;      call   delay      ;задерживаем время на нажатие

;      movlw   c1         ;запись с1 в аккумулятор

      call   Table      ;вызов таблицы
      movwf   PORTB      ;вернулись, выдаём в PORTB

      goto   Begin      ;возвращаемся

Table                  ;таблица
      addwf   PCL,f
      retlw   b'00111111'
      retlw   b'00000110'
      retlw   b'01011011'
      retlw   b'01001111'
      retlw   b'01100110'
      retlw   b'01101101'
      retlw   b'01111101'
      retlw   b'00000111'
      retlw   b'01111111'
      retlw   b'01101111'

delay
      movlw   0xFF
      movwf   c2
loop
      decfsz   c2,f
      goto   loop
      return

end

Добавлено: Вс июл 26, 2009 12:13:04
urry
movlw - загрузить константу в аккумулятор. :)
Вам нужно movf c1,w

Добавлено: Вс июл 26, 2009 14:32:31
Pahan
movlw c1
загружаецо не значение c1, а адрес регистра c1

Добавлено: Вс июл 26, 2009 15:18:59
Chettuser
(чтото схемка не прикрепилась...)
Спасибо всем кто откликнулся :), но...

incf c1,f - это, как я понимаю, c1=c1+1, почему то не работает, а нужно... странно - в описании команды есть f, на деле у меня не мурлыкает. Работает вариант с помещением результата в рабочий регистр (т.е. w=c1+1) !!!!!!! :shock: (Но мне нужен "w" в промежутке между командами).
ЗЫ: Или я хуже чем полный ламер... ?

Добавлено: Вс июл 26, 2009 15:53:24
Chettuser
zaman писал(а):Вот теперь понял.
Нужно поставить кварц на 32,768МГц ... , но ведь у меня контроллер PIC16F84A-04/P , а это значит что он расчитан всеголиш на 4МГц... Можно ли ставить часовой кварц как тактирующий на весь контроллер? :(


32 768 Герц или 32,768 кГц - кажется ошибочка/опечатка? Ставить можно, это же много меньше 4МГц...
Я, кстати, ставил часовой кварц - работает, только там кажется надо будет в режиме выставить LP (у Вас сейчас XT, но это я так... на всякий случай). :)) )

Добавлено: Вс июл 26, 2009 16:23:45
urry
Chettuser писал(а):incf c1,f - это, как я понимаю, c1=c1+1, почему то не работает, а нужно...

Оно работает, просто конкретно у Вас - невнимательность - Вы в коде не обозначили область начала регистров общего назначения
Вместо
cblock
c1
c2
endc

cblock 0x0c
c1
c2
endc

:)

Добавлено: Вс июл 26, 2009 16:26:49
Chettuser
Упссс... :oops: Спасибо большое :))

PS: Кстати нанюхал в сети книжки по PIC'ам:
1. http://r103.letitbit.net/download100/80909f524613_oqis2v2adr7805ev/820894/letitbit.net/Predko-spr-po-PIC-microcont.djvu

2. http://ds1.twirpx.com/files/011/11761_Yacenkov_v_s_mikrokontrollery_Microchip_prakticheskoe_rukovodstvo_DjVu.rar

Может пригодится кому...

PS: Жаль... ссылки сдохли...

Добавлено: Ср янв 06, 2010 20:20:35
Chettuser
Привет всем обитателям форума! Всех с Рождеством!
Извините начинающего, сильно не пинайте...

Пишу прогу для PIC16F84A и столкнулся с такой проблемой:
Нужно создать множественное условие:
if key > .2 & key ...
goto aa
else
goto bb
endif

корректно работает только:

if key> .2
goto aa
else
goto bb
endif

Как заставить работать условие которое с "&" ???

Еще раз прошу сильно новичка не пинать - я сам учусь... и пытаюсь сам разобраться в данной проблеме, но нигде про это ненаписано :cry: (я даже незнаю - можно ли применять IF в программе, или только как директиву для управления самой программой?)
Спасибо.

Добавлено: Чт янв 07, 2010 10:25:44
Igor_67
Найдите лучше книжки Н. И. Заеца по ПИКам. Как раз для вас - куча живых примеров на PIC16F84(A), PIC16F628 и некоторых других посложнее ( с АЦП)...

Re: Помогите с PIC16F84А пожалуста

Добавлено: Сб апр 17, 2010 19:33:35
Chettuser
никак не пойму почему стек вылетает :((( Хоть плачь!!! :kill: :cry:
Вроде переполнения не допускаю...

Re: Помогите с PIC16F84А пожалуста

Добавлено: Вс апр 18, 2010 10:54:01
uldemir
А откуда вы знаете что вылетает стек? в 16f84-м нет встроенного контроля стека. Если в отладчике - так в отладчике и смотрите.
Telepathic module not installed. Так как ничего больше не дано, то только общие советы - не делайте переходы внутрь подрограмм и не используйте в обработчиках прерываний переходы в основное тело. И не советую из обработчика прерываний вызывать подпрограмму вызываемую из основного тела программы. И еще, из моего недавнего опыта - всегда в обработчике прерываний снимайте флаг запроса того прерывания, которое обрабатываете.

Re: Помогите с PIC16F84А пожалуста

Добавлено: Вс апр 18, 2010 12:06:40
Chettuser
Сорри, я про отладчик конечно же :)
Видимо последнее из Ваших советов больше подходит под ситуацию. Спасибо!
ЗЫ: Совсем без переходов внутрь подпрограмм не всегда получается, увы. Вынужден следить за стеком в отладчике. (он как взбесился - перелетает с 2-й строки на последнюю). Буду думать дальше.