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

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 4
Зарегистрирован: Чт сен 20, 2007 07:06:45

Сообщение 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 сек.
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 487
Зарегистрирован: Чт ноя 23, 2006 22:47:35

Сообщение 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.
Контактная информация:
Реклама
Родился
Сообщения: 4
Зарегистрирован: Чт сен 20, 2007 07:06:45

Сообщение zaman »

Pahan писал(а): Да, кстати конструкция
ORG 4
GOTO INT
INT ......

в данном случае абсолютно бессмыслена. GOTO не нужен. Он будет нужен только если подпрограмма прерывания находицо в другом месте. А у тебя она идет сразу за goto.
Понимаю что не нужно, с начало не было, думал без этого не компилируется...
Исправил - компилируется, а как правильно организовать прерывание раз в секунду, так и не понял... помогите можалуста
Встал на лапы
Аватара пользователя
Сообщения: 85
Зарегистрирован: Пт май 26, 2006 23:28:37
Откуда: Харьков

Сообщение yaroslav »

Для часов вообще лучше применять часовой кварц на 32768 Гц
Вот, например, почитайте: http://pic.borda.ru/?1-2-40-00000042-000-0-0
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 4
Зарегистрирован: Чт сен 20, 2007 07:06:45

Сообщение zaman »

Вот теперь понял.
Нужно поставить кварц на 32,768МГц и предделитель на 128, таймер посчитает до 256 - значит прошла секунда, но ведь у меня контроллер PIC16F84A-04/P , а это значит что он расчитан всеголиш на 4МГц (итак боюсь что работает на 10МГц) Можно ли ставить часовой кварц как тактирующий на весь контроллер? А то мне пятой ноги на порте А жалко :(
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 450
Зарегистрирован: Пт фев 20, 2009 21:45:04
Откуда: Болгария

Сообщение бгкот »

Можно поставить кварц на 4,096 МГц, тоже часто встречаются.
©"Good indian is dead one!"
Контактная информация:
Реклама
Chettuser

Сообщение 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
Последний раз редактировалось Chettuser Вс июл 26, 2009 16:24:18, всего редактировалось 1 раз.
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

movlw - загрузить константу в аккумулятор. :)
Вам нужно movf c1,w
Контактная информация:
Мучитель микросхем
Аватара пользователя
Сообщения: 487
Зарегистрирован: Чт ноя 23, 2006 22:47:35

Сообщение Pahan »

movlw c1
загружаецо не значение c1, а адрес регистра c1
Контактная информация:
Chettuser

Сообщение Chettuser »

(чтото схемка не прикрепилась...)
Спасибо всем кто откликнулся :), но...

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

Сообщение Chettuser »

zaman писал(а):Вот теперь понял.
Нужно поставить кварц на 32,768МГц ... , но ведь у меня контроллер PIC16F84A-04/P , а это значит что он расчитан всеголиш на 4МГц... Можно ли ставить часовой кварц как тактирующий на весь контроллер? :(
32 768 Герц или 32,768 кГц - кажется ошибочка/опечатка? Ставить можно, это же много меньше 4МГц...
Я, кстати, ставил часовой кварц - работает, только там кажется надо будет в режиме выставить LP (у Вас сейчас XT, но это я так... на всякий случай). :)) )
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

Chettuser писал(а): incf c1,f - это, как я понимаю, c1=c1+1, почему то не работает, а нужно...
Оно работает, просто конкретно у Вас - невнимательность - Вы в коде не обозначили область начала регистров общего назначения
Вместо
cblock
c1
c2
endc

cblock 0x0c
c1
c2
endc

:)
Контактная информация:
Chettuser

Сообщение 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: Жаль... ссылки сдохли...
Последний раз редактировалось Chettuser Чт янв 07, 2010 15:16:00, всего редактировалось 1 раз.
Chettuser

Сообщение Chettuser »

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

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

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

if key> .2
goto aa
else
goto bb
endif

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

Еще раз прошу сильно новичка не пинать - я сам учусь... и пытаюсь сам разобраться в данной проблеме, но нигде про это ненаписано :cry: (я даже незнаю - можно ли применять IF в программе, или только как директиву для управления самой программой?)
Спасибо.
Электрический кот
Аватара пользователя
Сообщения: 1051
Зарегистрирован: Вт окт 21, 2008 11:46:23
Откуда: Барнаул

Сообщение Igor_67 »

Найдите лучше книжки Н. И. Заеца по ПИКам. Как раз для вас - куча живых примеров на PIC16F84(A), PIC16F628 и некоторых других посложнее ( с АЦП)...
Цапу крутить надо!!! Ку или не ку?
Chettuser

Сообщение Chettuser »

никак не пойму почему стек вылетает :((( Хоть плачь!!! :kill: :cry:
Вроде переполнения не допускаю...
Друг Кота
Аватара пользователя
Сообщения: 7365
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

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

Сообщение Chettuser »

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

Вернуться в «Микроконтроллеры и ПЛИС»