Здравствуйте,коты! Есть такая задача сделать примитивную схему включения\отключения нагрузки одной кнопкой.Есть куча схем на таймерах, транзисторах и реле, я их всех перепробовал. На таймере работает нестабильно, на других элементах меня не устроило. Где-то видел в обучающей литературе по программированию PIC простые схемы подобные моей, но не смог найти.Хотел Вас попросить написать программу для pic12f629 или 675, которая управляет тремя нагрузками . Алгоритм такой: при кратковременном нажатии кнопки s1 (s2,s3) включается и фиксируется нагрузка 1 (2,3). При повторном нажатии нагрузка отключается. Это устройство планирую использовать как универсальное,поэтому требуется,чтобы контроллер мог управлять нагрузками низким уровнем "0" и высоким "1" по входу.Соответственно нужно ,я так понимаю, две прошивки для "0" и "1". Не знаю как для этого контроллера возможно или нет сделать так же режим с памятью, который при пропадании питания и его включении мог бы запоминать исходные уровни на своем выходе? Например,я включил первую нагрузку.на каком то этапе пропало питание контроллера и нагрузка первая соответственно выключилась, для того чтобы ее повторно не включать мне при появлении питании,контроллер сам выставляет по выходу тот уровень ,который был при отключении. Схему проекта прилагаю.
1. Правые выводы S4-S6 должны быть притянуты к массе через резисторы. 2. Найдите в сети обучающий исходник на эти ПИКи (или на всеми любимые 16Ф84), в котором по нажатию кнопки зажигают и тушат светодиод. 3. Проанализируйте код и скопируйте нужный кусок на 2 другие кнопки. 4. Добавьте опрос кнопок. 5. Когда все это заработает (на макете или в Протеусе), добавьте в начало программы считывание из ЕЕПРОМ состояния ключей и внесение этих данных при их изменении.
Не считая пункта 5, для новичка это как раз хороший пример обучиться программированию. По ходу разбирательства с кодом спрашивайте, ответим, поможем. А когда с 4-мя пунктами разберетесь, то и 5-й будет под силу.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Сам пока еще учусь кодить для пиков на асме, но кое-что наваял.. Если совсем нет желания заводить дружбу с пиками (а дружить с ними очень даже интересно), то могу скопировать в ветку..
Однако, прав Zhuk72, лучше научиться самому.. Я, если нужно, тоже готов поделиться своими скромными знаниями..
Открыта удобная площадка с выгодными ценами, поставляющая весь ассортимент продукции, производимой компанией MEAN WELL – от завоевавших популярность и известных на рынке изделий до новинок. MEAN WELL.Market предоставляет гарантийную и сервисную поддержку, удобный подбор продукции, оперативную доставку по России.
На сайте интернет-магазина посетители смогут найти обзоры, интересные статьи о применении, максимальный объем технических сведений.
Наваял на скорую руку, только проверить негде: ни пика ни протеуса под рукой нет.. Если код окажется работоспособным, добавлю сохранение.. Только четвертую ногу нужно прижать к плюсу питания через резистор.. Выходы переключаются прижатием к земле противоположной лапки МК.. При удерживании кнопки в нажатом положении ничего не происходит, переключение совершается только при переходе из высокого уровня в низкий и более никак..
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
Продукция MOSO предназначена в основном для индустриальных приложений, использует инновационные решения на основе более 200 собственных патентов для силовой электроники и соответствует международным стандартам. LED-драйверы MOSO применяются в системах наружного освещения разных отраслей, включая промышленность, сельское хозяйство, транспорт и железную дорогу. В ряде серий реализована возможность дистанционного контроля и программирования работы по заданному сценарию. Разберем решения MOSO
подробнее>>
Обрабатывалась и индикация на светике + транзистор (типа горит непрерывно/мигает с разными периодами свечения/погасания) и собственно сама кнопа. Правда реализация для mcs51. Только вот с фиксацией значения через EEPROM при каждом нажатии... У оной ограниченный ресурс. Возможно фиксацию статуса нагрузки "по включении" есть смысл делать отдельной кнопой или использовыть резерв-источник на батарейке или ионисторе используя для хранения регистры ОЗУ - у пиков весьма малое потребление даже в рабочем состоянии + контроль питающего на встроенном компараторе собрать можно.
CaseBot, все работает! Только 7 нога при включении имеет высокий уровень,нужно чтобы был "0". Думаю,это легко исправить,код" GOTO ENDPROC" изменить на "GOTO GPTEST3",указав его в начале,то есть зациклить. Теперь можно и с памятью поэксперементировать
Чтобы можно было управлять высоким уровнем,то какая команда должна быть в коде?С низким уровнем,я так понял,"BTFSC".Получается высокий "BTFSS" ?
Вообще-то управляющий сигнал с "высоким" уровнем принято считать некорректным - равноценно "обрыву" цепи управления ("КЗ" встречается гораздо реже и его влияние элементарно устраняется сканером кнопок при начальной процедуре тестирования устройства при включении питания).
CaseBot, все работает! Только 7 нога при включении имеет высокий уровень,нужно чтобы был "0". Думаю,это легко исправить,код" GOTO ENDPROC" изменить на "GOTO GPTEST3",указав его в начале,то есть зациклить. Теперь можно и с памятью поэксперементировать
Чтобы можно было управлять высоким уровнем,то какая команда должна быть в коде?С низким уровнем,я так понял,"BTFSC".Получается высокий "BTFSS" ?
ENDPROC - это выход из прерывания, в нем нельзя зацикливаться, указывая "GOTO GPTEST3". Кроме того сохранение W и STATUS в прерывании сделано некорректно. Правильно так:
Чтобы 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) и в коде оперировать ими (пример упрощенный без фильтрации дребезга):
; 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-й адрес.
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Добавлено через минуту: Только что разглядел переключение в банк 1 и загрузку константы в W в начале кода после org 0. Зачем так разбивать инициализацию? Достаточно только goto INIT, а то ненароком можете залезть и в прерывания на 4-й адрес.
Загрузка константы в OSCCAL является обязательной операцией при работе со встроенным RC генератором (см. даташит). Предпочтение : BSF STATUS, RP0 ; Банк 1 CALL 3FFh ; Загрузить калибровочную константу MOVWF OSCCAL goto init однако можно и в самом ините вставить, если стабильность стартовой частоты некритична. Ну и само-собой следить, чтоб случайно это RETLW XX не затереть...
Да, про константу я забыл упомянуть, но тут она роли не играет, т.к. временно-зависимые процедуры отсутствуют. А вот автор темы скорее всего уже затер константу Теперь нужно либо что-то средне-приемлемое туда вписать, либо восстанавливать посредством PICKIT2.
А вообще в дополнении я имел в виду, что в начале пишется
я ничего не затер. Я только промоделировал в Протеусе. Просьба, не расписывайте что и куда и как правильно надо,я так с ходу не разберусь. Пожалуйста,автор прошивки, исправьте как необходимо сделать и скомпилируйте код. и чтобы не затер констатнту ,предусмотрите этот момент также. Я уже имел опыт ее восстанавливать)
Вот, пробуйте. Проект под МПЛАБ Х и исходник здесь для наглядности. Честно говоря, неохота было рисовать и проверять в Протеусе, но вроде все должно работать.
Некоторые замечания по проекту. Прерывания исключил. Зачем для опроса 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
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
память для предыдущего состояния выходов контроллера нужна,чтобы при выключении\включении питания данный контроллер выставлял рабочий режим управляемого оборудования. За шоколадку согласен)
Все-таки нарисовал схемку в Протеусе. Но почему-то не работает Если выполнить пошагово, то видно, как он включает светодиод, а после команды movf GPIO,w в W грузится не реальное значение порта, а предыдущее, и светодиод отключается. Грешил на защелку порта, сделал перед ней movf GPIO,f , но все равно, несмотря на правильное состояние порта в дебаг окне, после этих команд порт возвращается предыдущее. В архив добавил схему.
Глюк Протеуса или я напортачил где-то?
_________________ Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
сохранение W и STATUS в прерывании сделано некорректно.
Не особо понимаю зачем менять местами полубайты, и в даташите тоже так же указано.. Делаю как для себя понятнее.. В принципе, здесь значения можно даже не сохранять, все равно они нигде не используются и не изменяются..
Zhuk72 писал(а):
Зачем так разбивать инициализацию? Достаточно только goto INIT, а то ненароком можете залезть и в прерывания на 4-й адрес.
У меня всё под контролем даже еще одно место под инструкцию по адресу 0x03 осталось
Zhuk72 писал(а):
Опрос кнопок настолько запутан, что даже не стал выяснять, как это все работает.
Когда наступает прерывание (кстати я его использовал для того, чтобы легче было изменять интервал, и заодно реализуется эдакий фильтр дребезга, да и всё равно намеренно нажать и отпустить кнопку за 65 мс не так-то просто), текущее значение каждой кнопки сравнивается с предыдущим состоянием, и только если эта кнопка была в высоком состоянии, а теперь в низком, то тогда переключается состояние соответствующего выхода.. после всех опросов и сравнений сохраняется текущее состояние как предыдущее.. Имена кнопкам не давал, т.к. код не сильно большой, думал, и так понятно.. да и писал "на скорую руку"..
Добавил в свой код сохранение и загрузку предыдущего состояния выходов, но опять-таки проверить работоспособность не на чем.. Значение OSCCAL не стал записывать (мало ли, может, уже выставлено корректное значение)..
Не особо понимаю зачем менять местами полубайты, и в даташите тоже так же указано.. Делаю как для себя понятнее..
MOVF RESS, W MOVWF STATUS <--- тут мы STATUS восстановили MOVF RESW, W <--- а тут мы STATUS испортили RETFIE В отличии от команды movf, команда swapf НЕ ИЗМЕНЯЕТ регистр STATUS.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения