Скорее всего идут от датчика положения коленвала. А на нем, как правило, несколько "зубов" отсутствуют. Поэтому без фильтрации и гистерезиса и будет "дергать". Фильтр позволит уменьшить гистерезис.Мой аналитический склад ума дошел до того, что это либо импульсы на тахометр идут не ровно, а у меня замеряет между двух импульсов период...
Ассемблер (ASM) для AVR в вопросах и ответах
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Я же скорость считываю, а не обороты...
Возможно и там может быть тот факт, что где-то импульсы пропускает. Спидометр на это не реагирует, т.к. там инерционность большая, конденсаторы стоят какие-нибудь.
А у меня реагирует на каждый чих.
Возможно и там может быть тот факт, что где-то импульсы пропускает. Спидометр на это не реагирует, т.к. там инерционность большая, конденсаторы стоят какие-нибудь.
А у меня реагирует на каждый чих.
Станислав
- dr.doc
- Это не хвост, это антенна
- Сообщения: 1368
- Зарегистрирован: Вс мар 28, 2010 12:52:22
- Откуда: Беларусь
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Точно. Попутал. просто недавно знакомый про своего американца данные искал и у него получалось 4000 имп/миля. Но последовательность была неравномерной. Возможно мозг выдавал пачки, использую что-либо вроде ABS.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вот. Уже ближе к делу! У меня Тойота, на ней, как мне удалось найти, 2548 импульсов на километр. Схемку хочу сделать универсальную. На Тойотах самые меделнные импульсы (их меньше всего). На других автопромах их больше.
Чтобы измерить такие медленные импульсы я и сделал две переменные, т.к. у ТИНИ13 нет 16 разрядного таймера. Как и посоветовали, при каждом переполнении таймера делаю инкремент переменной. Получился таймер 16 разрядный. ))) По сохраненным значениям в памяти МК видно, что их достаточно, да и в ручную я посчитал, что при 4,8 МГц и делителе таймера на 256, один тик таймера будет 0,000213 секунды.
Чтобы измерить такие медленные импульсы я и сделал две переменные, т.к. у ТИНИ13 нет 16 разрядного таймера. Как и посоветовали, при каждом переполнении таймера делаю инкремент переменной. Получился таймер 16 разрядный. ))) По сохраненным значениям в памяти МК видно, что их достаточно, да и в ручную я посчитал, что при 4,8 МГц и делителе таймера на 256, один тик таймера будет 0,000213 секунды.
Станислав
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Я асм почти окончательно забросил. Делюсь некоторыми советами для тех кто еще верен асму животворящему 
Шаблон. Главный файл. pattern.asm:
В конце заголовочный файлов на конкретные МК есть таблицы векторов. Для каждого используемого МК делаем отдельный файл по этому примеру. vectors_m32.inc:
Шаблон конечного автомата (этакое ядро конечного автомата) с переходом по индексу-состоянию.
Пример использования шаблона конечного автомата:
До кучи набор макросов, подпрограмм.
Шаблон. Главный файл. pattern.asm:
Спойлер
Код: Выделить всё
//==================
.nolist
.include "m32def.inc"
.list
//==================
//=============== Функции и глобальные определения проекта ===============
//----------
#define NO 0
#define YES 1
//----------
//----------
#define TINY 0
#define MEGA 1
//----------
//----------
#define NO_CHANGE 0
#define CHANGE 1
//----------
//----------
#define tab_h(x) HIGH(x), LOW(x)
#define tab_l(x) LOW(x), HIGH(x)
//----------
//----------
#define WORK 0
#define DEBUG 1
//==================
//==================
#define PROJECT DEBUG // WORK //
#define CPU_TYPE MEGA
#define WATCH_DOG NO_CHANGE
#define EEPROM YES
//==================
//==================
.equ XTAL = 8000000
//==================
//==================
//---------- List used register ----------
// n/u - Not Used
// = r0 result multiply
// = r1 result multiply
.def RCLR = r2
.def RSER = r3
.def RSREG = r4
.def EEDREG = r5
.def KEYS_PREV = r6
.def KEYS_CURRENT = r7
.def ADC_PUMP_SPEED = r8
// = r9
// = r10
// = r11
// = r12
// = r13 n/u
// = r14 Used.
// = r15 Used.
//----------
.def TEMP = r16 // Used. Everywhere
// = r17 Used. Everywhere
// = r18 Used. Everywhere
// = r19 Used. Everywhere
.def FSM_STATE = r20
.def FSM_FLAGS = r21
.def CNT = r22
.def FLAGS = r23
.def POINT_ENTRY_L = r24 // adiw/sbiw
.def POINT_ENTRY_H = r25 // adiw/sbiw
// = r26 XL
// = r27 XH
// = r28 YL
// = r29 YH
// = r30 ZL
// = r31 ZH
//==================
//==================
.set NUM_FLG = -1
.macro Def_Flag
.set NUM_FLG = (NUM_FLG+1)
.set @0 = NUM_FLG
.if (NUM_FLG<=7)
.message "Flag Defined!"
.else
.error "Flag Not Defined"
.endif
.endmacro
.set NUM_ERR = 0
.macro Def_Err_ID
.set NUM_ERR = (NUM_ERR+1)
.set @0 = NUM_ERR
.message "Number Error Defined!"
.endmacro
.macro End_Table
.db 0xFF, 0xFF
.endmacro
//==================
#if (PROJECT==DEBUG)
//==================
.equ TEST_LED_PORT = PORTD
.equ TEST_LED_DDR = DDRD
.equ TEST_LED_PIN = PIND
.equ TEST_LED = PD7
//----------
//----------
.macro test_led_on
in r16, TEST_LED_DDR
setb r16, TEST_LED
out TEST_LED_DDR, r16
.endmacro
.macro test_led_off
in r16, TEST_LED_DDR
clrb r16, TEST_LED
out TEST_LED_DDR, r16
.endmacro
//==================
#endif
//==================
.include "vectors_m32.inc"
.include "library.inc"
.include "proc_errors.inc"
.include "system_timer.inc"
.include "fsm.inc"
.include "prototreads.inc"
.include "in_out_def.inc"
.include "in_out_lib.inc"
.include "val_def.inc"
.include "kbd_drv_def.inc"
.include "kbd_drv.inc"
.include "proc_menu.inc"
//************************************************************************
.dseg
.org 0x200
rdata:
.byte 6
.cseg
//************************************************************************
Reset:
//----------
Clear_Registers
//----------
//----------
clr RCLR
ser r16
mov RSER, r16
clr FLAGS
//----------
//----------
Init_Stack // Инициализация стека.
//----------
//----------
Clear_SRAM // Очистка ОЗУ.
//----------
//----------
Init_System_Timer // Инициализация системного таймера.
//----------
//----------
Init_WDT
//----------
//----------
Init_Sleep_Mode
//----------
//---------- Отладка ----------
#if (PROJECT==DEBUG)
#endif
//==================
sei
//==================
Main:
wdr
rcall Service_Timers
rcall KBD_DRV
rcall Proc_Menu
rjmp Main
//==================
В конце заголовочный файлов на конкретные МК есть таблицы векторов. Для каждого используемого МК делаем отдельный файл по этому примеру. vectors_m32.inc:
Спойлер
Код: Выделить всё
.cseg
.org 0x0000
rjmp Reset
; ***** INTERRUPT VECTORS ************************************************
.org INT0addr ; External Interrupt Request 0
reti
.org INT1addr ; External Interrupt Request 1
reti
.org INT2addr ; External Interrupt Request 2
reti
.org OC2addr ; Timer/Counter2 Compare Match
reti
.org OVF2addr ; Timer/Counter2 Overflow
reti
.org ICP1addr ; Timer/Counter1 Capture Event
reti
.org OC1Aaddr ; Timer/Counter1 Compare Match A
reti
.org OC1Baddr ; Timer/Counter1 Compare Match B
reti
.org OVF1addr ; Timer/Counter1 Overflow
reti
.org OC0addr ; Timer/Counter0 Compare Match
rjmp Sys_Timer_Comp
.org OVF0addr ; Timer/Counter0 Overflow
reti
.org SPIaddr ; Serial Transfer Complete
reti
.org URXCaddr ; USART, Rx Complete
reti
.org UDREaddr ; USART Data Register Empty
reti
.org UTXCaddr ; USART, Tx Complete
reti
.org ADCCaddr ; ADC Conversion Complete
reti
.org ERDYaddr ; EEPROM Ready
reti
.org ACIaddr ; Analog Comparator
reti
.org TWIaddr ; 2-wire Serial Interface
reti
.org SPMRaddr ; Store Program Memory Ready
reti
;----------
;----------
.org INT_VECTORS_SIZE ; size in words
;===================
Шаблон конечного автомата (этакое ядро конечного автомата) с переходом по индексу-состоянию.
Спойлер
Код: Выделить всё
.cseg
//==================
.macro Proc_FSM
ldz @0*2
rjmp _Proc_FSM
.endmacro
_Proc_FSM:
lpm XH, Z+ ; Считывание старшего байта адреса состояния автомата.
lpm XL, Z+ ; Считывание младшего байта адреса состояния автомата.
ld r16, X ; Считывание состояния автомата.
lpm r17, Z+ ; Считывание количества состояний автомата.
cp r16, r17
brsh Process_Errors_FSM
lpm XH, Z+
lpm XL, Z
movw ZH:ZL, XH:XL
add ZL, r16
adc ZH, RCLR
shiftlwz
lpm r17, Z+
lpm r16, Z
movw ZH:ZL, r17:r16
ijmp
Process_Errors_FSM:
cli
adiw ZL, 2
lpm r16, Z
rjmp Proc_Errors
//==================
//==================
Set_FSM_State:
st Y, FSM_STATE
ret
//==================
//==================
//Proc_FSM_Exit:
// st Y, FSM_FLAGS
// std Y+1, FSM_STATE
// ret
//==================
Пример использования шаблона конечного автомата:
Спойлер
Код: Выделить всё
KBD_DRV:
pushiwl Kbd_Drv_Save_Val // Эти две строки - манипуляция со стеком. В стек загоняется эта подпрограмма.
// После выхода из конечного автомата прыгаем сюда, сохраняем данные,
// после этого возвращаемся в место, откуда вызвали конечный автомат.
// если толком не знаете как работает стек, и как им манипулировать,
// не используйте этот прием.
pushiwl Define_Keys //
ldy _KEYS
ldd FSM_STATE, Y+DISP_KEYS
ldd FSM_FLAGS, Y+DISP_KEYS_FLAGS
Scan_Keys // Макрос сканирование кнопок. Дефайнами подставляются нужные функции. Порт\Матрица\Несколько портов.
Proc_FSM Tab_FSM_KBD_DRV
//==================
Kbd_Drv_Save_Val:
std Y+DISP_KEYS, FSM_STATE
std Y+DISP_KEYS_FLAGS, FSM_FLAGS
ret
//==================
Keys_Init:
ser r16
mov KEYS_PREV, r16
mov KEYS_CURRENT, r16
std Y+DISP_KEYS_BUF, r16
Set_State _KEYS_NONE
ret
Tab_FSM_KBD_DRV:
.db tab_h(_KEYS), MAX_FSM_KBD_DRV_STATES, tab_h(Tab_Jmp_KBD_DRV), ERR_ID_KBD_DRV
Tab_Jmp_KBD_DRV:
.equ MAX_FSM_KBD_DRV_STATES = 5 // Количество состояний автомата.
.equ _KEYS_INIT = 0
.db tab_h(Keys_Init)
.equ _KEYS_NONE = 1
.db tab_h(Keys_None)
.equ _KEYS_DOWN = 2
.db tab_h(Keys_Down)
.equ _KEYS_WAIT_UP = 3
.db tab_h(Keys_Wait_Up)
.equ _KEYS_UP = 4
.db tab_h(Keys_Up)
До кучи набор макросов, подпрограмм.
Спойлер
Код: Выделить всё
.macro clrb
cbr @0,1<<@1
.endmacro
.macro setb
sbr @0,1<<@1
.endmacro
.macro sfbs
lds r16,@0
sbrs r16,@1
.endmacro
.macro sfbc
lds r16,@0
sbrc r16,@1
.endmacro
.macro stfb
lds r16,@0
sbr r16,@1
sts @0,r16
.endmacro
.macro clfb
lds r16,@0
cbr r16,@1
sts @0,r16
.endmacro
.macro ldiw
ldi @0,High(@2)
ldi @1,Low(@2)
.endmacro
.macro ldx
ldi XH,High(@0)
ldi XL,Low(@0)
.endmacro
.macro ldy
ldi YH,High(@0)
ldi YL,Low(@0)
.endmacro
.macro ldz
ldi ZH,High(@0)
ldi ZL,Low(@0)
.endmacro
.macro pushx
push XL
push XH
.endmacro
.macro pushy
push YL
push YH
.endmacro
.macro pushz
push ZL
push ZH
.endmacro
.macro popx
pop XH
pop XL
.endmacro
.macro popy
pop YH
pop YL
.endmacro
.macro popz
pop ZH
pop ZL
.endmacro
.macro stsi
ldi r16,@1
sts @0,r16
.endmacro
.macro stsiw
ldi r16,high(@1)
sts @0+1,r16
ldi r16,low(@1)
sts @0,r16
.endmacro
.macro outi
ldi r16,@1
out @0,r16
.endmacro
.macro outiw
ldi r16,high(@1)
out @0H,r16
ldi r16,low(@1)
out @0L,r16
.endmacro
.macro adi
subi @0,-@1
.endmacro
.macro adci
sbci @0,-@1
.endmacro
.macro addiw
subi @0L,LOW(-@1)
sbci @0H,HIGH(-@1)
.endmacro
.macro cpw
cp @0,@1
cpc @2,@3
.endmacro
.macro subiw
subi @0L,LOW(@1)
sbci @0H,HIGH(@1)
.endmacro
.macro addw
add @0L,@1
adc @0H,@2
.endmacro
.macro shiftlwz
lsl ZL
rol ZH
.endmacro
.macro shiftrw
lsr @0H
ror @0L
.endmacro
.macro INIT_STACK
.ifdef SPH
outi SPH,HIGH(RAMEND)
.endif
outi SPL,LOW(RAMEND)
.endmacro
.macro INIT_WATCH_DOG
outi WDTCR,1<<WDTOE | 1<<WDE ; | 1<<WDP2 | 1<<WDP1 | 1<<WDP0
.endmacro
.macro INIT_SLEEP_MODE
in r16,MCUCR
sbr r16,1<<SE
out MCUCR,Temp
.endmacro
.macro INIT_EXT_INT0
in r16,MCUCR
sbr r16,1<<ISC00 | 1<<ISC01
out MCUCR,Temp
in r16,GICR
sbr r16,1<<INT0
out GICR,r16
.endmacro
.macro INIT_EXT_INT1
in r16,MCUCR
sbr r16,1<<ISC10 | 1<<ISC11
out MCUCR,Temp
in r16,GICR
sbr r16,1<<INT1
out GICR,r16
.endmacro
.macro INIT_EXT_INT2
in r16,MCUCR
sbr r16,1<<SE
out MCUCR,Temp
in r16,MCUCSR
sbr r16,1<<ISC2
out MCUCSR,Temp
in r16,GICR
sbr r16,1<<INT2
out GICR,r16
.endmacro
.macro INIT_TIMER0
out TCNT0,RCLR
in r16,TIMSK
sbr r16,1<<OCIE0
out TIMSK,r16
outi OCR0,(XTAL/64/1000)
outi TCCR0,1<<CS00 | 1<<CS01
.endmacro
.macro INIT_TIMER1
in r16,TIMSK
sbr r16,1<<OCIE1A
out TIMSK,r16
out TCNT1H,Zero
out TCNT1L,Zero
ldi r16,High(36)
out OCR1AH,r16
ldi r16,Low(36)
out OCR1AL,r16 ; При частоте кварца 7,3728 Мгц число 72=10 мс.
ldi r16,0x05
out TCCR1B,r16
.endmacro
.macro INIT_TIMER2
out TCNT2,RCLR
in r16,TIMSK
sbr r16,1<<OCIE2
out TIMSK,r16
outi OCR2,(XTAL/64/1000)
outi TCCR2,4
.endmacro
.macro Case
cpi STREG,@0
brne Exit_Case
rjmp @1
Exit_Case:
.endmacro
.macro Case_Not_Equal
cpi STREG,@0
breq Exit_Case
rjmp @1
Exit_Case:
.endmacro
.macro Read_State
lds r16,@0
.endmacro
.macro Set_State
ldi r16,@1
sts @0,r16
.endmacro
.macro Set_Mode
ldi r16,@1
sts @0,r16
.endmacro
.macro Check_States
cpi r16,@0
brlo Check_States_Exit
rjmp @1
Check_States_Exit:
.endmacro
.macro Read_Last_State
lds r17,@0
.endmacro
.macro ClearRegisters
clr r0
clr r1
clr r2
clr r3
clr r4
clr r5
clr r6
clr r7
clr r8
clr r9
clr r10
clr r11
clr r12
clr r13
clr r14
clr r15
clr r16
clr r17
clr r18
clr r19
clr r20
clr r21
clr r22
clr r23
clr r24
clr r25
clr r26
clr r27
clr r28
clr r29
clr r30
clr r31
.endmacro
.macro Set_State
ldi FSM_STATE, @0
.endmacro
.macro Clear_Registers
clr ZH
ldi ZL, 30
Clear_Register_Cycle:
dec ZL
st Z, ZH
brne Clear_Register_Cycle
.endmacro
;*************************************************************************
;=========== SRAM ====================
;*************************************************************************
.macro OUT_SRAM
ldi XH,HIGH(@0)
ldi XL,LOW(@0)
ldi Data_H,HIGH(@1)
ldi Data_L,LOW(@1)
rcall _OUT_SRAM
.endmacro
.macro OUTI_SRAM
ldi XH,HIGH(@0)
ldi XL,LOW(@0)
ldi r17,@1
ldi r16,@2
rcall _OUT_SRAM
.endmacro
_OUT_SRAM:
st X+,r16
dec r17
brne _OUT_SRAM
ret
.macro Copy_SRAM
.if @3==YES
push YH
push YL
.endif
ldi XH,HIGH(@0)
ldi XL,LOW(@0)
ldi YH,HIGH(@1)
ldi YL,LOW(@1)
ldi r17,@2
rcall _Copy_SRAM
.if @3==YES
pop YL
pop YH
.endif
.endmacro
_Copy_SRAM:
ld r16,X+
st Y+,r16
dec r17
brne _Copy_SRAM
ret
.macro Clear_SRAM
ldx SRAM_START
Clear_SRAM_Cycle:
st X+,RCLR
cpi XL,LOW(SRAM_START+SRAM_SIZE)
brne Clear_SRAM_Cycle
cpi XH,HIGH(SRAM_START+SRAM_SIZE)
brne Clear_SRAM_Cycle
.endmacro
;*************************************************************************
;*************************************************************************
;========== EEPROM ===================
;*************************************************************************
;Так как возможна случайная запись в EEPROM в случае сбоя питания, то:
;1 - В микроконтроллере включить контроль снижения напряжения питания.
;2 - Первый (0x00) байт никогда не используется.
;3 - После ресета обнулить указатель адреса EEPROM.
;Решения для увеличения ресурса EEPROM:
;4 - Перед записью считывается байт, предназначенный для записи,
;проверяется на равенство с записываемым, если байты равны, то переход
;к записи следующего байта.
;5 - В конце работы с EEPROM обнулить указатель адреса.
#if (EEPROM==YES)
.macro Read_EEPROM
ldix @0 ; Указатель адреса EEPROM.
ldiy @1 ; Указатель адреса SRAM.
ldi r17,@2
rcall _Read_EEPROM
.endmacro
_Read_EEPROM:
sbic EECR,EEWE
rjmp _Read_EEPROM
.ifdef EEARH
out EEARH,XH
.endif
out EEARL,XL
sbi EECR,EERE
sbi EECR,EERE
in EEDREG,EEDR
st Y+,EEDREG
adiw XL,1
dec r17
brne _Read_EEPROM
_Read_EEPROM_0:
sbic EECR,EEWE
rjmp _Read_EEPROM_0
.ifdef EEARH
out EEARH,RCLR
.endif
out EEARL,RCLR
ret
EERead:
sbic EECR,EEWE
rjmp EERead
.ifdef EEARH
out EEARH,XH
.endif
out EEARL,XL
sbi EECR,EERE
sbi EECR,EERE
in EEDREG,EEDR
EERead_1:
sbic EECR,EEWE
rjmp EERead_1
.ifdef EEARH
out EEARH,RCLR
.endif
out EEARL,RCLR
ret
EEWrite:
sbic EECR,EEWE
rjmp EEWrite
.ifdef EEARH
out EEARH,XH
.endif
out EEARL,XL
out EEDR,EEDREG
sbi EECR,EEMWE
sbi EECR,EEWE
EEWrite_1:
sbic EECR,EEWE
rjmp EEWrite_1
.ifdef EEARH
out EEARH,RCLR
.endif
out EEARL,RCLR
ret
.macro Write_EEPROM
ldiy @0 ; Указатель адреса SRAM.
ldix @1 ; Указатель адреса EEPROM.
ldi r17,@2
rcall _Write_EEPROM
.endmacro
_Write_EEPROM:
sbic EECR,EEWE
rjmp _Write_EEPROM
.ifdef EEARH
out EEARH,XH
.endif
out EEARL,XL
ld EEDREG,Y+
out EEDR,EEDREG
sbi EECR,EEMWE
sbi EECR,EEWE
adiw XL,1
dec r17
brne _Write_EEPROM
_Write_EEPROM_0:
sbic EECR,EEWE
rjmp _Write_EEPROM_0
.ifdef EEARH
out EEARH,RCLR
.endif
out EEARL,RCLR
ret
.macro Clear_EEPROM
ldx @0
ldy @1
rcall _Clear_EEPROM
.endmacro
_Clear_EEPROM:
sbic EECR,EEWE
rjmp _Clear_EEPROM
.ifdef EEARH
out EEARH,XH
.endif
out EEARL,XL
out EEDR,RCLR
sbi EECR,EEMWE
sbi EECR,EEWE
adiw XL,1
sbiw YL,1
brne _Clear_EEPROM
_Clear_EEPROM_0:
sbic EECR,EEWE
rjmp _Clear_EEPROM_0
.ifdef EEARH
out EEARH,RCLR
.endif
out EEARL,RCLR
ret
#endif
;*************************************************************************
/************************************************************************/
#if (BCD==YES)
.dseg
HEX_DEC_BUFFER:
.equ HEX_DEC_BUFFER_LENGHT = 5
.byte HEX_DEC_BUFFER_LENGHT
.cseg
Hex_Dec:
ldx HEX_DEC_BUFFER
ldi r17,HIGH(10000)
ldi r16,LOW(10000)
rcall Digit
st X+,r18
ldi r17,HIGH(1000)
ldi r16,LOW(1000)
rcall Digit
st X+,r18
ldi r17,HIGH(100)
ldi r16,LOW(100)
rcall Digit
st X+,r18
ldi r17,HIGH(10)
ldi r16,LOW(10)
rcall Digit
st X+,r18
mov r16,r14
ori r16,0x30
st X+,r16
Hex_Dec_End:
ret
Digit:
ldi r18,-1
Digit_Cycle:
inc r18
sub r14,r16
sbc r15,r17
brsh Digit_Cycle
add r14,r16
adc r15,r17
ori r18,0x30
ret
#endif
/************************************************************************/
/************************************************************************/
Empty_Action:
ret
/************************************************************************/
/************************************************************************/
Table_Bits:
.db 0b00000001, 0b00000010, 0b00000100, 0b00001000
.db 0b00010000, 0b00100000, 0b01000000, 0b10000000
/************************************************************************/
/************************************************************************/
.macro end_array
.db 0xFF,0xFF
.endmacro
/************************************************************************/
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Вот устроили из темы срач холиварный.
Эту часть надо вырезать и отнести в МЯЯЯУ.
А у меня тем временем глюки с моей программулиной даже в Протеусе. Не могу понять в чем дело. Возможно и прерывания гонят. Хотя, не должны. В эмуляторе же крутил много раз программу, там тупо крутится в главном цикле и выполняет условия. Однако, почему-то умудряется погасить один светодиод не тогда, когда надо, должен гасить оба сразу. А даже команды во всем тексте такой нет, где он гасит один светодиод...
Не пойму, как он умудряется это сделать.
и когда совсем импульсов нет, соответственно нет и прерываний. Почему тогда он не выключает их иной раз?
Эту часть надо вырезать и отнести в МЯЯЯУ. А у меня тем временем глюки с моей программулиной даже в Протеусе. Не могу понять в чем дело. Возможно и прерывания гонят. Хотя, не должны. В эмуляторе же крутил много раз программу, там тупо крутится в главном цикле и выполняет условия. Однако, почему-то умудряется погасить один светодиод не тогда, когда надо, должен гасить оба сразу. А даже команды во всем тексте такой нет, где он гасит один светодиод...
Не пойму, как он умудряется это сделать.
и когда совсем импульсов нет, соответственно нет и прерываний. Почему тогда он не выключает их иной раз?
Код: Выделить всё
Start:
cp ONBlL, PERIODL
cpc ONBlH, PERIODH
brsh ONB
rjmp T
ONB: sbi PORTB, 2
T: cp ONTumL, PERIODL ; Если
cpc ONTumH, PERIODH
brsh ONT
rjmp O
ONT: sbi PORTB, 0
O: cp OFFL, PERIODL ; Сравниваем с настоящим значением накопленного
cpc OFFH, PERIODH ; Если начисленное больше, то выключаем (скорость сильно маленькая)
brlo OFF
rjmp Start
OFF: cbi PORTB, 0
cbi PORTB, 2
rjmp Start ; Конец программы, переход на начало
Станислав
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Когда все работает, но иногда глючит причиной зачастую является ошибка сохранения флагов в обработчике прерывания или регистров. Поверьте ка что там у Вас.
Жирный плюс Вам за остановку этого беспредела.Сказочник писал(а):Вот устроили из темы срач холиварный.![]()
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
СКАЗОЧНИК писал(а):...
Программа не вся. У вас там строка есть, если начисленное больше, то выключаем, а команда стоит brlo. Или считается что если PERIOD больше?
Если происходит что-то необъяснимое, то локализуем ошибку. В вашем случае гаснет один светодиод. Значит, предполагаемые причины: в прерывании не сохраняется-восстанавливается SREG, какой-нибудь регистр. Работа с портом в прерывании и в основном цикле.
Какие функции еще выполняет пин? Может вы режим какой включаете, из-за чего гаснет светодиод.
Также следует не исключать ошибку самого протеуса. Для отладки программ лучше AVR-Studio 4.19 ничего нет. Так как это продукт самого ATMEL, то симулятор симулирует максимально приближенно к правде. Если же у студии и есть какие косяки с симулированием, то они известны.
Лично я пользуюсь всегда только студией, если нужно проверить программу. Протеусом пользовался для проверки пару раз максимум. Когда нужно было быстро проверить работоспособность связки. символьный дисплей, семисегментный дисплей.
- Starichok51
- Модератор
- Сообщения: 19045
- Зарегистрирован: Сб авг 14, 2010 15:05:51
- Откуда: г. Озерск, Челябинская обл.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
СКАЗОЧНИК писал(а):Вот устроили из темы срач холиварный.
на правах модератора удалил весь устроенный срач холиварный...
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Z_h_e писал(а):ошибка сохранения флагов в обработчике прерывания или регистров
А там я делал по вашему совету. Ой! Точно, в таймере флаги то используются! Сейчас исправлю!
Спойлер
Код: Выделить всё
; ----------
; ОБРАБОТЧИКИ ПРЕРЫВАНИЙ
; ----------
INT0add:
push temp ; Закидываем в стек темп
in temp, SREG ; Закидываем в стек СРЕГ
push temp
in temp, TIFR0 ; Проверка флага переполнения таймера
andi temp, (1<<1) ; Накладываем маску, если 1 бит был единицей, то он и останется, все остальные будут 0. Если он 0, то будет флаг Z
breq NOFLAG ; Нет флага (стоит Z), значит уходим, иначе обрабатываем флаг
out TIFR0, temp ; В темп уже есть этот флаг, как 1, снова его запихиваем и тем самым скинем флаг
inc OVF ; Добавляем еще одно переполнение к таймеру
NOFLAG: in PERIODL, TCNT0 ; Считываем значение младшего
mov PERIODH, OVF ; Считываем занчение старшего
clr OVF ; Чистим все для очередного замера
out TCNT0, OVF
pop temp ; Вытаскиваем из стека СРЕГ
out SREG, temp
pop temp ; Вытаскиваем из стека темп
reti
;----------
OVF0add:
inc OVF
cpi OVF, 251
brsh OVER
reti
OVER: ldi OVF, 250
reti
Demiurg писал(а):а команда стоит brlo. Или считается что если PERIOD больше?
Да, именно так. Если период больше всего всего, то значит импульс слишком длинный и давно пора выключить все нагрузки. ))) Даже алгоритм пришлось рисовать для этого на листочке. Вообще все конспектирую и стараюсь рисовать. Так понятнее разбираться.
Demiurg писал(а):в прерывании не сохраняется-восстанавливается SREG, какой-нибудь регистр. Работа с портом в прерывании и в основном цикле.
Demiurg писал(а):Может вы режим какой включаете, из-за чего гаснет светодиод.
Вот. В прерывании сохраняю регистры. Во втором прерывании с ними не работаю, поэтому и не трогаю. С портами не работаю в прерывании, Тини13, там альтернативных функций не так много, поэтому использую порт как есть и всего один INT0. Все...
Demiurg писал(а):Для отладки программ лучше AVR-Studio 4.19 ничего нет.
Тоже так думаю. Но сама студия в отладке показывает = все прекрасно. Даже с эмуляцией прерываний и т.д. и т.п. Все значения обрабатывает идеально.
Глючить начинает Протеус и Железо. Причем, как-то одинаково почти. В Протеусе я подаю импульсы с генератора, а в реальной жизни от спидометра на Тойота Спасио. И там и там моргает... А когда частота спидометра/генератора снижается, то выключается ближний свет, в то время, когда выключиться должны только вместе при самой маленькой скорости. Даже в программе нет такой строчки, где отдельное выключение порта... Только одновременно.
В Протеусе начал проверять, просто от безысходности. Дома нет возможности реальное железо тестировать, т.к. нет датчика скорости (или его эмулятора). Обычно Протеусом вообще не пользуюсь...
Не знаю. Буду сидеть и думать до конца. Хочу доделать это устройство. Результатами обязательно всеми поделюсь. Может кто полезное для себя возьмет или найдет.
Если кому будет интересно, выложу проект Протеуса и Прошивку.
Благодарю всех за проявленный интерес!
Starichok51 писал(а):на правах модератора

