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

Контроллер нагрузки

Добавлено: Сб мар 15, 2014 15:06:56
lucifern
Здравствуйте,коты! Есть такая задача сделать примитивную схему включения\отключения нагрузки одной кнопкой.Есть куча схем на таймерах, транзисторах и реле, я их всех перепробовал. На таймере работает нестабильно, на других элементах меня не устроило. Где-то видел в обучающей литературе по программированию PIC простые схемы подобные моей, но не смог найти.Хотел Вас попросить написать программу для pic12f629 или 675, которая управляет тремя нагрузками . Алгоритм такой: при кратковременном нажатии кнопки s1 (s2,s3) включается и фиксируется нагрузка 1 (2,3). При повторном нажатии нагрузка отключается. Это устройство планирую использовать как универсальное,поэтому требуется,чтобы контроллер мог управлять нагрузками низким уровнем "0" и высоким "1" по входу.Соответственно нужно ,я так понимаю, две прошивки для "0" и "1". Не знаю как для этого контроллера возможно или нет сделать так же режим с памятью, который при пропадании питания и его включении мог бы запоминать исходные уровни на своем выходе? Например,я включил первую нагрузку.на каком то этапе пропало питание контроллера и нагрузка первая соответственно выключилась, для того чтобы ее повторно не включать мне при появлении питании,контроллер сам выставляет по выходу тот уровень ,который был при отключении. Схему проекта прилагаю.

Re: Контроллер нагрузки

Добавлено: Сб мар 15, 2014 16:34:46
Zhuk72
1. Правые выводы S4-S6 должны быть притянуты к массе через резисторы.
2. Найдите в сети обучающий исходник на эти ПИКи (или на всеми любимые 16Ф84), в котором по нажатию кнопки зажигают и тушат светодиод.
3. Проанализируйте код и скопируйте нужный кусок на 2 другие кнопки.
4. Добавьте опрос кнопок.
5. Когда все это заработает (на макете или в Протеусе), добавьте в начало программы считывание из ЕЕПРОМ состояния ключей и внесение этих данных при их изменении.

Не считая пункта 5, для новичка это как раз хороший пример обучиться программированию. По ходу разбирательства с кодом спрашивайте, ответим, поможем. А когда с 4-мя пунктами разберетесь, то и 5-й будет под силу.

Re: Контроллер нагрузки

Добавлено: Сб мар 15, 2014 16:46:20
CaseBot
Сам пока еще учусь кодить для пиков на асме, но кое-что наваял.. Если совсем нет желания заводить дружбу с пиками (а дружить с ними очень даже интересно), то могу скопировать в ветку..

Однако, прав Zhuk72, лучше научиться самому.. Я, если нужно, тоже готов поделиться своими скромными знаниями..

Re: Контроллер нагрузки

Добавлено: Сб мар 15, 2014 21:45:59
lucifern
CaseBot писал(а): готов поделиться своими скромными знаниями..
Выложи что есть

Re: Контроллер нагрузки

Добавлено: Сб мар 15, 2014 23:42:24
CaseBot
Наваял на скорую руку, только проверить негде: ни пика ни протеуса под рукой нет..
Если код окажется работоспособным, добавлю сохранение..
Только четвертую ногу нужно прижать к плюсу питания через резистор.. Выходы переключаются прижатием к земле противоположной лапки МК.. При удерживании кнопки в нажатом положении ничего не происходит, переключение совершается только при переходе из высокого уровня в низкий и более никак..
Спойлер

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

        LIST        P=12F629
        __CONFIG    0X3F84
        INCLUDE     "P12F629.INC"
;---------------------------------------
RESW	EQU		0X20
RESS	EQU		0X21
GP_PREV	EQU		0X22
;---------------------------------------
		ORG     0
		BSF     STATUS, RP0		;BANK 1
        MOVLW   B'00000111'		;PRESCALER VARIABLE
        GOTO    INIT
;---------------------------------------
        ORG     4   			;INTERRUPT
		MOVWF	RESW
		MOVF	STATUS, W
		MOVWF	RESS

		BTFSC	GP_PREV, 3		;TEST BUTTON 3
		BTFSC	GPIO, 3
		GOTO	GPTEST4
		BTFSS	GP_PREV, 2
		BSF		GPIO, 2
		BTFSC	GP_PREV, 2
		BCF		GPIO, 2

GPTEST4	BTFSC	GP_PREV, 4		;TEST BUTTON 2
		BTFSC	GPIO, 4
		GOTO	GPTEST5
		BTFSS	GP_PREV, 1
		BSF		GPIO, 1
		BTFSC	GP_PREV, 1
		BCF		GPIO, 1

GPTEST5	BTFSC	GP_PREV, 5		;TEST BUTTON 1
		BTFSC	GPIO, 5
		GOTO	ENDPROC
		BTFSS	GP_PREV, 0
		BSF		GPIO, 0
		BTFSC	GP_PREV, 0
		BCF		GPIO, 0
		
ENDPROC	MOVF	GPIO, W
		MOVWF	GP_PREV			;SAVE GPIO
		BCF		INTCON, T0IF	;CLEAR INTERRUPT FLAG

		MOVF	RESS, W
		MOVWF	STATUS
		MOVF	RESW, W
		RETFIE
;---------------------------------------
INIT	MOVWF   OPTION_REG		;TMR0 PRESCALER IS 1:256
		MOVLW   B'10100000'		;INTERRUPN ON
        MOVWF   INTCON			;TMR0 ONLY
        MOVLW   B'00111000'		;GP0..2 DIGITAL OUT
        MOVWF   TRISIO			;GP3..5 DIGITAL IN
		MOVLW	B'00110000'		;PULL-UP FOR GP4, GP5
		MOVWF	WPU
		BCF		STATUS, RP0		;BANK 0
		MOVLW	B'00000111'
		MOVWF	CMCON			;COMPARATOR OFF
		MOVF	GPIO, W
		MOVWF	GP_PREV			;SAVE GPIO

LOOP	NOP
		GOTO	LOOP			;INFINITY CYCLE

		END

Re: Контроллер нагрузки

Добавлено: Вт мар 18, 2014 09:49:47
BOB51
Была раньше конструкция светик и кнопа на одном выводе.
knop.JPG
(5.65 КБ) 699 скачиваний
Обрабатывалась и индикация на светике + транзистор (типа горит непрерывно/мигает с разными периодами свечения/погасания) и собственно сама кнопа. Правда реализация для mcs51.
Только вот с фиксацией значения через EEPROM при каждом нажатии... У оной ограниченный ресурс. Возможно фиксацию статуса нагрузки "по включении" есть смысл делать отдельной кнопой или использовыть резерв-источник на батарейке или ионисторе используя для хранения регистры ОЗУ - у пиков весьма малое потребление даже в рабочем состоянии + контроль питающего на встроенном компараторе собрать можно.
:roll:

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 05:31:14
lucifern
CaseBot, все работает! :) Только 7 нога при включении имеет высокий уровень,нужно чтобы был "0". Думаю,это легко исправить,код" GOTO ENDPROC" изменить на "GOTO GPTEST3",указав его в начале,то есть зациклить. Теперь можно и с памятью поэксперементировать ;)

Чтобы можно было управлять высоким уровнем,то какая команда должна быть в коде?С низким уровнем,я так понял,"BTFSC".Получается высокий "BTFSS" ?

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 09:35:13
BOB51
Вообще-то управляющий сигнал с "высоким" уровнем принято считать некорректным - равноценно "обрыву" цепи управления ("КЗ" встречается гораздо реже и его влияние элементарно устраняется сканером кнопок при начальной процедуре тестирования устройства при включении питания). 8)

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 11:06:15
Zhuk72
lucifern писал(а):CaseBot, все работает! :) Только 7 нога при включении имеет высокий уровень,нужно чтобы был "0". Думаю,это легко исправить,код" GOTO ENDPROC" изменить на "GOTO GPTEST3",указав его в начале,то есть зациклить. Теперь можно и с памятью поэксперементировать ;)

