Обсуждаем контроллеры компании Atmel.
Ответить

Re: Знатоки ATMega, как настроить таймер?

Пн сен 23, 2013 07:04:19

кусочек кода инициализации покажите, посмотрим где собачка могла порыться...

Re: Знатоки ATMega, как настроить таймер?

Пн сен 23, 2013 16:32:03

Спойлер
Код:
; ПРОБНАЯ 2
.include "m2560def.inc"
.list
.def loop1=R0           ;счетчик 0.1сек
.def loop2=R1           ;счетчик 1.0сек
.def temp1=R16
.def temp2=R20
.def t1=R17      ;кол-во секунд T1
.def t2=R18      ;кол-во секунд T2
; ИНИЦИАЛИЗАЦИЯ
.cseg
.org 0
start:    rjmp RESET   ; СБРОС                              #1
      rjmp STOP           ; внешнее прерывание 0 команда STOP            #2
      reti              ; внешнее прерывание 1                     #3
      reti              ; внешнее прерывание 2                     #4
      reti              ; внешнее прерывание 3                     #5
      reti              ; внешнее прерывание 4                     #6
      reti              ; внешнее прерывание 5                     #7
      reti              ; внешнее прерывание 6                     #8
      reti              ; внешнее прерывание 7                     #9
      rjmp GO      ; внешнее прерывание PCINT0 команда START               #10
      reti              ; внешнее прерывание PCINT1                  #11
      reti              ; внешнее прерывание PCIIN2                        #12
      reti              ; WDT                              #13
      reti              ; TIMER2 COMPA                        #14
      reti              ; TIMER2 COMPB                        #15
      reti              ; TIMER2 OVF                           #16
      reti               ; TIMER1 CAPT                           #17
      rjmp TIMER   ; TIMER1 COMPA                        #18
      reti              ; TIMER1 COMPB                        #19
      reti              ; TIMER1 COMPC                        #20
      reti              ; TIMER1 OVF                           #21
      reti              ; TIMER0 COMPA                        #22
      reti              ; TIMER0 COMPB                        #23
      reti              ; TIMER0 OVF                           #24
      reti              ; SPI, STC                              #25
      reti              ; USART0 RX                           #26
      reti              ; USART0 UDRE                           #27
      reti              ; USART0 TX                           #28
      reti              ; ANALOG COMP                           #29
      reti              ; ADC                              #30
      reti              ; EE READY                           #31
      reti              ; TIMER3 CAPT                           #32
      reti              ; TIMER3 COMPA                        #33
      reti              ; TIMER3 COMPB                        #34
      reti              ; TIMER3 COMPC                        #35
      reti              ; TIMER3 OVF                           #36
      reti              ; USART1 RX                           #37
      reti              ; USART1 UDRE                           #38
      reti              ; USART1 TX                           #39
      reti              ; TWI                              #40
      reti              ; SPM READY                           #41
      reti              ; TIMER4 CAPT                           #42
      reti              ; TIMER4 COMPA                        #43
      reti              ; TIMER4 COMPB                        #44
      reti              ; TIMER4 COMPC                        #45
      reti              ; TIMER4 OVF                           #46
      reti              ; TIMER5 CAPT                           #47
      reti              ; TIMER5 COMPA                        #48
      reti              ; TIMER5 COMPB                        #49
      reti              ; TIMER5 COMPC                        #50
      reti              ; TIMER5 OVF                           #51
      reti              ; USART2 RX                           #52
      reti              ; USART2 UDRE                           #53
      reti              ; USART2 TX                           #54
      reti              ; USART2 RX                           #55
      reti              ; USART2 UDRE                           #56
      reti              ; USART2 TX                           #57
; КОНЕЦ ТАБЛИЦЫ ПРЕРЫВАНИЙ
; ВЕКТОР СБРОСА
RESET:   LDI R16, HIGH(RAMEND)   ;УСТАНОВКА УКАЗАТЕЛЯ СТЕКА SP
      OUT SPH,R16
      LDI R16, LOW(RAMEND)
      OUT SPL,R16
; УСТАНОВКА СЧЕТЧИКА ЗАДЕРЖКИ TC1
      LDI TEMP1,0x05
      LDI TEMP2,0
      STS TCCR1B,TEMP1      ; НАСТРОЙКА ПРЕДДЕЛИТЕЛЯ НА 1024
      STS TCCR1A,TEMP2      ; ОТКЛЮЧЕНИЕ COM1A,COM1B,COM1C,ШИМ
      LDI t1,3            ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК
      MOV loop2,t1         ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2
      LDI TEMP1,0b00000001
      OUT EIMSK,TEMP1      ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0
      LDI TEMP1,2
      STS TIMSK1,TEMP1      ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А
      SEI               ; разрешение прерываний
; НАСТРОЙКА PG НА ВЫХОД
      LDI TEMP1,15         ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР
      OUT DDRG,TEMP1      ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД
      OUT PORTG,TEMP1      ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ)
; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД
      LDI temp1,32         
      LDI temp2,32
      out DDRB,temp1      ; НАСТРОЙКА ПОРТА
OUTPUT:   out PORTB,temp2      ; ВЫВОД В ПОРТ
      nop
      nop
      nop
INPUT:   in temp2,PINB         ; ЧТЕНИЕ ПОРТА Б
      ANDI temp2,1         ; маска для чтения 1го бита по флагу Z
      BRNE SET1         ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ
      LDI temp2,0         ; ноль занесем в порт (зажгем светодиод)
      JMP OUTPUT         ; ВЫВОД НУЛЯ В ПОРТ
SET1:   out PORTB,temp1      ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА
      jmp INPUT            ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА
STOP:   PUSH TEMP1
      PUSH TEMP2
      LDI TEMP1,62         ;
      OUT PORTG,TEMP1      ; ВКЛЮЧАЕМ СИД НА PG0
      LDI TEMP1,0xF
      LDI TEMP2,0x42
      STS OCR1AH,TEMP1      ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК
      STS OCR1AL,TEMP2
      LDI TEMP1,0   
      LDI TEMP2,2         
      STS TCNT1H,TEMP1      ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
      STS TCNT1L,TEMP1      ;
      STS TIMSK1,TEMP2      ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ
      POP TEMP2
      POP TEMP1
      reti
GO:      reti
TIMER:   PUSH TEMP1
      PUSH TEMP2
      CLI
      TST LOOP2         ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z
      BREQ TIM            ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ
      DEC LOOP2         ; УМЕНЬШАЕМ НА 1 LOOP2
      LDI TEMP1,0         ;
      STS TCNT1H,TEMP1      ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
      STS TCNT1L,TEMP1
TIMEND:   POP TEMP2
      POP TEMP1
      SEI
      reti
TIM:           LDI TEMP1,62
      OUT PORTG,TEMP1      ; ГАСИМ СВЕТОДИОД
      MOV loop2,t1         ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД
      CLR TEMP1
      STS TIMSK1,TEMP1      ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1
      JMP TIMEND

Вот такой маленький код. Жмем на кнопку на PB0, программно на РВ5 зажигаем светодиод (это из первого пробного проекта), кроме того, жмем на кнопку на PD0 (INT0), зажигаем светодиод на PG0, должен запуститься таймер ТС1 и по истечении 3сек после отпускания кнопки потушить светодиод на PG0. Все просто. Системаня частота 4МГц от встроенного RC генератора, предделитель 1024.
Насчет таблицы прерываний,вижу косяк,что каждый вектор в памяти занимает 2 байта,потому мое прерывание по INT0 перескакивает джампер на STOP и запускает следующий,расположенный по адресу 0х4 в памяти. Отрезок таблицы векторов из даташита:

Код:
Address     Labels Code    Comments
0x0000      jmp RESET      ; Reset Handler
0x0002      jmp INT0         ; IRQ0 Handler
0x0004      jmp INT1         ; IRQ1 Handler
0x0006      jmp INT2         ; IRQ2 Handler
0x0008      jmp INT3         ; IRQ3 Handler
0x000A      jmp INT4         ; IRQ4 Handler
0x000C      jmp INT5        ; IRQ5 Handler
0x000E      jmp INT6         ; IRQ6 Handler
0x0010      jmp INT7         ; IRQ7 Handler
0x0012      jmp PCINT0     ; PCINT0 Handler


