Заголовок сообщения: Помогите чайнику с таймером на PIC16F84a
Добавлено: Пт апр 23, 2010 08:38:28
Родился
Зарегистрирован: Пт мар 20, 2009 08:46:44 Сообщений: 13
Рейтинг сообщения:0
Собрал я таймер на мк , работает замечательно. Но вот беда диапозон времени не тот что нужен. В данном таймере диапазон от 0-90 мин а мне нужно от 1- 12 часов. Как это сделать? Какие изменения нужно внести в программу? Прошу вашей помощи.
; ;***************** Основной код******************************* ; ORG 0 ;Программа начинается с метки 'Main' goto Main ORG 4 ;Вектор прерывания goto Int_Prog
; ;**************** Начальная инициализация ******************* ; Main clrf PORTA ;Очистить выходные защелки порта А clrf PORTB ; и порта В clrf TMR0 ;Очистить таймер bsf STATUS,RP0 ;Открыть доступ к банку 1 movlw M_O_INIT ;Загрузить исходные movwf OPTION_REG^80H ; данные в OPTION_REG movlw M_TA_INIT ;Настроить порт А movwf TRISA^80H ; movlw M_TB_INIT ;Настроить порт В movwf TRISB^80H ; bcf STATUS,RP0 ;Включить банк 0 movlw M_I_INIT ;Загрузить исходные movwf INTCON ; данные в INTCON movlw M_FLAG_INIT ;Загрузить исходные movwf Flags ; данные в ячейку Flags clrf R_Bits ;Очистить R_Bits Test bcf INTCON,7 ;Запрет прерываний movlw b'10000000' ;Вывод на LSB(HG1) индикатор цифры 8 movwf PORTB bsf PORTA,0 call Delay_1s ;Пауза 1сек bsf PORTA,1 ;Вывод на MSB индикатор(HG2) цифры 8 call Delay_1s ;Пауза 1сек clrf PORTA ;Порты в исходное состояние clrf PORTB clrf N ;Обнулить N bsf PORTA,TMR_Run First_Pass call One_Shot ;Пробное измерение, зарядка конденсатора call Delay_100ms ;Задержка 0,1сек
; ;****************** Установка времени выдержки таймера********************** ;
Get_Time bsf Flags,Phase ;Признак режима установки bcf INTCON,7 ;Запрет прерываний
call One_Shot ;Подсчет числа 'N' импульсов разрядки movlw 0x03 ;Запись ст. байта адреса таблицы movwf PCLATH ; преобразования в PCLATH movf N,w call Convert ;Таблица преобразования movwf R_Bits ;Хранение результата преобразования clrf PCLATH ;PCLATH в исходное состояние call Bin_to_BCD ;Перекодирование в BCD код bsf INTCON,7 ;Разрешить прерывания
; ;****************** Проверка состояния кнопки SB1 ************************** ;
Check_SB1 btfsc PORTA,TMR_On ;Пока кнопка не нажата- goto Get_Time ; таймер в режиме установки call Delay_100ms bcf Flags,Phase ;Установить признак работы таймера на счет call Delay_1s ;Задержка, необходимая для отпускания SB1
Time_Count bsf PORTA,TMR_Run ;Транзистор VT1 закрыт btfss PORTA,TMR_On ;Сброс таймера при повторном нажатии goto Reset_TMR ; на SB1 movfw Int_Count_High ;Сравнение счетчика прерываний с 15000 xorlw 0x3A ; (3A98hex),что соответствует 1мин. btfss STATUS,Z goto Time_Count movfw Int_Count_Low sublw 0x97 btfsc STATUS,C goto Time_Count ;Если 1мин не закончилась-продолжить счет decf R_Bits,f ;R_Bits=R_Bits-1. Если установленное btfsc STATUS,Z ; время закончилось (R_Bits=0), установить bsf Flags,Phase ; признак окончания работы таймера call Bin_to_BCD ;Преобразование R_Bits в BCD-код btfss Flags,Phase ;Если таймер в режиме счета- goto Timer_On ; идти на продолжение счета времени
Timer_Stop call Delay_1s call Beep bsf PORTA,TMR_Run ;Транзистор VT1 закрыт Reset_TMR call Delay_1s clrf R_Bits ;Обнулить счетчик времени clrf Int_Count_Low ; и прерываний clrf Int_Count_High bsf Flags,Phase ;Флаг режима установки=1 call Delay_100ms goto Get_Time ;Идти на установку
; ;******** Подпрограмма преобразования двоичного кода в BCD-код ********* ; Двоичный код в регистре R_Bits, после преобразования в Digit_0 ; - единицы, в Digit_1 - десятки.
А в чем должна выражаться помощь? Ну ладно, помогу. Слово "Помагите" правильно пишется "помогите". Если хотите получить от прерывания 250 мкс интервалы, то в прерывании лучше не присваивать значение 6 TMR0, а прибавлять (во-первых вы не можете гарантировать, что в прерывание вошли именно на переходе FF->00, а не позже, во-вторых, к моменту присвоения в прерывании уже выполнено по меньшей мере 8 команд). Кстати, прибавлять надо не 6.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Я (и большинство других, наверняка) не телепат. Если можно, поконкретнее. У вас есть исходник, разберитесь в нем, и измените как вам надо. В чем проблема то?
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Хоть бы схему привёл или исходник откуда содрана. Автор может увидит тут исходник без ссылки на него - обидится. Вообще мне видится два варианта изменения. Первый забить таблицу Convert числами от 1 до 12 (равномерно) и в Timer_On и в Int_prog сделать измерение интервала в один час. Тогда можно выставить число от 1 до 12 и получить желаемое.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Ладно, если уж начал вникать - вот лекарство. В процедуре Int_prog удлинил минуту в 60 раз. Насчет точности этой минуты меня гложут сомнения, но пусть это останентся на совести автора. Я ведь даже не знаю какой частоты кварц применен. Таблицу Convert можно не перебивать - будет крутой таймер с выдержкой от 1 до 90 часов.
Вызов подпрограммы , да еще табличной конвертации, в прерывании . .. Что то отвернуло даже анализировать далее сей "шедевр".
А почему нет? Я, лично, так тоже делаю. Мне не жаль подарить один уровень стека из 8. И, кстати, человек делает динамическую индикацию в прерывании, а не так другие писатели шедевров с задержками в основном теле программы. Зато, он не вызывает эту конвертацию из других мест. Шедевр, если вникнуться, написан неплохо. Хотя и есть спорные моменты. Как я уже сразу написал, не нравится присвоение в прерывании от TMR0. Это место, где постоянно будет накапливаться ошибка. Но каждый пишет по-своему. Я так не пишу. Но это не значит, что другие не имеют права так писать.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
И, кстати, человек делает динамическую индикацию в прерывании, а не так другие писатели шедевров с задержками в основном теле программы.
А конвертировать нужно обязательно в прерывании ???? В прерывании нужен счетчик( секунд,минут , часов и т.д. ) , обработчик кнопок , вывод из буфера на индикацию со сканером разрядов. И все . И никаких пп. там на.. не нужно. Задержки вообще зло- тратить процессорное время впустую ...
вывод из буфера на индикацию со сканером разрядов.
Ну вот это там и делается. и ничего больше. Или предлагаешь в буфере держать полный имидж? Я дак еще в буфере бывает храню аттрибут что этот разряд должен моргать, и в этом же прерывании это моргание и обсчитывается. Так что этот приём считаю рациональным.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
В основном цикле заполнять буфер уже сконвертированными данными . Буфер 2 байта . Bin2BCD конвертите же в главном цикле , почему в 7 сегментный код надо в прерывании ????????? Скажу по секрету эта ваша любимая BIN2BCD здесь вообще на.. не нужна . Под мигание и еще под кучку флагов можно и отдельные переменные завести . А вообще не плохо было бы перелопатить все это на посегментную индикацию , жрать будет меньше и не надо ключей.
Да нет, нафик не сдалось. Просто размышляю, почему автор так безобразно время меряет. В минуте автор отсчитывает 15000 прерываний. Значит прерывание предполагается раз в 4 миллисекунды. По регистру option указано, что коэффициент предделителя 16. получается что за 4000 микросекунд должно пройти 4000+8+3 импульсов. Короч, точность не ахти какая. Ошибка около 0,3% или я чегой-то не понимаю. Или там кварц на 4011 кГц (где такой взять?). Хотя для таймера на полтора часа такая ошибка была приемлима и что-либо особенное городить не было смысла.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Заголовок сообщения: Re: Помогите чайнику с таймером на PIC16F84a
Добавлено: Сб апр 24, 2010 11:18:20
Прорезались зубы
Зарегистрирован: Вт сен 30, 2008 09:23:14 Сообщений: 209 Откуда: Краснодарский край
Рейтинг сообщения:0
Судя по описанию это Кухонный таймер из Журнала Радио. Номер, на вскидку, не скажу. Я такой собрал, полезная штука. Там переменником регулируется время от 0 до 90 мин. У меня не было нужного сопрота, я поставил другой и максимальное время у меня 70 мин. Если мне надо 1ч40 мин. я его включаю дважды. Вроде полезная штука. Особенно когда фоторезист засветить или мясо пожарить.)))) Кварц 4 Мгц.
; ;***************** Основной код******************************* ; ORG 0 ;Программа начинается с метки 'Main' goto Main ORG 4 ;Вектор прерывания goto Int_Prog
; ;**************** Начальная инициализация ******************* ; Main clrf PORTA ;Очистить выходные защелки порта А clrf PORTB ; и порта В clrf TMR0 ;Очистить таймер bsf STATUS,RP0 ;Открыть доступ к банку 1 movlw M_O_INIT ;Загрузить исходные movwf OPTION_REG^80H ; данные в OPTION_REG movlw M_TA_INIT ;Настроить порт А movwf TRISA^80H ; movlw M_TB_INIT ;Настроить порт В movwf TRISB^80H ; bcf STATUS,RP0 ;Включить банк 0 movlw M_I_INIT ;Загрузить исходные movwf INTCON ; данные в INTCON movlw M_FLAG_INIT ;Загрузить исходные movwf Flags ; данные в ячейку Flags clrf R_Bits ;Очистить R_Bits Test bcf INTCON,7 ;Запрет прерываний movlw b'10000000' ;Вывод на LSB(HG1) индикатор цифры 8 movwf PORTB bsf PORTA,0 call Delay_1s ;Пауза 1сек bsf PORTA,1 ;Вывод на MSB индикатор(HG2) цифры 8 call Delay_1s ;Пауза 1сек clrf PORTA ;Порты в исходное состояние clrf PORTB clrf N ;Обнулить N bsf PORTA,TMR_Run First_Pass call One_Shot ;Пробное измерение, зарядка конденсатора call Delay_100ms ;Задержка 0,1сек
; ;****************** Установка времени выдержки таймера********************** ;
Get_Time bsf Flags,Phase ;Признак режима установки bcf INTCON,7 ;Запрет прерываний
call One_Shot ;Подсчет числа 'N' импульсов разрядки movlw 0x03 ;Запись ст. байта адреса таблицы movwf PCLATH ; преобразования в PCLATH movf N,w call Convert ;Таблица преобразования movwf R_Bits ;Хранение результата преобразования clrf PCLATH ;PCLATH в исходное состояние call Bin_to_BCD ;Перекодирование в BCD код bsf INTCON,7 ;Разрешить прерывания
; ;****************** Проверка состояния кнопки SB1 ************************** ;
Check_SB1 btfsc PORTA,TMR_On ;Пока кнопка не нажата- goto Get_Time ; таймер в режиме установки call Delay_100ms bcf Flags,Phase ;Установить признак работы таймера на счет call Delay_1s ;Задержка, необходимая для отпускания SB1
Time_Count bsf PORTA,TMR_Run ;Транзистор VT1 закрыт btfss PORTA,TMR_On ;Сброс таймера при повторном нажатии goto Reset_TMR ; на SB1 movfw Int_Count_High ;Сравнение счетчика прерываний с 15000 xorlw 0x3A ; (3A98hex),что соответствует 1мин. btfss STATUS,Z goto Time_Count movfw Int_Count_Low sublw 0x97 btfsc STATUS,C goto Time_Count ;Если 1мин не закончилась-продолжить счет decf R_Bits,f ;R_Bits=R_Bits-1. Если установленное btfsc STATUS,Z ; время закончилось (R_Bits=0), установить bsf Flags,Phase ; признак окончания работы таймера call Bin_to_BCD ;Преобразование R_Bits в BCD-код btfss Flags,Phase ;Если таймер в режиме счета- goto Timer_On ; идти на продолжение счета времени
Timer_Stop call Delay_1s call Beep bsf PORTA,TMR_Run ;Транзистор VT1 закрыт Reset_TMR call Delay_1s clrf R_Bits ;Обнулить счетчик времени clrf Int_Count_Low ; и прерываний clrf Int_Count_High bsf Flags,Phase ;Флаг режима установки=1 call Delay_100ms goto Get_Time ;Идти на установку
; ;******** Подпрограмма преобразования двоичного кода в BCD-код ********* ; Двоичный код в регистре R_Bits, после преобразования в Digit_0 ; - единицы, в Digit_1 - десятки.
Rrrrrrrrr. Не надо постить такие огромные листинги. тем более 3 раза, тем более в таком нечитабельном виде. кстати, я там бред написал. Начал писать инкрементирующий счетчик и закончил мыслью декрементирующего счетчика. в конце надо присваивать не 60, а ноль.
Код:
incf int_count_pre movlw 60 subwf int_count_pre, w btfss status, c goto Indicate clrf int_cout_pre
А адрес любой свободный в нулевой странице. Наприме следующий свободный 0x20.
_________________ А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения