О сайте: |
Pic.Rkniga.ru - Сайт как для начинающих, так и для опытных радиолюбителей, разрабатывающих свои устройства на популярных PIC микроконтроллерах. Здесь можно обмениваться сообщениями на форуме, а также добавлять на сайт статьи и схемы своих устройств.
|
|
|
|
|
Вопрос по прерываниям, Не могу реализовать подпрограмму прерываний как надо. Помогите, опытны |
|
Mikado |
20 декабря 2014 19:17
|
Новичок
Репутация: 0
Группа: Посетители
Сообщений: 3
Регистрация: 20.12.2014
ICQ:--
|
Здравствуйте. Полагаю, что вопрос вам покажется примитивным, но я весь день убил - ниасилил. Задача простая, на вывод контроллера зацеплен зуммер. Нужно сделать так, чтобы зуммер пищал в течении 1 секунды с частотой f1, а в течении другой секунды с частотой f2. Накидал программу, прошил контроллер, но частота не меняется, вернее она меняется один раз а потом все время одинаковая. Подскажите, что я делаю не так. Скидываю код программы. Надеюсь на вашу помощь, спасибо.
#include p16f873a.inc __CONFIG _HS_OSC ;высокочастотный кварцевый резонатор ORG h'000' ;вектор сброса программы GOTO BEGIN ;переход на начало основной программы ORG h'004' ;вектор прерывания GOTO INT ;переход к обработчику прерываний ;начало основной программы BEGIN: BSF STATUS,RP0 ;переход в первый банк ;установка режимов работы портов MOVLW b'00001110' MOVWF ADCON1 ;программируем регистр АЦП1 ;вывод RA0/AN0 - настроена как аналоговый вход ;выводы RA1-RA7 - настроены как цифровые каналы ;ввода-вывода. ;зуммер подключен к выводам RA2-RA3 MOVLW b'00000001' MOVWF TRISA ;программируем регистр направления линий RA ;RA0 - настроен на вход, RA1-7 - выход ;установка режима работы TMR1 BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00110000' MOVWF T1CON ;установка предделителя 1:8 MOVLW h'0B' ;запись в регистры хранения данных TMR1 MOVWF TMR1H ;числа 3036, получается 8*(65536-3036)=500000 MOVLW h'DC' ;это значение соответствует половине периода MOVWF TMR1L ;T=1сек ;установка режима работы TMR2 MOVLW b'00001111' MOVWF T2CON ;настройка TMR2, предделитель 1:16 BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;выдержка таймера TMR2 устанавливается равной ;половине периода частот 1кГц BCF STATUS,RP0 ;переход в нулевой банк CLRF h'20' ;при выборе первоначальной частоты 1кГц запишем ;0 в регистр 20h, это потребуется для смены частоты ;значение 0 - 1КГц, значение 1 - 2 КГц ;установка разрешения прерываний MOVLW b'11000000' MOVWF INTCON ;глобальное разрешение прерываний GIE=1 BSF STATUS,RP0 ;переход в первый банк MOVLW b'00000011' MOVWF PIE1 ;разрешение прерываний от TMR1, TMR2 ;запуск таймеров BCF STATUS,RP0 ;переход в нулевой банк BSF T1CON,TMR1ON BSF T2CON,TMR2ON ;основная программа M10: BCF STATUS,RP0 ;переход в нулевой банк BSF T1CON,TMR1ON ;BSF T2CON,TMR2ON GOTO M10 ;зацикливаемся здесь
;подрограмма прерываний от переполнения таймеров INT: BCF STATUS,RP0 ;переход в нулевой банк BTFSS PIR1,TMR1IF ;проверка флага прерываний от TMR1 GOTO I10 ;проверка флага прерываний от TMR2 BCF PIR1,TMR1IF ;сброс флага прерываний от таймера 1 MOVLW h'0B' ; MOVWF TMR1H ;Перезапуск таймера 1 MOVLW h'DC' ; MOVWF TMR1L ; BTFSC 20h,RP0 ;режим работы таймера 1КГц? GOTO I30 ;переход к переключению TMR2 в режим 2КГц GOTO I40 ;переход к переключению TMR2 в режим 1Кгц
I30: BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00000011' MOVWF T2CON ;настройка TMR2, предделитель 1:&& BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;задаем период TMR2 = 2КГц BCF STATUS,RP0 ;переход в нулевой банк BCF h'20',RP0 GOTO I10 ;переход к выходу из прерываний
I40: BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00001000' MOVWF T2CON ;настройка TMR2, предделитель 1:&& BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;задаем период TMR2 = 1КГц BSF h'20',RP0 I10: BTFSS PIR1,TMR2IF ;проверка произошла из-за переполнения 2 таймера GOTO I20 ;выход из подпрограммы прерываний BCF STATUS,RP0 ;переход в нулевой банк BCF PIR1,TMR2IF ;сброс флага прерываний от TMR2 BTFSS PORTA,2 ;проверка, что на BZ1 '1' GOTO I50 ;переход к подаче импульса на BZ1 BCF PORTA,2 ;сброс BZ1 в '0' GOTO I20 ;переход к выходу из прерываний
I50: BSF PORTA,2 ;установка на BZ1 в '1'
I20: RETFIE ;выход из программы прерываний
END ;конец программы
В программе частоты в конкретных числах - это не проблема, интересует где именно ошибка, не получается ее выцепить самостоятельно. BZ - зуммер. |
|
|
|
alex |
20 декабря 2014 23:13
|
Активный участник
Репутация: 3
Группа: Администраторы
Сообщений: 107
Регистрация: 13.06.2012
ICQ:--
|
Описывать все найденные ошибки не буду. Останавлюсь на общих: Не настроены биты конфигурации, а точнее сторожевой таймер, который постоянно сбрасывает микроконтроллер. В подпрограммах I30 и I40 происходит выключение таймер T2CON бит 2. Необходимо настроить предделители. Частоту 1 и 2 кГц не подгонял, попробуйте сами. В подпрограмме I40 перед строчкой BSF h'20',RP0 необходимо перейти в первый банк В ассемблере h'20' - так пишутся числа. Адреса пишутся так - 20H. Смотрите приведенный и немного исправленный мною исходный код, поскольку описывать все изменения очень долго. Адрес 20h в тексте программы заменил на Bz1(Bz1 equ 20h). Проверил в протеусе - пиликает. текст программы:
Bz1 equ 20h #include p16f873a.inc __CONFIG 1100000111010 ;_CP_OFF _DEBUG_OFF _WRT_OFF _CPD_OFF _LVP_OFF _BODEN_OFF _PWRTE_OFF _WDT_OFF _HS_OSC ;высокочастотный кварцевый резонатор ORG h'000' ;вектор сброса программы GOTO BEGIN ;переход на начало основной программы ORG h'004' ;вектор прерывания GOTO INT ;переход к обработчику прерываний ;начало основной программы BEGIN: BSF STATUS,RP0 ;переход в первый банк ;установка режимов работы портов MOVLW b'00001110' MOVWF ADCON1 ;программируем регистр АЦП1 ;вывод RA0/AN0 - настроена как аналоговый вход ;выводы RA1-RA7 - настроены как цифровые каналы ;ввода-вывода. ;зуммер подключен к выводам RA2-RA3 MOVLW b'00000001' MOVWF TRISA ;программируем регистр направления линий RA ;RA0 - настроен на вход, RA1-7 - выход ;установка режима работы TMR1 BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00110000' MOVWF T1CON ;установка предделителя 1:8 MOVLW h'0B' ;запись в регистры хранения данных TMR1 MOVWF TMR1H ;числа 3036, получается 8*(65536-3036)=500000 MOVLW h'DC' ;это значение соответствует половине периода MOVWF TMR1L ;T=1сек ;установка режима работы TMR2 MOVLW b'00001100' MOVWF T2CON ;настройка TMR2, предделитель 1:16 BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;выдержка таймера TMR2 устанавливается равной ;половине периода частот 1кГц BCF STATUS,RP0 ;переход в нулевой банк CLRF Bz1 ;при выборе первоначальной частоты 1кГц запишем ;0 в регистр 20h, это потребуется для смены частоты ;значение 0 - 1КГц, значение 1 - 2 КГц ;установка разрешения прерываний MOVLW b'11000000' MOVWF INTCON ;глобальное разрешение прерываний GIE=1 BSF STATUS,RP0 ;переход в первый банк MOVLW b'00000011' MOVWF PIE1 ;разрешение прерываний от TMR1, TMR2 ;запуск таймеров BCF STATUS,RP0 ;переход в нулевой банк BSF T1CON,TMR1ON BSF T2CON,TMR2ON ;основная программа BCF STATUS,RP0 ;переход в нулевой банк M10: nop ;BSF T1CON,TMR1ON ;BSF T2CON,TMR2ON GOTO M10 ;зацикливаемся здесь
;подрограмма прерываний от переполнения таймеров INT: BCF STATUS,RP0 ;переход в нулевой банк BCF STATUS,RP1 BTFSS PIR1,TMR1IF ;проверка флага прерываний от TMR1 GOTO I10 ;проверка флага прерываний от TMR2 BCF PIR1,TMR1IF ;сброс флага прерываний от таймера 1 MOVLW h'0B' ; MOVWF TMR1H ;Перезапуск таймера 1 MOVLW h'DC' ; MOVWF TMR1L ; BTFSC Bz1,RP0 ;режим работы таймера 1КГц? GOTO I30 ;переход к переключению TMR2 в режим 2КГц GOTO I40 ;переход к переключению TMR2 в режим 1Кгц
I30: BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00001100' MOVWF T2CON ;настройка TMR2, предделитель 1:&& BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;задаем период TMR2 = 2КГц BCF STATUS,RP0 ;переход в нулевой банк BCF Bz1,RP0 GOTO I10 ;переход к выходу из прерываний
I40: BCF STATUS,RP0 ;переход в нулевой банк MOVLW b'00011100' MOVWF T2CON ;настройка TMR2, предделитель 1:&& BSF STATUS,RP0 ;переход в первый банк MOVLW d'250' MOVWF PR2 ;задаем период TMR2 = 1КГц BCF STATUS,RP0 BSF Bz1,5
I10: BTFSS PIR1,TMR2IF ;проверка произошла из-за переполнения 2 таймера GOTO I20 ;выход из подпрограммы прерываний BCF STATUS,RP0 ;переход в нулевой банк BCF PIR1,TMR2IF ;сброс флага прерываний от TMR2 BTFSS PORTA,2 ;проверка, что на BZ1 '1' GOTO I50 ;переход к подаче импульса на BZ1 BCF PORTA,2 ;сброс BZ1 в '0' GOTO I20 ;переход к выходу из прерываний
I50: BSF PORTA,2 ;установка на BZ1 в '1'
I20: RETFIE ;выход из программы прерываний
END ;конец программы |
|
|
|
Mikado |
21 декабря 2014 08:18
|
Новичок
Репутация: 0
Группа: Посетители
Сообщений: 3
Регистрация: 20.12.2014
ICQ:--
|
Огромное спасибо Вам! Все работает. Я порадовался, что хоть ошибки и были, но в целом жизнеспособная была программа. Спасибо еще раз за отклик! |
|
|
|
|
|
1чел. читают эту тему (гостей: 1)
Пользователей: 0
Информация
Посетители, находящиеся в группе Гости, не могут оставлять ответы в данном форуме. |
|
|
|
Сейчас: 29 марта 2024 08:50 |
|