Здесь вектора расположены по конкретным адресам в памяти. Но как внести команды конкретно в эти ячейки? Как правильно написать таблицу в AVRStudio?
Блин,кажись доперло! Нужно вместо rjmp и reti писать jmp т.к. команда jmp имеет размер 32 бита, а не 16 как две предыдущие. Но прерывания от ТС1 все равно не работают...
P.S. извините за то,что все слитно-форматирование текста никак не могу понять здесь :(
Последний раз редактировалось Gudd-Head Ср окт 23, 2013 13:00:23, всего редактировалось 1 раз.
Причина: Нарушение п.2.5 Правил Форума

Re: Знатоки ATMega, как настроить таймер?

Пн сен 23, 2013 17:09:11

Для начала, вставляете текст программы -> выделяете его -> нажимаете тег CODE -> если код длинный дополнительно выделяете с предыдущим тегом и нажимаете тег spoiler.
Спойлер
Код:
; ПРОБНАЯ 2
.include "m2560def.inc"
.list
.def loop1=R0 ;счетчик 0.1сек
.def loop2=R1 ;счетчик 1.0сек
.def temp1=R16
.def temp2=R20
.def t1=R17 ;кол-во секунд T1
.def t2=R18 ;кол-во секунд T2
; ИНИЦИАЛИЗАЦИЯ
.cseg
.org 0
start:
   JMP RESET ; СБРОС #1
   jmp STOP ; внешнее прерывание 0 команда STOP #2
;reti ; внешнее прерывание 1 #3
;reti ; внешнее прерывание 2 #4
;reti ; внешнее прерывание 3 #5
;reti ; внешнее прерывание 4 #6
;reti ; внешнее прерывание 5 #7
;reti ; внешнее прерывание 6 #8
;reti ; внешнее прерывание 7 #9
.org $0012   
   jmp GO ; внешнее прерывание PCINT0 команда START #10
;reti ; внешнее прерывание PCINT1 #11
;reti ; внешнее прерывание PCIIN2 #12
;reti ; WDT #13
;reti ; TIMER2 COMPA #14
;reti ; TIMER2 COMPB #15
;reti ; TIMER2 OVF #16
;reti ; TIMER1 CAPT #17
.org $0022   
   jmp TIMER ; TIMER1 COMPA #18
reti ; TIMER1 COMPB #19
reti ; TIMER1 COMPC #20
reti ; TIMER1 OVF #21
reti ; TIMER0 COMPA #22
reti ; TIMER0 COMPB #23
reti ; TIMER0 OVF #24
reti ; SPI, STC #25
reti ; USART0 RX #26
reti ; USART0 UDRE #27
reti ; USART0 TX #28
reti ; ANALOG COMP #29
reti ; ADC #30
reti ; EE READY #31
reti ; TIMER3 CAPT #32
reti ; TIMER3 COMPA #33
reti ; TIMER3 COMPB #34
reti ; TIMER3 COMPC #35
reti ; TIMER3 OVF #36
reti ; USART1 RX #37
reti ; USART1 UDRE #38
reti ; USART1 TX #39
reti ; TWI #40
reti ; SPM READY #41
reti ; TIMER4 CAPT #42
reti ; TIMER4 COMPA #43
reti ; TIMER4 COMPB #44
reti ; TIMER4 COMPC #45
reti ; TIMER4 OVF #46
reti ; TIMER5 CAPT #47
reti ; TIMER5 COMPA #48
reti ; TIMER5 COMPB #49
reti ; TIMER5 COMPC #50
reti ; TIMER5 OVF #51
reti ; USART2 RX #52
reti ; USART2 UDRE #53
reti ; USART2 TX #54
reti ; USART2 RX #55
reti ; USART2 UDRE #56
reti ; USART2 TX #57
; КОНЕЦ ТАБЛИЦЫ ПРЕРЫВАНИЙ
; ВЕКТОР СБРОСА
RESET:
   LDI R16, HIGH(RAMEND) ;УСТАНОВКА УКАЗАТЕЛЯ СТЕКА SP
   OUT SPH,R16
   LDI R16, LOW(RAMEND)
   OUT SPL,R16
; УСТАНОВКА СЧЕТЧИКА ЗАДЕРЖКИ TC1
LDI TEMP1,0x05
LDI TEMP2,0
STS TCCR1B,TEMP1 ; НАСТРОЙКА ПРЕДДЕЛИТЕЛЯ НА 1024
STS TCCR1A,TEMP2 ; ОТКЛЮЧЕНИЕ COM1A,COM1B,COM1C,ШИМ
LDI t1,3 ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК
MOV loop2,t1 ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2
LDI TEMP1,0b00000001
OUT EIMSK,TEMP1 ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0
LDI TEMP1,2
STS TIMSK1,TEMP1 ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А
SEI ; разрешение прерываний
; НАСТРОЙКА PG НА ВЫХОД
LDI TEMP1,15 ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР
OUT DDRG,TEMP1 ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД
OUT PORTG,TEMP1 ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ)
; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД
LDI temp1,32
LDI temp2,32
out DDRB,temp1 ; НАСТРОЙКА ПОРТА
OUTPUT: out PORTB,temp2 ; ВЫВОД В ПОРТ
nop
nop
nop
INPUT: in temp2,PINB ; ЧТЕНИЕ ПОРТА Б
ANDI temp2,1 ; маска для чтения 1го бита по флагу Z
BRNE SET1 ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ
LDI temp2,0 ; ноль занесем в порт (зажгем светодиод)
JMP OUTPUT ; ВЫВОД НУЛЯ В ПОРТ
SET1: out PORTB,temp1 ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА
jmp INPUT ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА
STOP: PUSH TEMP1
PUSH TEMP2
LDI TEMP1,62 ;
OUT PORTG,TEMP1 ; ВКЛЮЧАЕМ СИД НА PG0
LDI TEMP1,0xF
LDI TEMP2,0x42
STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК
STS OCR1AL,TEMP2
LDI TEMP1,0
LDI TEMP2,2
STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
STS TCNT1L,TEMP1 ;
STS TIMSK1,TEMP2 ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ
POP TEMP2
POP TEMP1
reti
GO: reti
TIMER: PUSH TEMP1
PUSH TEMP2
CLI
TST LOOP2 ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z
BREQ TIM ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ
DEC LOOP2 ; УМЕНЬШАЕМ НА 1 LOOP2
LDI TEMP1,0 ;
STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
STS TCNT1L,TEMP1
TIMEND: POP TEMP2
POP TEMP1
SEI
reti
TIM: LDI TEMP1,62
OUT PORTG,TEMP1 ; ГАСИМ СВЕТОДИОД
MOV loop2,t1 ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД
CLR TEMP1
STS TIMSK1,TEMP1 ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1
JMP TIMEND

Re: Знатоки ATMega, как настроить таймер?

