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

Обсуждаем контроллеры компании Atmel.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Для какого камня эта "простенькая" программа :) Судя по названиям регистров, похоже ATmega48...328
Спойлер

Код: Выделить всё

Label_01:
           jmp Label_03	; Reset
;	jmp Label_02	; External Interrupt Request 0
;                    jmp Label_02	; External Interrupt Request 1
;                    jmp Label_02	; Pin Change Interrupt Request 0
;                    jmp Label_02	; Pin Change Interrupt Request 0
;                    jmp Label_02	; Pin Change Interrupt Request 1
;                    jmp Label_02	; Watchdog Time-out Interrupt
.org	7	; для 48,88
;.org	0x0E	; для 168,328
	jmp Int_T2M_01	; Timer/Counter2 Compare Match A

   ;                 jmp Label_02	; Timer/Counter2 Compare Match B
    ;                jmp Label_02	; Timer/Counter2 Overflow
     ;               jmp Label_02	; Timer/Counter1 Capture Event
      ;              jmp Label_02	; Timer/Counter1 Compare Match A
       ;             jmp Label_02	; Timer/Counter1 Compare Match B
        ;            jmp Label_02	; Timer/Counter1 Overflow
         ;           jmp Label_02	; TimerCounter0 Compare Match A
          ;          jmp Label_02	; TimerCounter0 Compare Match B
           ;         jmp Label_02	; Timer/Couner0 Overflow
.org	0x11	; для 48,88
;.org	0x22	; для 168,328
                    jmp Int_SPI_01	; SPI Serial Transfer Complete

                    jmp Label_02	; USART Rx Complete
DS в помощь, никакие Мортоны и Трамперты не помогут.
Последний раз редактировалось akl Вт окт 31, 2017 14:39:00, всего редактировалось 1 раз.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

Книга. В этой книге очень подробно, доступно расписаны архитектура МК, система команд. Примеры программ.
Джон Мортон - Микроконтроллеры AVR. Вводный курс
vispower
Нашел транзистор. Понюхал.
Сообщения: 181
Зарегистрирован: Ср фев 18, 2009 13:59:46

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

Сообщение vispower »

[uquote="akl",url="/forum/viewtopic.php?p=3220893#p3220893"]Для какого камня эта "простенькая" программа :) Судя по названиям регистров, похоже ATmega48...328
DS в помощь, никакие Мортоны и Трамперты не помогут.[/uquote]
дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.
Demiurg
Это не хвост, это антенна
Сообщения: 1480
Зарегистрирован: Ср июн 25, 2008 15:19:44
Контактная информация:

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

Сообщение Demiurg »

vispower писал(а): дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет?
Не будет. И не потому что я такой нехороший дядька. Все просто и банально. Потому что вы заипете все форумы своими вопросами. Тогда как многие первые вопросы отпадут сами собой после чтения и самостоятельной практики.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

[uquote="vispower",url="/forum/viewtopic.php?p=3220964#p3220964"]дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.[/uquote]Спокойнее, я, например, без понятия что стоит в ардуйне. Так работает, потому что вектора стоят правильно. Удачи
Спойлер

Код: Выделить всё

.include "m328pdef.inc"

Label_01:
           jmp Label_03	; Reset
;	jmp Label_02	; External Interrupt Request 0
;                    jmp Label_02	; External Interrupt Request 1
;                    jmp Label_02	; Pin Change Interrupt Request 0
;                    jmp Label_02	; Pin Change Interrupt Request 0
;                    jmp Label_02	; Pin Change Interrupt Request 1
;                    jmp Label_02	; Watchdog Time-out Interrupt
;.org	7	; для 48,88
.org	0x0E	; для 168,328
	jmp Int_T2M_01	; Timer/Counter2 Compare Match A

   ;                 jmp Label_02	; Timer/Counter2 Compare Match B
    ;                jmp Label_02	; Timer/Counter2 Overflow
     ;               jmp Label_02	; Timer/Counter1 Capture Event
      ;              jmp Label_02	; Timer/Counter1 Compare Match A
       ;             jmp Label_02	; Timer/Counter1 Compare Match B
        ;            jmp Label_02	; Timer/Counter1 Overflow
         ;           jmp Label_02	; TimerCounter0 Compare Match A
          ;          jmp Label_02	; TimerCounter0 Compare Match B
           ;         jmp Label_02	; Timer/Couner0 Overflow
;.org	0x11	; для 48,88
.org	0x22	; для 168,328
                    jmp Int_SPI_01	; SPI Serial Transfer Complete

                    jmp Label_02	; USART Rx Complete
                    jmp Label_02	; USART, Data Register Empty
                    jmp Label_02	; USART Tx Complete
                    jmp Label_02	; ADC Conversion Complete
                    jmp Label_02	; EEPROM Ready
                    jmp Label_02	; Analog Comparator
                    jmp Label_02	; Two-wire Serial Interface
                    jmp Label_02	; Store Program Memory Read
                    
Label_02:			cli
					jmp Label_01

					 ;поле констант
                     .dw	0x0001		;000037 0001
                     .dw	0x0025		;000040 0025
					 .dw	0x0028		;000041 0028
					 .dw	0x002B		;000042 002b

					 ;старт программы - инициализация
Label_03:           eor r1, r1			;r1 в ноль
					out SREG, r1		;в SREG ноль

                    ldi r28,low(RAMEND) 	;
                    ldi r29,high(RAMEND)	;конец рамы
                    out SPH, r29		; 
                    out SPL, r28		;загрузить стек 
					
					
					sei					;разрешить прерывание глобально
                    ;начальная инициализация таймеров и порта (из дизассемблированного примера Fade)
		            in r24, TCCR0A			;читать Timer/Counter Control Register A
                    sbr r24, 0x02			;установить регистр WGM01: Waveform Generation Mode
                    out TCCR0A, r24		;записать Timer/Counter Control Register A
                    in r24, TCCR0A			;читать Timer/Counter Control Register A
                    sbr r24, 0x01			;установить регистр WGM00: Waveform Generation Mode
                    out TCCR0A, r24		;записать Timer/Counter Control Register A		- Fast PWM	
                    in r24, TCCR0B			;читать TCCR0B – Timer/Counter Control Register B
                    sbr r24, 0x02			;
                    out TCCR0B, r24		;бит1 в единицу 
                    in r24, TCCR0B 		;читать TCCR0B – Timer/Counter Control Register B
                    sbr r24, 0x01 			;
                    out TCCR0B, r24		;бит0 в единицу  clkI/O/64 (From prescaler)
                    lds r24, TIMSK0		;читать TIMSK0 – Timer/Counter Interrupt Mask Register
                    sbr r24, 0x01			;	
                    sts TIMSK0, r24		;разрешить прерывание Bit 0 – TOIE0: Timer/Counter0 Overflow Interrupt Enable
                    sts TCCR1B, r1			;TCCR1B – Timer/Counter1 Control Register B  - в ноль
                    lds r24, TCCR1B		;читать TCCR1B – Timer/Counter1 Control Register B
                    sbr r24, 0x02 
                    sts TCCR1B, r24		;clkI/O/8 (From prescaler)
                    lds r24, TCCR1B		;читать TCCR1B – Timer/Counter1 Control Register B
                    sbr r24, 0x01 
                    sts TCCR1B, r24		;теперь clkI/O/64 (From prescaler)
                    lds r24, TCCR1A		;читать TCCR1A – Timer/Counter1 Control Register A
                    sbr r24, 0x01 
                    sts TCCR1A, r24		;до 00ff
                    lds r24, TCCR2B		;TCCR2B – Timer/Counter Control Register B
;                    sbr r24, 0x04 
;                    sts TCCR2B, r24		;clkT2S/64 (From prescaler)
                    lds r24, TCCR2A		;TCCR2A – Timer/Counter Control Register A
                    sbr r24, 0x01 
                    sts TCCR2A, r24		;0xFF TOP BOTTOM
                    lds r24, ADCSRA		; ADCSRA – ADC Control and Status Register A
                    sbr r24, 0x04 
                    sts ADCSRA, r24		;бит2 в 1
                    lds r24, ADCSRA 
                    sbr r24, 0x02	
                    sts ADCSRA, r24		;бит1 в 1 
                    lds r24, ADCSRA 
                    sbr r24, 0x01 
                    sts ADCSRA, r24		;бит0 в 1	Division Factor 128
                    lds r24, ADCSRA 
                    sbr r24, 0x80 
                    sts ADCSRA, r24		;бит7 в 1	Bit 7 – ADEN: ADC Enable
					sts UCSR0B, r1	    ;статусный регистр порта в ноль	
                    
					;Т2 настроить на 1 секунду
                    ldi r24, 0x02		;WGM21-WGM20 10 CTC сброс по совпадению
					sts TCCR2A, r24		;0xFF TOP BOTTOM
                    ldi r24, 0x01		;clk/1
;                    ldi r24, 0x07		;clk/1024
					sts TCCR2B, r24		;предделитель
                    ldi r24, 0x7F		;
					sts OCR2A, r24		;задать частоту
                    ldi r24, 0x02		;
					sts TIMSK2, r24		;прерывание по совпадению А
	STS	TIFR2,R24
                    

					;в режим ожидания
					ldi r24, 0x01
					out SMCR, r24		;режим ожидания Idle
Label_End:
	sleep
	nop
	nop
					rjmp Label_End



Int_T2M_01:		;Timer/Counter1 Overflow
	RETI
;					cli
;					ret
					 
					 /*
					 ldi r24, 0x09			;в r24 = 9
                     call Label_28			;вызов процедурки 2
                     ldi r16, 0x71 
                     ldi r17, 0x00			;r16r17 = 0071
                     ldi r25, 0x00 
	                 mov r14, r25			;r14=0
                     ldi r25, 0x00 
                     mov r15, r25			;r15=0
Label_48:            lds r28, 0x010B		;из sram 
                     lds r29, 0x010C		;из sram 
                     ldi r24, 0x09				
                     call Label_28			;второй вызов процедурки 2 так же на входе r24=9
                     sbiw r29:r28, 0x00		;минус ноль	
                     brne Label_29			;если Y регистр не ноль
Label_42:            ldi r22, 0x00 
                     rjmp Label_30 
Label_29:            cpi r28, 0xFF 
                     cpc r29, r1 
                     brne Label_31 
Label_41:            ldi r22, 0x01 
Label_30:            ldi r24, 0x09 
                     call Label_32 
                     rjmp Label_33 
Label_31:            movw r31:r30, r17:r16 
                     lpm r24, Z 
                     cpi r24, 0x03 
                     breq Label_34 
                     brsh Label_35 
                     cpi r24, 0x01 
                     breq Label_36 
                     cpi r24, 0x02 
                     brne Label_37 
                     in r24, TCCR0A 
                     sbr r24, 0x20 
                     out TCCR0A, r24 
                     out OCR0B, r28 
                     rjmp Label_33 
Label_35:            cpi r24, 0x07 
                     breq Label_38 
                     cpi r24, 0x08 
                     breq Label_39 
                     cpi r24, 0x04 
                     brne Label_37 
                     lds r24, TCCR1A 
                     sbr r24, 0x20 
                     sts TCCR1A, r24 
                     sts OCR1BH, r29 
                     sts OCR1BL, r28 
                     rjmp Label_33 
Label_36:            in r24, TCCR0A 
                     sbr r24, 0x80 
                     out TCCR0A, r24 
                     out OCR0A, r28 
                     rjmp Label_33 
Label_34:            lds r24, TCCR1A 
                     sbr r24, 0x80 
                     sts TCCR1A, r24 
                     sts OCR1AH, r29 
                     sts OCR1AL, r28 
                     rjmp Label_33 
Label_38:            lds r24, TCCR2A 
                     sbr r24, 0x80 
                     sts TCCR2A, r24 
                     sts OCR2A, r28 
                     rjmp Label_33 
Label_39:            lds r24, TCCR2A 
                     sbr r24, 0x20 
                     sts TCCR2A, r24 
                     sts OCR2B, r28 
                     rjmp Label_33 
Label_37:            cpi r28, 0x80 
                     cpc r29, r1 
                     brlt Label_40 
                     rjmp Label_41 
Label_40:            rjmp Label_42 
Label_33:            lds r18, 0x0100 
                     lds r19, 0x0101 
                     lds r24, 0x010B 
                     lds r25, 0x010C 
                     add r24, r18 
                     adc r25, r19 
                     sts 0x010C, r25 
                     sts 0x010B, r24 
                     sbiw r25:r24, 0x01 
                     cpi r24, 0xFE 
                     cpc r25, r1 
                     brlo Label_43 
                     neg r19 
                     neg r18 
                     sbc r19, r1 
                     sts 0x0101, r19 
                     sts 0x0100, r18 
Label_43:            call Label_44 
                     movw r5:r4, r23:r22 
                     movw r7:r6, r25:r24 
                     ldi r24, 0x1E 
                     mov r8, r24 
                     mov r9, r1 
                     mov r10, r1 
                     mov r11, r1 
Label_46:            call Label_44 
                     movw r27:r26, r25:r24 
                     movw r25:r24, r23:r22 
                     sub r24, r4 
                     sbc r25, r5 
                     sbc r26, r6 
                     sbc r27, r7 
                     cpi r24, 0xE8 
                     sbci r25, 0x03 
                     cpc r26, r1 
                     cpc r27, r1 
                     brlo Label_45 
                     ldi r31, 0x01 
                     sub r8, r31 
                     sbc r9, r1 
                     sbc r10, r1 
                     sbc r11, r1 
                     ldi r18, 0xE8 
                     add r4, r18 
                     ldi r18, 0x03 
                     adc r5, r18 
                     adc r6, r1 
                     adc r7, r1 
Label_45:            cp r8, r1 
                     cpc r9, r1 
                     cpc r10, r1 
                     cpc r11, r1 
                     brne Label_46 
                     cp r14, r1 
                     cpc r15, r1 
                     brne Label_47 
                     rjmp Label_48 
Label_47:            call Label_09 
                     rjmp Label_48 
					 

Label_8:             cli					;запрет прерываний
Label_49:            rjmp Label_49 
						*/


						/*
					 ;процедурка 2	на входе r24 (вызов из процедурки1 r24=09) манипуляции с константами
Label_28:            ldi r25, 0x00 
                     movw r31:r30, r25:r24  ;загрузка Z-регистра входными данными
                     subi r30, 0x5C			;
                     sbci r31, 0xFF			;Z минус FF5C (z = 0009 - ff5c = 00ad (/2=56) )  
                     lpm r18, Z				;чтение из программной памяти по адресу Z  (01)
                     movw r31:r30, r25:r24	;загрузка Z-регистра входными данными
                     subi r30, 0x70			; 
                     sbci r31, 0xFF			;Z минус FF70 (z = 0009 - ff70 = 0099 (/2=4c старший байт) ) 
                     lpm r24, Z				;чтение из программной памяти по адресу Z (02)
                     and r24, r24			;финт с флагами
                     breq Label_10			;если r24=0 переход на выход
                     ldi r25, 0x00			;r25=0
                     add r24, r24			;
                     adc r25, r25			;
                     movw r31:r30, r25:r24 
                     subi r30, 0x7A 
                     sbci r31, 0xFF			;0004 - FF7A = 008A (WORD 0045)
                     lpm r26, Z+ 
                     lpm r27, Z				;в X = 0024
                     movw r31:r30, r25:r24 
                     subi r30, 0x84 
                     sbci r31, 0xFF			;0004 - FF84 = 0080 (WORD 0040)
                     lpm r24, Z+ 
                     lpm r25, Z				;в r24r25 = 0025
	                 in r24, SREG			;сохранить в r24 регистр флагов
                     cli					;запретить прерывания
                     ld r30, X 
                     or r30, r18			;в r18 01
                     st X, r30				;ddrb0 в 1
                     out SREG, r24			;восстановить из r24 регистр флагов
Label_10:            ret 

Label_32:            ldi r25, 0x00 
                     movw r31:r30, r25:r24 
                     subi r30, 0x98 
                     sbci r31, 0xFF 
                     lpm r19, Z 
                     movw r31:r30, r25:r24 
                     subi r30, 0x5C 
                     sbci r31, 0xFF 
                     lpm r18, Z 
                     movw r31:r30, r25:r24 
                     subi r30, 0x70 
                     sbci r31, 0xFF 
                     lpm r30, Z 
                     and r30, r30 
                     brne Label_11 
                     rjmp Label_12 
Label_11:            and r19, r19 
                     breq Label_13 
                     cpi r19, 0x03 
                     breq Label_14 
                     brsh Label_15 
                     cpi r19, 0x01 
                     breq Label_16 
                     cpi r19, 0x02 
                     brne Label_13 
                     in r24, TCCR0A 
                     andi r24, 0xDF 
                     rjmp Label_17 
Label_15:            cpi r19, 0x07 
                     breq Label_18 
                     cpi r19, 0x08 
                     breq Label_19 
                     cpi r19, 0x04 
                     brne Label_13 
                     lds r24, TCCR1A 
                     andi r24, 0xDF 
                     rjmp Label_20 
Label_14:            lds r24, TCCR1A 
                     andi r24, 0x7F 
Label_20:            sts TCCR1A, r24 
                     rjmp Label_13 
Label_16:            in r24, TCCR0A 
                     andi r24, 0x7F 
Label_17:            out TCCR0A, r24 
                     rjmp Label_13 
Label_18:            lds r24, TCCR2A 
                     andi r24, 0x7F 
                     rjmp Label_21 
Label_19:            lds r24, TCCR2A 
                     andi r24, 0xDF 
Label_21:            sts TCCR2A, r24 
Label_13:            ldi r31, 0x00 
                     add r30, r30 
                     adc r31, r31 
                     subi r30, 0x84 
                     sbci r31, 0xFF 
                     lpm r26, Z+ 
                     lpm r27, Z 
                     in r24, SREG 
                     cli 
                     ld r30, X 
                     cpse r22, r1 
                     rjmp Label_22 
                     com r18 
                     and r18, r30 
                     rjmp Label_23 
Label_22:            or r18, r30 
Label_23:            st X, r18 
                     out SREG, r24 
Label_12:            ret 

Label_44:            in r19, SREG 
                     cli 
                     lds r24, 0x0107 
                     lds r25, 0x0108 
                     lds r26, 0x0109 
                     lds r27, 0x010A 
                     in r18, TCNT0 
                     sbis TIFR0, TOV0 
                     rjmp Label_24 
                     cpi r18, 0xFF 
                     breq Label_24 
                     adiw r25:r24, 0x01 
                     adc r26, r1 
                     adc r27, r1 
Label_24:            out SREG, r19 
                     mov r27, r26 
                     mov r26, r25 
                     mov r25, r24 
                     eor r24, r24 
                     add r24, r18 
                     adc r25, r1 
                     adc r26, r1 
                     adc r27, r1 
                     movw r23:r22, r25:r24 
                     movw r25:r24, r27:r26 
                     ldi r20, 0x02 
Label_25:            add r22, r22 
                     adc r23, r23 
                     adc r24, r24 
                     adc r25, r25 
                     dec r20 
                     brne Label_25 
                     ret 
					 */

					 ;обработка прерывания spi
Int_SPI_01:          push r1 
                     push r0 
                     in r0, SREG 
                     push r0 
                     eor r1, r1 
                     push r18 
                     push r19 
                     push r24 
                     push r25 
                     push r26 
                     push r27 
                     lds r24, 0x0103 
                     lds r25, 0x0104 
                     lds r26, 0x0105 
                     lds r27, 0x0106 
                     lds r19, 0x0102 
                     ldi r18, 0x03 
                     add r18, r19 
                     cpi r18, 0x7D 
                     brsh Int_SPI_02 
                     adiw r25:r24, 0x01 
                     adc r26, r1 
                     adc r27, r1 
                     rjmp Int_SPI_03 
Int_SPI_02:          ldi r18, 0x86 
                     add r18, r19 
                     adiw r25:r24, 0x02 
                     adc r26, r1 
                     adc r27, r1 
Int_SPI_03:          sts 0x0102, r18 
                     sts 0x0103, r24 
                     sts 0x0104, r25 
                     sts 0x0105, r26 
                     sts 0x0106, r27 
                     lds r24, 0x0107 
                     lds r25, 0x0108 
                     lds r26, 0x0109 
                     lds r27, 0x010A 
                     adiw r25:r24, 0x01 
                     adc r26, r1 
                     adc r27, r1 
                     sts 0x0107, r24 
                     sts 0x0108, r25 
                     sts 0x0109, r26 
                     sts 0x010A, r27 
                     pop r27 
                     pop r26 
                     pop r25 
                     pop r24 
                     pop r19 
                     pop r18 
                     pop r0 
                     out SREG, r0 
                     pop r0 
                     pop r1 
                     reti 
.exit
vispower
Нашел транзистор. Понюхал.
Сообщения: 181
Зарегистрирован: Ср фев 18, 2009 13:59:46

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

Сообщение vispower »

[uquote="akl",url="/forum/viewtopic.php?p=3221024#p3221024"][uquote="vispower",url="/forum/viewtopic.php?p=3220964#p3220964"]дык написал же ардуино уно, атмега328 там. кроме как ссылку на книгу, больше подсказок не будет? асм загрузить в студию там дело двух минут. шагаешь до цикла ожидания, стваишь брикпойнт на прерывание 8, жмешь рун, и по адресу стека видишь вместо обратного адреса примерно в два раза меньший адрес.[/uquote]Спокойнее, я, например, без понятия что стоит в ардуйне. Так работает, потому что вектора стоят правильно. Удачи[/uquote]
во гут, спасибки. Т0 не отключен был, а обработка прерывания неправильная рета небыло. короч как обычно собственный человеческий фактор
Аватара пользователя
Starichok51
Модератор
Сообщения: 19045
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

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

Сообщение Starichok51 »

сам должен в отладчике свои ошибки искать, а не засирать людям мозги своим фактором...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

Появилось свободное время вроде допилил функцию "Включить Через"

Код: Выделить всё

#define AMOUNT_TIMERS 2		//Количество используемых таймеров
typedef struct 
{
	uint8_t FlagTimersON;		//Флаг работы таймера
	uint8_t FlagTimersOFF;
	uint8_t TimeCountingON;	//Переменная фиксирующая время старта
	uint8_t TimeCountingOFF;
}TimerStruct;

typedef struct 
{
	TimerStruct Channel[AMOUNT_TIMERS];
	uint16_t MS;
	uint16_t TimeCurrent;	//Текущие время
}SoftTimers;
SoftTimers TIMER;
/*Функция инициализации таймеров (установка всех значений в 0 )*/
void InitTimers()
{
	TIMER.TimeCurrent=0;
	TIMER.MS=0;
	for(uint8_t i=0;i<AMOUNT_TIMERS;i++)
	{
		TIMER.Channel[i].FlagTimersON=0;
		TIMER.Channel[i].FlagTimersOFF=0;
		TIMER.Channel[i].TimeCountingON=0;
	}
}

ISR (TIMER0_OVF_vect)
{
	TCNT0=125;		//значение для T0_0VF переполнения 1 раз в MS
	TIMER.MS++;		//Подсчет MS
	if (TIMER.MS==65535)
	{
		TIMER.MS=0;
	}
}
/*Функция вернет TRUE через время TimeVar,Иначе возвращает  CurrentFlag */
uint8_t OnAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	uint8_t OutFlag=0;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersON==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingON=TIMER.MS;
		TIMER.Channel[Number].FlagTimersON=1;
	}
	uint16_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON;
	if (TimerToStart == TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=1;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].FlagTimersON=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	return OutFlag;
}

uint8_t OFFAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	uint8_t OutFlag=0;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersOFF==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingOFF=TIMER.MS;
		TIMER.Channel[Number].FlagTimersOFF=1;
	}
	uint16_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF;
	if (TimerToSTOP == TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=0;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].FlagTimersOFF=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	return OutFlag;
}
Вызов Функции:

Код: Выделить всё

                   (Время,Канал,Переменная)
PIN=OnAfterTimeMS(10,0,PIN);
Хотел бы услышать совет как её можно еще улучшить?(для многократного использования).

Добавлено after 36 minutes 49 seconds:
И стоит ли объединять две функции онн\офф в 1ну?. с выбором параметра через свитч.
andrei23061996@gmail.com
.................................................................................................................
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

Код: Выделить всё