Чтобы можно было управлять высоким уровнем,то какая команда должна быть в коде?С низким уровнем,я так понял,"BTFSC".Получается высокий "BTFSS" ?
ENDPROC - это выход из прерывания, в нем нельзя зацикливаться, указывая "GOTO GPTEST3".
Кроме того сохранение W и STATUS в прерывании сделано некорректно. Правильно так:
Спойлерorg4
MOVWF RESW
SWAPF STATUS,W
MOVWF RESS
.....
опрос кнопок
...
SWAPF RESS,W
MOVWF STATUS
SWAPF RESW,F
SWAPF RESW,W
RETFIE
Чтобы 7 нога (GP0) при включении была в 0, нужно в начале инициализации очистить порт от случайных значений командой CLRF GPIO, чего сейчас нет. Кроме того перед инициализацией WPU не был переключен банк. Следовательно кусок INIT должен выглядеть так:
СпойлерINIT MOVWF OPTION_REG ;TMR0 PRESCALER IS 1:256
MOVLW B'10100000' ;INTERRUPN ON
MOVWF INTCON ;TMR0 ONLY
CLRF GPIO
MOVLW B'00111000' ;GP0..2 DIGITAL OUT
MOVWF TRISIO ;GP3..5 DIGITAL IN
BSF STATUS,RP0 ; BANK1
MOVLW B'00110000' ;PULL-UP FOR GP4, GP5
MOVWF WPU
BCF STATUS, RP0 ;BANK 0
MOVLW B'00000111'
MOVWF CMCON ;COMPARATOR OFF
MOVF GPIO, W
MOVWF GP_PREV ;SAVE GPIO
Опрос кнопок настолько запутан, что даже не стал выяснять, как это все работает. Просто совет автору кода: в начале кода директивами #DEFINE задавать понятные имена кнопкам (S1-S3) и соответствующим им нагрузками (L1-L3) и в коде оперировать ими (пример упрощенный без фильтрации дребезга):
Спойлер#define S1 GPIO,5
#define S2 GPIO,4
#define S3 GPIO,3
#define L1 GPIO,0
#define L2 GPIO,1
#define L3 GPIO,2
#define GPL1 GP_PREV,0
#define GPL2 GP_PREV,1
#define GPL3 GP_PREV,2

; Test S1
btfsc S1
goto $+6
btfss GPL1
bsf L1
btfsc GPL1
bcf L1
goto ENDPROC
; Test S2
btfsc S2
goto $+6
btfss GPL2
bsf L2
btfsc GPL2
bcf L2
goto ENDPROC
; Test S3
btfsc S3
goto ENDPROC
btfss GPL3
bsf L3
btfsc GPL3
bcf L3
; Процедура выхода из прерывания
ENDPROC
......
При таком написании отчетливо видно соответствие кнопок и нагрузок. Кроме того, если понадобится поменять местами выводы (речь не конкретно об этом проекте), то это достаточно будет сделать в одном месте, в начале, не бегая по всему листу, который может содержать не одну тысячу строк.

Если управление будет не нулем, а единицей, то в опросе кнопок 3 команды btfsc Sх надо заменить на btfss S3 и, как я говорил раньше, правые выводы S4-S6 должны быть притянуты к массе через резисторы.


Добавлено через минуту:
Только что разглядел переключение в банк 1 и загрузку константы в W в начале кода после org 0. Зачем так разбивать инициализацию? Достаточно только goto INIT, а то ненароком можете залезть и в прерывания на 4-й адрес.

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 12:06:12
BOB51
Zhuk72 писал(а): Добавлено через минуту:
Только что разглядел переключение в банк 1 и загрузку константы в W в начале кода после org 0. Зачем так разбивать инициализацию? Достаточно только goto INIT, а то ненароком можете залезть и в прерывания на 4-й адрес.
Загрузка константы в OSCCAL является обязательной операцией при работе со встроенным RC генератором (см. даташит).
Предпочтение :
BSF STATUS, RP0 ; Банк 1
CALL 3FFh ; Загрузить калибровочную константу
MOVWF OSCCAL
goto init
однако можно и в самом ините вставить, если стабильность стартовой частоты некритична.
Ну и само-собой следить, чтоб случайно это RETLW XX не затереть... 8)
:beer:

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 13:01:59
Zhuk72
Да, про константу я забыл упомянуть, но тут она роли не играет, т.к. временно-зависимые процедуры отсутствуют.
А вот автор темы скорее всего уже затер константу :) Теперь нужно либо что-то средне-приемлемое туда вписать, либо восстанавливать посредством PICKIT2.

А вообще в дополнении я имел в виду, что в начале пишется

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

      ORG     0
      BSF     STATUS, RP0      ;BANK 1
        MOVLW   B'00000111'      ;PRESCALER VARIABLE
        GOTO    INIT
а потом в INIT'е пишется

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

INIT
          MOVWF   OPTION_REG      ;TMR0 PRESCALER IS 1:256
          ........... и т.д.
т.е. процедура инициализации получается разорванной на части.

Re: Контроллер нагрузки

Добавлено: Ср мар 19, 2014 20:45:48
lucifern
:) я ничего не затер. Я только промоделировал в Протеусе. Просьба, не расписывайте что и куда и как правильно надо,я так с ходу не разберусь. Пожалуйста,автор прошивки, исправьте как необходимо сделать и скомпилируйте код. и чтобы не затер констатнту ,предусмотрите этот момент также. Я уже имел опыт ее восстанавливать)

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 07:33:18
lucifern
Ребята, откомпилируйте мне исправленный код программы,пожалуйста. Я уже молчу про память...

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 08:37:42
Zhuk72
Чуть позже сделаю и выложу.