Пн сен 23, 2013 17:13:28

Спасибо,понятно :) А по основному вопросу?

Re: Знатоки ATMega, как настроить таймер?

Пн сен 23, 2013 17:50:46

Спойлер
Код:
; ПРОБНАЯ 2
.include "m2560def.inc"
.list
.def loop1=R0 ;счетчик 0.1сек
.def loop2=R1 ;счетчик 1.0сек
.def temp1=R16
.def temp2=R20
.def t1=R17 ;кол-во секунд T1
.def t2=R18 ;кол-во секунд T2
; ИНИЦИАЛИЗАЦИЯ
.cseg
.org 0
start:
   JMP RESET ; СБРОС #1
   jmp STOP ; внешнее прерывание 0 команда STOP #2
;reti ; внешнее прерывание 1 #3
;reti ; внешнее прерывание 2 #4
;reti ; внешнее прерывание 3 #5
;reti ; внешнее прерывание 4 #6
;reti ; внешнее прерывание 5 #7
;reti ; внешнее прерывание 6 #8
;reti ; внешнее прерывание 7 #9
.org $0012   
   jmp GO ; внешнее прерывание PCINT0 команда START #10
;reti ; внешнее прерывание PCINT1 #11
;reti ; внешнее прерывание PCIIN2 #12
;reti ; WDT #13
;reti ; TIMER2 COMPA #14
;reti ; TIMER2 COMPB #15
;reti ; TIMER2 OVF #16
;reti ; TIMER1 CAPT #17
.org $0022   
   jmp TIMER ; TIMER1 COMPA #18
reti ; TIMER1 COMPB #19
reti ; TIMER1 COMPC #20
reti ; TIMER1 OVF #21
reti ; TIMER0 COMPA #22
reti ; TIMER0 COMPB #23
reti ; TIMER0 OVF #24
reti ; SPI, STC #25
reti ; USART0 RX #26
reti ; USART0 UDRE #27
reti ; USART0 TX #28
reti ; ANALOG COMP #29
reti ; ADC #30
reti ; EE READY #31
reti ; TIMER3 CAPT #32
reti ; TIMER3 COMPA #33
reti ; TIMER3 COMPB #34
reti ; TIMER3 COMPC #35
reti ; TIMER3 OVF #36
reti ; USART1 RX #37
reti ; USART1 UDRE #38
reti ; USART1 TX #39
reti ; TWI #40
reti ; SPM READY #41
reti ; TIMER4 CAPT #42
reti ; TIMER4 COMPA #43
reti ; TIMER4 COMPB #44
reti ; TIMER4 COMPC #45
reti ; TIMER4 OVF #46
reti ; TIMER5 CAPT #47
reti ; TIMER5 COMPA #48
reti ; TIMER5 COMPB #49
reti ; TIMER5 COMPC #50
reti ; TIMER5 OVF #51
reti ; USART2 RX #52
reti ; USART2 UDRE #53
reti ; USART2 TX #54
reti ; USART2 RX #55
reti ; USART2 UDRE #56
reti ; USART2 TX #57
; КОНЕЦ ТАБЛИЦЫ ПРЕРЫВАНИЙ
; ВЕКТОР СБРОСА
RESET:
   LDI R16, HIGH(RAMEND) ;УСТАНОВКА УКАЗАТЕЛЯ СТЕКА SP
   OUT SPH,R16
   LDI R16, LOW(RAMEND)
   OUT SPL,R16
;*************************************************
   LDI   R22,1
   OUT   DDRD,R22
   OUT   PORTD,R22
   CBI   DDRD,0
;*************************************************
; УСТАНОВКА СЧЕТЧИКА ЗАДЕРЖКИ TC1
   LDI TEMP1,0x05
   LDI TEMP2,0
STS TCCR1B,TEMP1 ; НАСТРОЙКА ПРЕДДЕЛИТЕЛЯ НА 1024
STS TCCR1A,TEMP2 ; ОТКЛЮЧЕНИЕ COM1A,COM1B,COM1C,ШИМ

   LDI TEMP1,0x0F
   LDI TEMP2,0x42
   STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК
   STS OCR1AL,TEMP2

LDI t1,3 ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК
MOV loop2,t1 ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2
LDI TEMP1,0b00000001
OUT EIMSK,TEMP1 ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0
LDI TEMP1,2
STS TIMSK1,TEMP1 ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А
;*************************************************
   SER   R22
   OUT   TIFR1,R22   
;*************************************************
;SEI ; разрешение прерываний
; НАСТРОЙКА PG НА ВЫХОД
LDI TEMP1,15 ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР
OUT DDRG,TEMP1 ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД
OUT PORTG,TEMP1 ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ)
; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД
LDI temp1,32
LDI temp2,32
out DDRB,temp1 ; НАСТРОЙКА ПОРТА
OUTPUT: out PORTB,temp2 ; ВЫВОД В ПОРТ
nop
nop
nop
   SEI

INPUT:
   in temp2,PINB ; ЧТЕНИЕ ПОРТА Б
   ANDI temp2,1 ; маска для чтения 1го бита по флагу Z
   BRNE SET1 ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ
   LDI temp2,0 ; ноль занесем в порт (зажгем светодиод)
   JMP OUTPUT ; ВЫВОД НУЛЯ В ПОРТ
SET1:
   out PORTB,temp1 ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА
   Rjmp INPUT ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА

STOP:
   PUSH TEMP1
PUSH TEMP2
LDI TEMP1,62 ;
OUT PORTG,TEMP1 ; ВКЛЮЧАЕМ СИД НА PG0
LDI TEMP1,0xF
LDI TEMP2,0x42
STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК
STS OCR1AL,TEMP2
LDI TEMP1,0
LDI TEMP2,2
STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
STS TCNT1L,TEMP1 ;
STS TIMSK1,TEMP2 ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ
POP TEMP2
POP TEMP1
reti
GO: reti
TIMER:
   PUSH TEMP1
   PUSH TEMP2
;CLI
   TST LOOP2 ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z
   BREQ TIM ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ
   DEC LOOP2 ; УМЕНЬШАЕМ НА 1 LOOP2
   LDI TEMP1,0 ;
   STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1
   STS TCNT1L,TEMP1
TIMEND:
   POP TEMP2
   POP TEMP1
;SEI
   reti
TIM:
   LDI TEMP1,62
   OUT PORTG,TEMP1 ; ГАСИМ СВЕТОДИОД
   MOV loop2,t1 ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД
   CLR TEMP1
   STS TIMSK1,TEMP1 ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1
   JMP TIMEND

В подробности не вдавался; переделал без комментариев. INT0 работает по низкому уровню????? T1 лучше перевести в режим CTC. Исчезаю.

Re: Таймеры/счётчики в AVR

Ср сен 25, 2013 17:15:30

На сайте есть статья http://radiokot.ru/circuit/power/supply/19/
Хочу осилить программу для этого блока самостоятельно. Вроде всё получается, но не понятно следующее. Я задействовал два таймера Т1 и Т2,настроил их на шим режим, соответственно выходы у меня ОС1А и ОС2. А тут вижу что выход на задание напряжения и тока берётся с выводов ОС1А и ОС1В. Но ведь это выходы только с одного таймера Т1. Как можно одним таймером рулить двумя заданиями.

Re: Таймеры/счётчики в AVR

Чт сен 26, 2013 11:58:43

Мужики если я сильно ошибаюсь то укажите где, только ответте плиз.
Последний раз редактировалось chayniks Чт сен 26, 2013 12:36:58, всего редактировалось 1 раз.

Re: Таймеры/счётчики в AVR

Чт сен 26, 2013 12:19:16

Ну так у ШИМ период постоянный, только заполнение разное. У таймера 2 регистра сравнения, и каждый рулит своим выходом. Просто задаете в регистры OCR1A и OCR1B разные значения, и все дела. Таймер будет считать сам по себе от 0 до MAX, а на выходах будет 0 или 1 в зависимости от того что больше: значение в соответствующем регистре сравнения или значение счетчика. Так можно хоть 2 (как тут), хоть 100 (не видел таких, но программно можно) каналов сделать с одним таймером/счетчиком.

Re: Таймеры/счётчики в AVR

Чт сен 26, 2013 12:38:12

А.. Понял. я думал так нельзя.
Получилось спасибо.

Re: Таймеры/счётчики в AVR

Пн окт 07, 2013 15:39:29

Пытаюсь добиться на тиньке13 максимальной и нулевой скважности. С fast PWM не выходит. Вроде как Phase Correct PWM должно получиться. Но никак в толк не возьму, какие биты установить в TCCR0A. Помогите, а

Re: Таймеры/счётчики в AVR

Сб окт 12, 2013 21:46:20

Viper115 писал(а):Пытаюсь добиться на тиньке13 максимальной и нулевой скважности. С fast PWM не выходит. Вроде как Phase Correct PWM должно получиться. Но никак в толк не возьму, какие биты установить в TCCR0A. Помогите, а

WGM(2-0)

помогите с таймером ТС0

Вт окт 15, 2013 18:58:22

Мяу коты.
Голова кипит, а дело на месте стоит не могу разобраться с таймером на тини 13 ТС0. мне нужно во время выполнения программы запустить таймер и по мере счета проверять какое значение он уже насчитал (это без его остановки) затем остановить считать значения. и заново. можете объяснить в какие биты что писать. по возможности с комментариями.



Сюда перенес.

aen

Re: Знатоки ATMega, как настроить таймер?

Вт окт 15, 2013 23:42:47

БАААльшое кошачье спасибо))) Разобрался-таки))

Re: Таймеры/счётчики в AVR

Вс окт 27, 2013 15:06:23

Парни, нужна консультация по асинхронному режиму работы Timer/Counter2 в ATMega8. Суть в том, что не срабатывает прерывание TIM2_OVF (проверял работу в ISIS v.7.7 SP2), хотя рассчитывал на прерывание в 1 сек.

Ниже код проги (ассемблер, набирал в Atmel Studio v6.0.1996 SP2). В прерывании RESET прописаны строки инициализации асинхронного режима T/C2:
Спойлер
Код:

.def   Temp=R18


.CSEG
.ORG 0

rjmp RESET

TIM2_OVF:
           
   ;Включить светодиод, подключенный к PC0
   ldi Temp, 0b00000001
   out PortC, Temp

   ;Включить светодиод, подключенный к PC1
   ldi Temp, 0b00000010
   out PortC, Temp

reti

RESET:   
      cli ; Clear the interrupt bit in the status register, disable interrupt execution
      
      ;Инициализация стека
      ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM
      out SPH,r16 ; Set Stack Pointer to top of RAM
      ldi r16,low(RAMEND)
      out SPL,r16

      ;Настройка порта C на вывод.
      ldi Temp,0b11111111
      out ddrc,Temp

      ;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ
         ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2.
         ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6
         in Temp, TIMSK
         cbr Temp, 0b11000000
         out TIMSK, Temp

         ;2. Select clock source by setting AS2 as appropriate
         ;Установить бит AS2 = 1 в регистре ASSR, бит 3
         in Temp, ASSR
         sbr Temp, 0b00001000
         out ASSR, Temp

         ;3. Write new values to TCNT2, OCR2, and TCCR2.
         ;Записать новые значения в TCNT2 (хранит значение),
         ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями)
         ldi Temp, 0
         out TCNT2, Temp
         out OCR2, Temp ;В программе не используется
         ;Устанавливаем предделитель = 128
         ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек.
         in Temp, TCCR2
         sbr Temp, 0b00000101
         out TCCR2, Temp

         ;4. To switch to asynchronous operation:
         ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR
         ;В ASSR д.б. значение 0b00001000, проверяем его.
         Wait_For_Switch_ASSR:
            in Temp, ASSR
            andi Temp, 0b00000111
            brbc 1, Wait_For_Switch_ASSR  ;BRBC - Branch if Bit in SREG is Cleared
         ;<END Wait_For_Switch_ASSR>

         ;5. Clear the Timer/Counter2 Interrupt Flags.
         ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.:
         ;Alternatively, OCF2 is cleared by writing a logic one to the flag
         ;Alternatively, TOV2 is cleared by writing a logic one to the flag.
         in Temp, TIFR
         sbr Temp, 0b11000000
         out TIFR, Temp

         ;6. Enable interrupts, if needed.
         ;Разрешаем прерывания по переполнению в Timer/Counter2
         ;Записать TOIE2 = 1 (бит 6 в TIMSK)
         in Temp, TIMSK
         sbr Temp, 0b01000000
         out TIMSK, Temp
      ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>

      sei ; Enable interrupts

;<END RESET>

Main:

   Ldi Temp, 0b00000100 ;Включить светодиод, подключенный к PC2
   out PortC, Temp

rjmp Main


Схема в ISIS ниже. Светится только жёлтый светодиод, подключенный к PC2. Хотя, по идее, через секунду после запуска программы должны засветиться светодиоды, подключенные к PC1 и PC0. На 4-х разрядный индикатор и кнопки не обращайте внимания (от другой проги остались).
Изображение
Последний раз редактировалось Black_Wolf Вс окт 27, 2013 21:58:36, всего редактировалось 1 раз.

Re: Таймеры/счётчики в AVR

Вс окт 27, 2013 16:26:32

Не хватает
Код:
.CSEG
.ORG 0

rjmp RESET

.ORG 4                 ;!!!!!!!!!!!!!!!!!!!!!!!!!

TIM2_OVF:

Re: Таймеры/счётчики в AVR

Вс окт 27, 2013 21:50:27

akl, работает, спасибо!

Но, если немного изменить код программы, добавив функционала (что требует добавить в обработчик прерывания RESET новые переменные и их начальные значения), то прерывание TIM2_OVF снова перестаёт работать.

Касаемо директивы .ORG нашел:
.ORG address означет примерно следующее «копать отсюда и до обеда», т.е. до конца памяти. Данный оператор указывает с какого адреса пойдет собственно программа. Обычно используется для создания таблицы прерываний.


Тем не менее, не понятно почему "4" в строке ".ORG 4". Поясните это, пож-та.

В предыдущих софто-испытательных наработках я использовал прерывания TIM0_OVF и TIM1_OVF - всё работало, но такая "шляпа" получилась с TIM2_OVF асинхронного Timer/Counter2....