З.Ы. В верху неправильный подсчет написал по времени периода таймера.
Вот правильный:
Спойлер
Частота МК 4,8 МГц. Тмк = 0,000000208 с.Частота таймера 4,8 МГц/256 = 18750 Гц. Ттайм = 0,000053333 с.
Полный счет таймера 256 TCNT0 и еще 250 переполнений (так ограничивает прерывание), получается за примерно 3,4 с.
Минимальный период импульса указан выше = 0,0000533333 с.
Т.е. таймер может считать от f = 0.294 Гц, до f = 18750 Гц.
Мои подсчеты по замерам на реальном автомобиле при скорости в районе 5 км/ч fимп. = 8,75 Гц или Тимп. = 0,1143 с.
А при скорости 200 км/ч fимп. = 141,844 Гц или Тимп. = 0,007 с.
Запас есть, как не крути.
Думаю, надо считать несколько импульсов за период времени... или несколько импульсов измерять период, а потом вычислять среднее арифметическое, как и раньше говорил(и).
Станислав
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Протеус отлично средство отладки, просто надо понимать что это всего лишь эмулятор, но Вашу задачу он легко съест.СКАЗОЧНИК писал(а):В Протеусе начал проверять, просто от безысходности.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
У меня еще комп его плохо тянет. и иной раз виснет. 
Станислав
- Z_h_e
- Собутыльник Кота
- Сообщения: 2708
- Зарегистрирован: Сб май 14, 2011 21:16:04
- Откуда: г. Чайковский
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Виснет часто тоже. Тут приходится играться, бывает добавляешь резистор не в тему, просто не подключенный и опять все заработало. А по скорости, если убрать аналоговую часть, то работает в реальном режиме времени.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Все. Тема моя походу умерла сама собой. )))) Я только что осознал, что в городе есть светофоры и пешеходные переходы... И каждое снижение скорости или остановка будут гасить туманки и второй ближний свет. Лампам придет писец еще быстрее...
Вот блин.
У кого есть предложения, куда еще можно применять эту плату? Может использовать ее как отсечку для Жигулей? А то у меня просили.
Вот блин. У кого есть предложения, куда еще можно применять эту плату? Может использовать ее как отсечку для Жигулей? А то у меня просили.
Станислав
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
СКАЗОЧНИК писал(а):...
Смириться, успокоив себя тем, что получил бесценный опыт. Отрицательный результат - тоже результат.
А наработки когда-нибудь пригодятся в другом устройстве.
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Ассемблер (ASM) для AVR в вопросах и ответах
А ввести два режима - город и трасса? В одном ничего такого не делать (или делать иначе), в другом - переключать фары как задумано.
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Хороший вариант. ))) Все равно решили эту схему доделывать, но изменили немного критерии и включили в работу задержки, т.е. если стоим более 10 секунд, то выключить свет. А город-трасса - тоже есть, можно включить в ручную все. А можно в автоматическом режиме через эту конструкцию.
Сейчас буду додумывать.
Спасибо.
Сейчас буду додумывать.
Спасибо.
Станислав
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Код: Выделить всё
;----------
OVF0add:
inc OVF
cpi OVF, 251
brsh OVER
reti
retiКоманда CPI меняет регистр SREG. Когда Вы научитесь сохранять этот регистр , если применяете команды его изменяющие?
- СКАЗОЧНИК
- Идёт направо - песнь заводит, Налево - сказку говорит.
- Сообщения: 5000
- Зарегистрирован: Чт апр 21, 2011 17:55:50
- Откуда: Иркутск
Re: Ассемблер (ASM) для AVR в вопросах и ответах
В прерываниях у меня сохраняется этот регистр. Уже )))) 

Станислав
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Уточню. Если при скорости 200 км/3600сек измерено 141,844 имп./сек, то датчик выдает 2553 имп/км. В общем, ожидаемо. Чего нельзя сказать про скорость 5км/час. Должно получиться 3,54 имп./сек.СКАЗОЧНИК писал(а): ...Мои подсчеты по замерам на реальном автомобиле при скорости в районе 5 км/ч fимп. = 8,75 Гц или Тимп. = 0,1143 с. А при скорости 200 км/ч fимп. = 141,844 Гц или Тимп. = 0,007 с.