ISR (TIMER0_OVF_vect)
{
//   TCNT0=125;      //значение для T0_0VF переполнения 1 раз в MS
   TCNT0=-125;      //значение для T0_0VF переполнения 1 раз в MS
Формирование интервала досчётом до переполнения должно делаться так. Например, попробуйте формировать 0,64мс, занося число 80, получите лажу. Если будет занесено -80, будет похоже на правду.
По мне, правильнее записывать такие вещи в символьном виде, типа

Код: Выделить всё

F_CPU=8000000	;тактовая частота 8 МГц
TCNT0=-2*F_CPU/64/1000	; 2мс
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

А по чему следует заносить отрицательное число ? я почему то думал что счетчик считает от 00 до 256 .

Добавлено after 52 minutes 24 seconds:
Может кто подсказать почему не обнуляется переменная TIMER.Channel[Number].FlagTimersOFF и аналогично TIMER.Channel[Number].FlagTimersON

Код: Выделить всё

uint8_t OnAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	uint8_t OutFlag=0;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersON==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingON=TIMER.MS;
		TIMER.Channel[Number].FlagTimersON=1;
	}
	uint16_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON;
	if (TimerToStart == TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=1;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].FlagTimersON=0;
		TimerToStart=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	return OutFlag;
}

uint8_t OFFAfterTimeMS(uint16_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	uint8_t OutFlag=0;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersOFF==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingOFF=TIMER.MS;
		TIMER.Channel[Number].FlagTimersOFF=1;
	}
	uint16_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF;
	if (TimerToSTOP == TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=0;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].FlagTimersOFF=0;
		TimerToSTOP=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	return OutFlag;
}
andrei23061996@gmail.com
.................................................................................................................
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

7seg писал(а):Может кто подсказать почему не обнуляется переменная TIMER.Channel[Number].FlagTimersOFF и аналогично TIMER.Channel[Number].FlagTimersON
Давайте начнем со структуры:
СпойлерУ вас объявлено

Код: Выделить всё

typedef struct
{
   uint8_t FlagTimersON;      //Флаг работы таймера
   uint8_t FlagTimersOFF;
   uint8_t TimeCountingON;   //Переменная фиксирующая время старта
   uint8_t TimeCountingOFF;
}TimerStruct;
и

Код: Выделить всё

typedef struct
{
   TimerStruct Channel[AMOUNT_TIMERS];
   uint16_t MS;
   uint16_t TimeCurrent;   //Текущие время
}SoftTimers;
SoftTimers TIMER;
и соответственно в коде у вас

Код: Выделить всё

TIMER.Channel[Number].TimeCountingON=TIMER.MS;
или

Код: Выделить всё

uint8_t = uint16_t
Далее uint16_t MS максимально может контролировать до 65535мс = 65 секунд.
Далее что бы это все у вас работало нужно постоянно опрашивать функцию OnAfterTimeMS или OFFAfterTimeMS что не есть зергуд.
И опишите еще раз что вы путаетесь получить?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Dimon456 писал(а):И опишите еще раз что вы путаетесь получить?
вот и мне показалось, что тут путаница :) из-за желания охватить все случаи жизни наперёд в одном коде
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

Точно изменил на uint16_t и заработало. )
andrei23061996@gmail.com
.................................................................................................................
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

Ну если уж на все случаи жизни,
то не uint16_t, а uint32_t, 4294967295миллисекунд = 4294967,295секунд = 71582,78825минут = 1193.046470833часов = 49.71026961804дней,
и то может не хватить.
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

Ругается компилятор на 4294967295 this decimal constant is unsigned only in ISO C90 [enabled by default]
andrei23061996@gmail.com
.................................................................................................................
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

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

Сообщение Dimon456 »

Какой компилятор? В чем пишите?
Укажите int32_t, будет до 2147483647, где-то до 24 дней.
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

AtmelStudio
andrei23061996@gmail.com
.................................................................................................................
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

7seg писал(а):Ругается компилятор на 4294967295
потому что 4294967295UL
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
7seg
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Ср май 03, 2017 03:22:26

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

Сообщение 7seg »

И все таки он заработал )
Спойлер

Код: Выделить всё

#define AMOUNT_TIMERS 5		//Количество используемых таймеров
typedef struct 
{
	uint8_t FlagTimersON;		//Флаг работы таймера
	uint8_t FlagTimersOFF;
	uint32_t TimeCountingON;	//Переменная фиксирующая время старта
	uint32_t TimeCountingOFF;
}TimerStruct;

typedef struct 
{
	TimerStruct Channel[AMOUNT_TIMERS];
	uint32_t MS;
	uint32_t TimeCurrent;	//Текущие время
}SoftTimers;
SoftTimers TIMER;
/*Функция инициализации таймеров (установка всех значений в 0 )*/
void InitTimers()
{
	TIMER.TimeCurrent=0;
	TIMER.MS=0;
	for(uint8_t i=0;i<AMOUNT_TIMERS;i++)
	{
		TIMER.Channel[i].FlagTimersON=0;
		TIMER.Channel[i].FlagTimersOFF=0;
		TIMER.Channel[i].TimeCountingON=0;
	}
}

ISR (TIMER0_OVF_vect)
{
	TCNT0=125;		//значение для T0_0VF переполнения 1 раз в MS
	TIMER.MS++;		//Подсчет MS
	if (TIMER.MS == 4294967295UL)
	{
		TIMER.MS=0;
	}
}
/*Функция вернет TRUE через время TimeVar,Иначе возвращает  CurrentFlag */
uint8_t OnAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	cli();
	uint8_t OutFlag=0;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersON==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingON=TIMER.MS;
		TIMER.Channel[Number].FlagTimersON=1;
	}
	uint32_t TimerToStart = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingON;
	if (TimerToStart >= TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=1;
		TIMER.Channel[Number].FlagTimersON=0;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].TimeCountingON=0;
		TimerToStart=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	sei();
	return OutFlag;
}

uint8_t OFFAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
{
	cli();
	uint8_t OutFlag=CurrentFlag;						//Переменная отвечает за RETURN f().
	TIMER.TimeCurrent=TIMER.MS;				//Присваиваем текущие значение МС
	if (TIMER.Channel[Number].FlagTimersOFF==0)	//Условия для захвата времени вызова функции и установки флага работы
	{
		TIMER.Channel[Number].TimeCountingOFF=TIMER.MS;
		TIMER.Channel[Number].FlagTimersOFF=1;
	}
	uint32_t TimerToSTOP = TIMER.TimeCurrent-TIMER.Channel[Number].TimeCountingOFF;
	if (TimerToSTOP >= TimeVar)			//Если время до старта == TimeVar, то OutFlag=1 и обнуляем Флаг работы.
	{
		OutFlag=0;
		TIMER.Channel[Number].FlagTimersOFF=0;
		TIMER.TimeCurrent=0;
		TIMER.Channel[Number].TimeCountingOFF=0;
		TimerToSTOP=0;
	}
	else
	{
		OutFlag=CurrentFlag;
	}
	sei();
	return OutFlag;
}
andrei23061996@gmail.com
.................................................................................................................
viiv
Грызет канифоль
Сообщения: 287
Зарегистрирован: Чт ноя 06, 2014 13:09:06

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

Сообщение viiv »

1)
[uquote="7seg",url="/forum/viewtopic.php?p=3226300#p3226300"]

Код: Выделить всё

	if (TIMER.MS == 4294967295UL)
[/uquote]
поле MS структуры имеет тип uint32_t, поэтому более логично

Код: Выделить всё

	if (TIMER.MS == UINT32_MAX)
:))

И вообще код

Код: Выделить всё

   if (TIMER.MS == 4294967295UL)
   {
      TIMER.MS=0;
   }
лишний!!! Чем Вам так "неугодило" значение 4294967295UL, что Вы его исключаете??? Если увеличить на единицу - будет 0UL :-)

2) Поле TimeCurrent не соответствует названию :)) TimeCurrent (текущее время) - это поле MS. Да и логика TimeCurrent станная,

3) поле MS (не понимаю, зачем большими буквами) неплохо бы volatile объявить. мало ли как компилятор соптимизирует. Или нет?

4)

Код: Выделить всё

/*Функция вернет TRUE через время TimeVar,Иначе возвращает  CurrentFlag */
uint8_t OnAfterTimeMS(uint32_t TimeVar,uint8_t Number,uint8_t CurrentFlag)
Не знаю, может и задумка хитрая. Но (по крайнем мере комметарий "супер-крутой"). Как по по возвращенному значению понять, время TimeVar истекло или это CurrentFlag?
Ответить

Вернуться в «AVR»