Вот, пробуйте. Проект под МПЛАБ Х и исходник здесь для наглядности.
Честно говоря, неохота было рисовать и проверять в Протеусе, но вроде все должно работать.

Некоторые замечания по проекту. Прерывания исключил. Зачем для опроса 3-х кнопок использовать таймер в железке, которая ничем не занята, и к тому же делать это каждые 65 мс, когда их можно проверять, грубо говоря, каждые 10 мкс? Второе: внутренние подтягивающие резисторы отключил, т.к. они все равно будут висеть только на двух кнопках из трех (на GP3 они не подключаются). Поэтому выводы МК, используемые для кнопок подтяните к питанию через резисторы. И, наконец, по поводу ЕЕПРОМ. Осталось добавить запись и считывание одного регистра, в исходнике это указано, но сейчас не могу, свои дела ждут. Кроме того я давно это не делал, поэтому надо копаться и читать ДШ. Может кто-то другой компетентный в этом вопросе добавит.
Спойлер

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

;***************************************
;                                      *
;     Фигнюшка для трех нагрузок :)    *
;                                      *
;***************************************
    list        P=12F629
    __CONFIG _INTRC_OSC_NOCLKOUT & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _BODEN_OFF & _CP_OFF & _CPD_OFF
    include     "P12F629.INC"
    errorlevel -302
;---------------------------------------
    CBLOCK      0x20

gp_stat
CounterA
CounterB

    ENDC
;---------------------------------------
        #define S1      GPIO,5
        #define S2      GPIO,4
        #define S3      GPIO,3
        #define L1      GPIO,0
        #define L2      GPIO,1
        #define L3      GPIO,2
        #define GPL1    gp_stat,0
        #define GPL2    gp_stat,1
        #define GPL3    gp_stat,2
;---------------------------------------
        org     0
        goto    init
;---------------------------------------
        org     0x4
        nop
;---------------------------------------
init
        call    0x3ff
        bsf     STATUS, RP0
        movwf   OSCCAL
        movlw   b'10000111'     ; Pull-ups disabled (7), TMR0 1:256 (2-0)
        movwf   OPTION_REG
        clrf    INTCON          ; Interrupts off
        movlw   b'00111000'     ; GP0-GP2 out, GP3-GP5 in
        movwf   TRISIO
        clrf    WPU             ; Pull-ups off
        clrf    IOC             ; Interrupt-on-change off
        bcf     STATUS, RP0
        movlw   b'00000111'
        movwf   CMCON           ; COMPARATOR OFF
;------------------------------------------------------------------------
        clrf    GPIO
        call    saveport
; Вместо двух предыдущих команд надо будет прописать процедуру считывания
; из EEPROM предыдущего состояния порта.
;------------------------------------------------------------------------
loop1
        movf    GPIO,f          ; Фиксируем состояние порта
        ; Test S1
        btfsc   S1              ; Проверка кнопки
        goto    loop2           ; Если не нажата, проверяем следующую,
        call    delay5ms        ; иначе осуществляем антидребезг,
        btfsc   S1              ; проверяем повторно.
        goto    loop2           ; В случае ошибочного срабатывания проверяем другую.
        btfss   S1              ; Ожидаем отпускание кнопки
        goto    $-1             ; перед тем, как исполнить команду.
        btfss   GPL1            ; Проверяем предыдущее состояние порта.
        bsf     L1              ; Включаем нагрузку, если была отключена.
        btfsc   GPL1            ; Eсли же была включена,
        bcf     L1              ; отключаем ее.
        call    saveport        ; Сохраняем состояние порта
        goto    loop1
loop2
        ; Test S2
        btfsc   S2
        goto    loop3
        call    delay5ms
        btfsc   S2
        goto    loop3
        btfss   S2
        goto    $-1
        btfss   GPL2
        bsf     L2
        btfsc   GPL2
        bcf     L2
        call    saveport
        goto    loop1
loop3
        ; Test S3
        btfsc   S3
        goto    loop1
        call    delay5ms
        btfsc   S3
        goto    loop1
        btfss   S3
        goto    $-1
        btfss   GPL3
        bsf     L3
        btfsc   GPL3
        bcf     L3
        call    saveport
        goto    loop1

;**********************************
;           Подпрограммы          *
;**********************************
saveport
        movf    GPIO,w
        movwf   gp_stat
; Здесь надо добавить процедуру записи gp_stat в EEPROM.
        return

