Страница 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/80 ... ocont.djvu

2. http://ds1.twirpx.com/files/011/11761_Y ... o_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-й строки на последнюю). Буду думать дальше.