....кажется разобрался...
".ORG 4" - это адрес вектора прерываний для ATmega8A. Из тех.документации:
Спойлер
Код:
The most typical and general program setup for the Reset and Interrupt Vector Addresses in ATmega8A is:
addressLabels Code Comments
$000 rjmp RESET ; Reset Handler
$001 rjmp EXT_INT0 ; IRQ0 Handler
$002 rjmp EXT_INT1 ; IRQ1 Handler
$003 rjmp TIM2_COMP ; Timer2 Compare Handler
$004 rjmp TIM2_OVF ; Timer2 Overflow Handler
$005 rjmp TIM1_CAPT ; Timer1 Capture Handler
$006 rjmp TIM1_COMPA ; Timer1 CompareA Handler
$007 rjmp TIM1_COMPB ; Timer1 CompareB Handler
$008 rjmp TIM1_OVF ; Timer1 Overflow Handler
$009 rjmp TIM0_OVF ; Timer0 Overflow Handler
$00a rjmp SPI_STC ; SPI Transfer Complete Handler
$00b rjmp USART_RXC ; USART RX Complete Handler
$00c rjmp USART_UDRE ; UDR Empty Handler
$00d rjmp USART_TXC ; USART TX Complete Handler
$00e rjmp ADC ; ADC Conversion Complete Handler
$00f rjmp EE_RDY ; EEPROM Ready Handler
$010 rjmp ANA_COMP ; Analog Comparator Handler
$011 rjmp TWSI ; Two-wire Serial Interface Handler
$012 rjmp SPM_RDY ; Store Program Memory Ready Handler

Изменил в своей проге блок RESET следующим образом:
1. Инициализация стека
2. НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ
3. Присвоение нач.значений переменным
4. Настройка порта С на вывод
Было - 1, 3, 2, 4. Но в чём разница (один вариант работает, другой нет), пока не понятно.
Спойлер
Код:
.def   Seconds=R16
.def   SetOnVD1=R17
.def   SetOnVD2=R20
.def   Temp=R18


.CSEG
.ORG $00
rjmp RESET ; Reset Handler
rjmp TIM2_OVF ; Timer2 Overflow Handler

.ORG $04
TIM2_OVF:
   
   cpi Seconds,0
   brbs 1, TurnON_VD2 ;BRBS - Branch if Bit in SREG is Set
   TurnON_VD1:
      out PortC, SetOnVD1
      inc Seconds
   rjmp TIM2_OVF_Exit

   TurnON_VD2:
      out PortC, SetOnVD2
      dec Seconds

   TIM2_OVF_Exit:

reti

RESET:   
      cli ; Clear the interrupt bit in the status register, disable interrupt execution
      
      ;Инициализация стека
      ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM
      out SPH,r16 ; Set Stack Pointer to top of RAM
      ldi r16,low(RAMEND)
      out SPL,r16

      ;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ
         ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2.
         ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6
         in Temp, TIMSK
         cbr Temp, 0b11000000
         out TIMSK, Temp

         ;2. Select clock source by setting AS2 as appropriate
         ;Установить бит AS2 = 1 в регистре ASSR, бит 3
         in Temp, ASSR
         sbr Temp, 0b00001000
         out ASSR, Temp

         ;3. Write new values to TCNT2, OCR2, and TCCR2.
         ;Записать новые значения в TCNT2 (хранит значение),
         ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями)
         ldi Temp, 0
         out TCNT2, Temp
         out OCR2, Temp ;В программе не используется
         ;Устанавливаем предделитель = 128
         ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек.
         in Temp, TCCR2
         sbr Temp, 0b00000101
         out TCCR2, Temp

         ;4. To switch to asynchronous operation:
         ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR
         ;В ASSR д.б. значение 0b00001000, проверяем его.
         Wait_For_Switch_ASSR:
            in Temp, ASSR
            andi Temp, 0b00000111
            brbc 1, Wait_For_Switch_ASSR  ;BRBC - Branch if Bit in SREG is Cleared
         ;<END Wait_For_Switch_ASSR>

         ;5. Clear the Timer/Counter2 Interrupt Flags.
         ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.:
         ;Alternatively, OCF2 is cleared by writing a logic one to the flag
         ;Alternatively, TOV2 is cleared by writing a logic one to the flag.
         in Temp, TIFR
         sbr Temp, 0b11000000
         out TIFR, Temp

         ;6. Enable interrupts, if needed.
         ;Разрешаем прерывания по переполнению в Timer/Counter2
         ;Записать TOIE2 = 1 (бит 6 в TIMSK)
         in Temp, TIMSK
         sbr Temp, 0b01000000
         out TIMSK, Temp
      ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>

      ;Вспомогательные переменные
      ;ldi   Temp, 0
      ldi Seconds, 0
      ldi   SetOnVD1, 0b00000001
      ldi   SetOnVD2, 0b00000010


      ;Настройка порта C на вывод.
      ldi Temp,0b11111111
      out ddrc,Temp


      sei ; Enable interrupts

;Перейти в основное тело программы
;<END RESET>

Main:

   Ldi Temp, 0b00000100
   out PortC, Temp

rjmp Main

Re: Таймеры/счётчики в AVR

Пн окт 28, 2013 06:00:00

Вроде, должна работать, только светики на PC0, PC1 будут загораться на 8 тактов ядра в секунду. На столько же светик PC2 будет гаснуть.
Попробуйте так
Спойлер
Код:
.include    "m8def.inc"   ; используем mega8

.def   Seconds=R16
.def   SetOnVD1=R17
.def   SetOnVD2=R20
.def   Temp=R18


.CSEG
.ORG $00
rjmp RESET ; Reset Handler
;rjmp TIM2_OVF ; Timer2 Overflow Handler

