Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
30.03.2007, 00:11
|
|
Прописка
Регистрация: 19.10.2006
Сообщений: 112
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
|
pic16f870 - Помогите разобраться с таймерами
Помогите разобраться или хотя бы подскажите в каком направлении идти.
Задача :
Нужно сделать таймер считающий посекундно (пока что только до 9).
Вопросы:
1) Можно ли это реализовать без подключения внешнего тактового генератора.
2) Какие именно регистры (кроме OPTION_REG) нужно использовать.
3) Есть какие-нибудь конкретные примеры с таймером (на минуты или секунды).
4) Какой лучше всего использовать таймер (TMR0, TMR1 или TMR2).
Заранее спасибо !!!
|
|
|
|
30.03.2007, 09:55
|
|
Почётный гражданин KAZUS.RU
Регистрация: 12.05.2006
Адрес: Владимир
Сообщений: 2,806
Сказал спасибо: 3,022
Сказали Спасибо 4,233 раз(а) в 1,192 сообщении(ях)
|
1. Конечно можно! Есть несколько вариантов. И даже без использования таймеров вообще (организовать циклы в программе), но с использованием таймеров программа паралельно с отмером времени таймерами может заниматься ещё чем-то, если это требуется.
----------------
2. Странный вопрос... Ответ: это зависит от того, какой способ счёта импульсов будет выбран, какой таймер, и даже какой кварцевый резонатор. В примере ниже будет видно какие регистры были затронуты. Пример вовсе не претендует на идеальность, можете критиковать! Но вот я сделал так.
----------------
4. Сначала ответ на 4 вопрос: какие свободны таймеры, такие и можно использовать. Но при высокочастотном кварце длительные интервалы времени лучше реализовать на таймере, который всех больше задержку может организовать, плюс добавить дополнительные программные регистры для увеличения этого времени (см. пример).
Далее символами "CLK" обозначим время приращения каждого из этих таймеров на единичку, то есть например при кварцевом резонаторе 20 МГц это время будет 4*(1/20000000) = 0,2 мкс. В вашем случае, если микроконтроллер не занимается ничем другим высокоскоростным, лучше применить низкочастотный кварцевый резонатор, например 32768Гц от любых электронных часов, при этом пересчитать всё в примере ниже. Для кварца 32768Гц значение CLK будет 4*(1/3276 ![Горд собой](images/smilies/icon_dovl.gif) = 122,0703125 мкс. Далее о возможностях таймеров:
TMR0 = CLK * 256(таймер 8 бит) * 256(максимальный делитель для таймера, если этот делитель не используется для WDT) = 0,0131072 сек при кварце 20МГц, 8 сек при кварце 32768Гц
TMR1 = CLK * 65536(таймер 16 бит) * 8(максимальный делитель для таймера) = 0,1048576 сек при кварце 20МГц, 64 сек при кварце 32768Гц
TMR2 = CLK * 256(таймер 8 бит) * 16(максимальный предделитель для таймера) * 16(максимальный постделитель для таймера) = 0,0131072 сек при кварце 20МГц, 8 сек при кварце 32768Гц
Таким образом, TMR1 предпочтительней использовать при высокочастотном кварце, при низкочастотном всё равно какой. Учтите: включаются и выключаются таймеры 1 и 2, таймер 0 считает постоянно, управлять его включением-выключением в своей программе (файл макросов) я решил при помощи битов разрешения прерывания.
----------------
3. Простите, уважаемый, что не разжую ответ на этот вопрос. Пример у меня есть только для использования высокочастотного кварца, а именно 20 МГц. Скачайте приложенный файл (в архиве не все файлы моего проекта, но для разбора таймеров хватит).
das321d.asm - основной компилируемый файл
init321d.inc - тут инициализируются устройства, регистры в начале программы. Смотреть тут про таймеры.
int321d.inc - файл где описывается, что делать в случае возникновения прерываний. В своей программе я использую только TMR1, другие в файле прерываний не описаны.
mac321d.inc - файл описания макросов. Тут таймеры запускаются и останавливаются.
com01.inc - тут есть пример. Ближе к концу этого файла есть вызов макроса запуска таймера.
----------------
Прикрепленный файл: 4514583.rar
|
|
|
|
30.03.2007, 14:57
|
|
Прохожий
Регистрация: 24.07.2005
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
1. да, применив кварцевый резонатор.
2,3,4. как вариант
Код:
|
;Fosc=4MHz
goto aaa
org 0x0004
‹...› ;сохраняем w,status,pclath(=0)
bcf PIR1_TMR1IF ;сброс флага прерывания по переполнению TMR1
decfsz TMR1HH,1
goto intend
‹...ABC...› ;секунда истекла... предпринимаем меры
bcf T1CON_TMR1ON ;TMR1 выключен
‹...›
установка TMR1 (возможно применение табличной выборки значений для отсчета,
меняя динамику сработки ‹...ABC...› ):
- если кусок ‹...ABC...› по м.ц. линеен, то в TMR1HH:TMR1H:TMR1L помещаем
фикс. значения (с учетом смещения) ;
- если не линеен, то через вычисления, на основе текущего значения TMR1,
корректируем TMR1HH:TMR1H:TMR1L .
‹...›
bsf T1CON_TMR1ON ;инициируем отсчет
intend
‹...› ;восстанавливаем pclath,status,w
retfie
aaa
‹...›
clrf INTCON ;прерывания запрещены
clrf PIR1 ;
clrf PIR2 ;
bsf STATUS_RP0 ;
clrf PIE1 ;
clrf PIE2 ;
bcf STATUS_RP0 ;
clrf CCP1CON
clrf CCP2CON
clrf T1CON ;TMR1 выключен 1:1 Fosc/4
movlw 0xc0 ;загрузка таймера TMR1HH:TMR1H:TMR1L
movwf TMR1L ;65536*15+16960=1сек
movlw 0xbd ;варьируем значениями для сработки ‹...ABC...›
movwf TMR1H ;при 1:1 max=16.7сек при 1:8 max=2.13мин
movlw 0x10 ;мало?! доводим до 32 разрядов
movwf TMR1HH ;
bsf INTCON_GIE ;прерывания разрешены
bsf STATUS_RP0 ;прерывание по переполнению TMR1 разрешено
bsf PIE1_TMR1IE ;
bcf STATUS_RP0 ;
bsf T1CON_TMR1ON ;TMR1 включен
‹...› ;руки развязаны и мы творим чудеса |
|
|
|
|
30.03.2007, 20:53
|
|
Прописка
Регистрация: 19.10.2006
Сообщений: 112
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
|
T-34 и dimmich большое вам спасибо. Щас буду разбираться и выбирать наилучший вариант
|
|
|
|
03.04.2007, 21:02
|
|
Прописка
Регистрация: 19.10.2006
Сообщений: 112
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
|
Сообщение от T-34
|
1. да, применив кварцевый резонатор.
2,3,4. как вариант
Код:
|
;Fosc=4MHz
goto aaa
org 0x0004
‹...› ;сохраняем w,status,pclath(=0)
bcf PIR1_TMR1IF ;сброс флага прерывания по переполнению TMR1
decfsz TMR1HH,1
goto intend
‹...ABC...› ;секунда истекла... предпринимаем меры
bcf T1CON_TMR1ON ;TMR1 выключен
‹...›
установка TMR1 (возможно применение табличной выборки значений для отсчета,
меняя динамику сработки ‹...ABC...› ):
- если кусок ‹...ABC...› по м.ц. линеен, то в TMR1HH:TMR1H:TMR1L помещаем
фикс. значения (с учетом смещения) ;
- если не линеен, то через вычисления, на основе текущего значения TMR1,
корректируем TMR1HH:TMR1H:TMR1L .
‹...›
bsf T1CON_TMR1ON ;инициируем отсчет
intend
‹...› ;восстанавливаем pclath,status,w
retfie
aaa
‹...›
clrf INTCON ;прерывания запрещены
clrf PIR1 ;
clrf PIR2 ;
bsf STATUS_RP0 ;
clrf PIE1 ;
clrf PIE2 ;
bcf STATUS_RP0 ;
clrf CCP1CON
clrf CCP2CON
clrf T1CON ;TMR1 выключен 1:1 Fosc/4
movlw 0xc0 ;загрузка таймера TMR1HH:TMR1H:TMR1L
movwf TMR1L ;65536*15+16960=1сек
movlw 0xbd ;варьируем значениями для сработки ‹...ABC...›
movwf TMR1H ;при 1:1 max=16.7сек при 1:8 max=2.13мин
movlw 0x10 ;мало?! доводим до 32 разрядов
movwf TMR1HH ;
bsf INTCON_GIE ;прерывания разрешены
bsf STATUS_RP0 ;прерывание по переполнению TMR1 разрешено
bsf PIE1_TMR1IE ;
bcf STATUS_RP0 ;
bsf T1CON_TMR1ON ;TMR1 включен
‹...› ;руки развязаны и мы творим чудеса |
|
Не могу найти TMR1HH и CCP2CON
|
|
|
|
04.04.2007, 10:00
|
|
Почётный гражданин KAZUS.RU
Регистрация: 12.05.2006
Адрес: Владимир
Сообщений: 2,806
Сказал спасибо: 3,022
Сказали Спасибо 4,233 раз(а) в 1,192 сообщении(ях)
|
В его примере регистр TMR1HH выполняет ту же функцию, что и у меня Tmr1Reg1 и Tmr1Reg2 (два регистра потребовалось, потому что у меня кварц более высокочастотный). И мои и его регистры - программные, их нужно создать в начале программы. Я свой блок описания регистров приложил (в начале основного компилируемого файла они описаны). В своём примере bopohok видимо отрезал кусок описания регистров.
В его примере видимо использовался другой контроллер. В pic16f870 нет регистра CCP2CON. В моём примере тоже МК другой - pic16f628. Просто исключай строки с этими регистрами. При составлении своей программы начни с инициализации всех подобных управляющих периферией регистров: отключи ненужные модули, таймеры, вобщем задай свою конфигурацию микроконтроллера. Прям возьми даташит на свой МК, и каждый встретившийся регистр для управления какими-то устройствами проинициализируй в нужные тебе значения. Посмотри как это сделал например я в файле init321d.inc, только регистры и/или биты в регистрах у тебя могут быть другими. Смотри свой даташит.
Не забывай при написании программы всегда помнить в каком банке памяти сейчас находишься, и переключай банк при обращении к регистру, если он находится в другом банке памяти.
|
|
|
|
04.04.2007, 16:49
|
|
Прописка
Регистрация: 19.10.2006
Сообщений: 112
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
|
Спасибо dimmich.
Я исправил старый код и добавил ещё одну кнопку на обнуление (точнее на 9, т.к. таймер считает с девяти до нуля) и выход на светодиод (всё время чтобы горел). Когда запуская МК на табло высвечивается 0, как только обнуляю на табло появляется 9 и всё время горит ![Очень злюсь](images/smilies/icon_evil.gif) .
Думаю что ошибка в где-то в прерывании.
Код:
|
list p=16f870 ; list directive to define processor
include ‹p16f870.inc› ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_OFF & _CPD_OFF
;***** VARIABLE DEFINITIONS
w_temp EQU 0x71 ; variable used for context saving
status_temp EQU 0x72 ; variable used for context saving
TMR1HH EQU 0x20
NINE EQU 0x21 ; 4islo ot kotorogo s4et4ik budet otnimatj
;************************************************* *********************
ORG 0x0
clrf PCLATH ; ensure page bits are cleared
goto start
;-----------------------------------------------------------------------------
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
bcf STATUS, RP1 ; RP1=0 switch to BANK0
bcf STATUS, RP0 ; RP0=0
bcf PIR1,TMR1IF ;
decfsz TMR1HH,1
goto intend
bcf T1CON,TMR1ON ;
;vivod na indikator
decfsz NINE,1
goto cleaner
goto next
cleaner
movlw b'1001'
movwf NINE
next
movlw NINE
movwf PORTB
movlw 0xda ;
movwf TMR1L ;
movlw 0xB4 ;
movwf TMR1H ; TMR1 = 0xB4C0 + 26 = 0xB4DA
movlw 0x4c ;
movwf TMR1HH ; TMR1HH = 76 (4C)
bsf T1CON,TMR1ON ;
intend ;
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;-----------------------------------------------------------------------------
start
bcf STATUS, RP1 ; RP1=0
bcf STATUS, RP0 ; RP0=0
clrf INTCON ;
clrf PIR1 ;
clrf PIR2 ;
bsf STATUS, RP0 ; to BANK1
clrf PIE1 ;
clrf PIE2 ;
bcf STATUS,RP0 ; to BANK0
clrf CCP1CON ;
clrf T1CON ;
movlw 0xc0 ;
movwf TMR1L ;
movlw 0xb4 ;
movwf TMR1H ; TMR1 = 0xB4C0
movlw 0x4c ;
movwf TMR1HH ; TMR1HH = 76 (4C)
bsf INTCON,GIE ;
bsf STATUS,RP0 ; to BANK1
bsf PIE1,TMR1IE ;
bcf STATUS,RP0 ; to BANK0
bsf T1CON,TMR1ON ;
movlw b'11010000' ; RB0-RB3 - na indikator, RB4 - na knopku obnulenija, RB5- vse vremja gora6ij diod
bsf STATUS,RP0 ; to BANK1
movwf TRISB ;
bcf STATUS,RP0 ; to BANK0
movlw b'1001'
movwf NINE
bsf PORTB,5
;-----------------------------------------------------------------------------
cikl
bcf STATUS,RP0 ; to BANK0
bcf STATUS,RP1 ; to BANK0
BTFSS PORTB, 4 ; esli 5 bit v registre PORTB raven edinice to sled. po kodu instrukcija propuskaetsa
goto cikl
movlw b'1001'
movwf NINE
movwf PORTB
goto cikl
end |
|
|
|
|
05.04.2007, 06:54
|
|
Прохожий
Регистрация: 24.07.2005
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Код:
|
‹...int...›
;vivod na indikator
decf NINE,1
movf NINE,0
movwf PORTB
movlw 0xda ;уточнить!!!
movwf TMR1L ;
movlw 0xB4 ;
movwf TMR1H ; TMR1 = 0xB4C0 + 26 = 0xB4DA
movlw 0x4c+1 ;
movwf TMR1HH ; TMR1HH = 76 (4C)
‹...›
‹...›
movlw b'11010000' ; RB0-RB3 - indikator, RB4 - knopka, RB5- diod
bsf INTCON,GIE ;
bsf INTCON,PEIE ;
bsf STATUS,RP0 ; to BANK1
bsf PIE1,TMR1IE ;
movwf TRISB ;
bcf STATUS,RP0 ; to BANK0
cikl
bsf PORTB,5
clrf T1CON
movlw 0xc0 ;уточнить!!!
movwf TMR1L ;
movlw 0xb4 ;
movwf TMR1H ; TMR1 = 0xB4C0
movlw 0x4c+1 ;
movwf TMR1HH ; TMR1HH = 76 (4C)
movlw b'1001'
movwf NINE
BTFSS PORTB,4 ;ожидание
goto $-1 ;
bsf T1CON,TMR1ON
bcf PORTB,5
movwf PORTB
movf NINE,1
btfss STATUS,Z
goto $-2
goto cikl
end |
|
|
|
|
05.04.2007, 14:21
|
|
Прописка
Регистрация: 19.10.2006
Сообщений: 112
Сказал спасибо: 0
Сказали Спасибо 2 раз(а) в 1 сообщении
|
dimmich и T-34 спасибо ещё раз .
Наконец разобрался с таймером, всё работает ![Валяюсь от смеха](images/smilies/icon_biggrin.gif) Прикладываю сам код, кому надо - берите
Ещё раз повторяю этот код для pic16f870 (с кварцем на 20 МГц) считает (через дешифратор) от 9 до 0 и по новому. Если надо можно обнулить кнопкой (RC5 если память не изменяет).
Прикрепленный файл: 8232614.rar
|
|
|
|
02.05.2007, 16:50
|
|
Временная регистрация
Регистрация: 29.08.2006
Сообщений: 54
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Прошу помощи!! Вообщем дела такое есть НЕХ для PIC16F877. Пытался получить АSM разными прогами, то что получал обратно в НЕХ выдавало ошибки. Вот сообственно вопрос как это сделать MPlab?? И если кто разбирается в дизассемблировании, попробуйте сделать файл, и потом проверить. Прилепил НЕХ.
Заранее, благодарен.
Прикрепленный файл: 7407769.zip
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 11:47.
|
|