;PIC Time Delay = 0.00500100 s with Osc = 4000000 Hz
delay5ms
		movlw	D'7'
		movwf	CounterB
		movlw	D'124'
		movwf	CounterA
loop
        decfsz	CounterA,1
		goto	loop
		decfsz	CounterB,1
		goto	loop
		retlw	0
;**********************************
;        Конец подпрограмм        *
;**********************************

        org     0x3ff
        retlw   0                   ; Сюда можно вписать считанную константу

        end

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 12:10:48
iGraphicsS
Если хотите, за шоколадку наваяю) Ниже подпрограммы работы с EEPROM на PIC16F1825

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

EEPROM_RD	NOP		;ЧТЕНИЕ ИЗ EEPROM ПО АДРЕСУ В W
	BANKSEL EEADRL
	MOVWF EEADRL		
	BCF EECON1,6
	BCF EECON1,7
	BSF EECON1,0
	MOVFW EEDATL	                        ;РЕЗУЛЬТАТ В W
	RETURN	
EEPROM_WR	NOP		;ЗАПИСЬ В EEPROM ПО АДРЕСУ В W И ДАННЫМИ В TEMP (РЕГИСТР В ОЗУ)
	BANKSEL EEADRL
	MOVWF EEADRL
	MOVFW TEMP
	MOVWF EEDATL
	BCF EECON1,6
	BCF EECON1,7
	BSF EECON1,2
	MOVLW 55h
	MOVWF EECON2
	MOVLW 0AAh
	MOVWF EECON2
	BSF EECON1,1
	BCF EECON1,2	
        
	RETURN

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 12:46:36
lucifern
память для предыдущего состояния выходов контроллера нужна,чтобы при выключении\включении питания данный контроллер выставлял рабочий режим управляемого оборудования. За шоколадку согласен)

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 12:57:30
Zhuk72
Все-таки нарисовал схемку в Протеусе. Но почему-то не работает :)
Если выполнить пошагово, то видно, как он включает светодиод, а после команды movf GPIO,w в W грузится не реальное значение порта, а предыдущее, и светодиод отключается. Грешил на защелку порта, сделал перед ней movf GPIO,f , но все равно, несмотря на правильное состояние порта в дебаг окне, после этих команд порт возвращается предыдущее.
В архив добавил схему.

Глюк Протеуса или я напортачил где-то?

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 14:36:05
CaseBot
Не было возможности раньше ответить..
Так вооот..
Zhuk72 писал(а):сохранение W и STATUS в прерывании сделано некорректно.
Не особо понимаю зачем менять местами полубайты, и в даташите тоже так же указано.. Делаю как для себя понятнее.. В принципе, здесь значения можно даже не сохранять, все равно они нигде не используются и не изменяются..
Zhuk72 писал(а):Зачем так разбивать инициализацию? Достаточно только goto INIT, а то ненароком можете залезть и в прерывания на 4-й адрес.
У меня всё под контролем 8) даже еще одно место под инструкцию по адресу 0x03 осталось
Zhuk72 писал(а):Опрос кнопок настолько запутан, что даже не стал выяснять, как это все работает.
Когда наступает прерывание (кстати я его использовал для того, чтобы легче было изменять интервал, и заодно реализуется эдакий фильтр дребезга, да и всё равно намеренно нажать и отпустить кнопку за 65 мс не так-то просто), текущее значение каждой кнопки сравнивается с предыдущим состоянием, и только если эта кнопка была в высоком состоянии, а теперь в низком, то тогда переключается состояние соответствующего выхода.. после всех опросов и сравнений сохраняется текущее состояние как предыдущее..
Имена кнопкам не давал, т.к. код не сильно большой, думал, и так понятно.. да и писал "на скорую руку"..

Добавил в свой код сохранение и загрузку предыдущего состояния выходов, но опять-таки проверить работоспособность не на чем..
Значение OSCCAL не стал записывать (мало ли, может, уже выставлено корректное значение)..

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 14:50:38
КРАМ
CaseBot писал(а):Не особо понимаю зачем менять местами полубайты, и в даташите тоже так же указано.. Делаю как для себя понятнее..
MOVF RESS, W
MOVWF STATUS <--- тут мы STATUS восстановили
MOVF RESW, W <--- а тут мы STATUS испортили
RETFIE
В отличии от команды movf, команда swapf НЕ ИЗМЕНЯЕТ регистр STATUS.

Re: Контроллер нагрузки

Добавлено: Пт мар 21, 2014 15:03:20
CaseBot
КРАМ писал(а):В отличии от команды movf, команда swapf НЕ ИЗМЕНЯЕТ регистр STATUS.
Теперь ясно, буду знать..