.ORG $04
TIM2_OVF:
   
   cpi Seconds,0
   BREQ   TurnON_VD2
;   brbs 1, TurnON_VD2 ;BRBS - Branch if Bit in SREG is Set
TurnON_VD1:
   EOR   SetOnVD1,R22
      out PortC, SetOnVD1
      inc Seconds
   rjmp TIM2_OVF_Exit

TurnON_VD2:
   EOR   SetOnVD2,R22
      out PortC, SetOnVD2
      dec Seconds

TIM2_OVF_Exit:
   
   reti

RESET:   
      cli ; Clear the interrupt bit in the status register, disable interrupt execution
     
      ;Инициализация стека
      ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM
      out SPH,r16 ; Set Stack Pointer to top of RAM
      ldi r16,low(RAMEND)
      out SPL,r16

      ;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ
         ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2.
         ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6
         in Temp, TIMSK
         cbr Temp, 0b11000000
         out TIMSK, Temp

         ;2. Select clock source by setting AS2 as appropriate
         ;Установить бит AS2 = 1 в регистре ASSR, бит 3
         in Temp, ASSR
         sbr Temp, 0b00001000
         out ASSR, Temp

         ;3. Write new values to TCNT2, OCR2, and TCCR2.
         ;Записать новые значения в TCNT2 (хранит значение),
         ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями)
         ldi Temp, 0
         out TCNT2, Temp
         out OCR2, Temp ;В программе не используется
         ;Устанавливаем предделитель = 128
         ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек.
         in Temp, TCCR2
         sbr Temp, 0b00000101
         out TCCR2, Temp

         ;4. To switch to asynchronous operation:
         ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR
         ;В ASSR д.б. значение 0b00001000, проверяем его.
         Wait_For_Switch_ASSR:
            in Temp, ASSR
            andi Temp, 0b00000111
            brbc 1, Wait_For_Switch_ASSR  ;BRBC - Branch if Bit in SREG is Cleared
         ;<END Wait_For_Switch_ASSR>

         ;5. Clear the Timer/Counter2 Interrupt Flags.
         ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.:
         ;Alternatively, OCF2 is cleared by writing a logic one to the flag
         ;Alternatively, TOV2 is cleared by writing a logic one to the flag.
         in Temp, TIFR
         sbr Temp, 0b11000000
         out TIFR, Temp

         ;6. Enable interrupts, if needed.
         ;Разрешаем прерывания по переполнению в Timer/Counter2
         ;Записать TOIE2 = 1 (бит 6 в TIMSK)
         in Temp, TIMSK
         sbr Temp, 0b01000000
         out TIMSK, Temp
      ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>

      ;Вспомогательные переменные
      ;ldi   Temp, 0
      ldi Seconds, 0
      ldi   SetOnVD1, 0b00000001
      ldi   SetOnVD2, 0b00000010


      ;Настройка порта C на вывод.
      ldi Temp,0b11111111
      out ddrc,Temp


   LDI R22,0b00000100
   Ldi Temp, 0b00000100
   out PortC,Temp

      sei ; Enable interrupts

;Перейти в основное тело программы
;<END RESET>

Main:

;   Ldi Temp, 0b00000100
;   out PortC, Temp

rjmp Main

Re: Таймеры/счётчики в AVR

Вт окт 29, 2013 00:20:41

Мне вот что не понятно по векторам прерываний:

Так мигают светодиоды, т.е. прога работает как надо (пишу отрывок кода):
Код:
.CSEG
.ORG $00 rjmp RESET ; Reset Handler
;.ORG $04 rjmp TIM2_OVF ; Timer2 Overflow Handler
...
.ORG $04
TIM2_OVF:
   ...
reti

Так мигают только светики PC0 и РС2 (PC1 не загорается):
Код:
.CSEG
.ORG $00 rjmp RESET ; Reset Handler
.ORG $04 rjmp TIM2_OVF ; Timer2 Overflow Handler
...
;.ORG $04
TIM2_OVF:
   ...
reti


К примеру, так светики PC0 и РС1 не горят и не моргают (РС2 постоянно горит):
Код:
.CSEG
.ORG $00 rjmp RESET ; Reset Handler
;.ORG $04 rjmp TIM2_OVF ; Timer2 Overflow Handler
...
.ORG $04
TIM2_OVF:
   nop
   nop
   nop
   ...
reti


На мой взгляд разницы быть не должно.
Кстати, директива ".include "m8def.inc" роли не играет. Видимо Atmel Studio сама цепляет этот inc-файл.

Re: Таймеры/счётчики в AVR

Вт окт 29, 2013 02:42:10

Похоже, у меня неправильная сборка студии, но в ней Ваши примеры работают :dont_know:
ASTUD_4_684.GIF

Re: Таймеры/счётчики в AVR

Вт окт 29, 2013 07:19:01

akl, спасибо за помощь! :)

Предполагаю, что Atmel Studio 6.0.1996 SP2 косячит. Сегодня скачаю новый релиз Atmel Studio 6.1 update 2.0 (build 2730), попробую его. Потом отпишусь...
Ответить