[an error occurred while processing this directive]
Если пойдет на асме, то вот:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Леонид Иванович 07 июня 2006 г. 10:41
В ответ на: Поделитесь примером программы или алгоритмом для подключения энкодера к AVR. отправлено <font color=gray>MikhailSh</font> 07 июня 2006 г. 10:01

[pre]
;----------------------------------------------------------------------------

.include "m8def.inc"
.include "macros.mac"
.include "Header.asm"

;------------------------- Interrupt Vectors: -------------------------------

.CSEG ;code segment
.org 0
rjmp Init ;reset vector
.org OC1Aaddr
rjmp Timer ;Timer1 OC vector
.org SPMaddr+1 ;skip vector table

;-------------------- Program Execution Starts Here: ------------------------

Init: ldy RAMEND
out SPL,YL ;locate stack
out SPH,YH
rcall iWdog ;start internal watchdog
rcall iPorts ;ports init
rcall iVar ;variables init
rcall iTimer ;system timer init
rcall iEnc ;encoder subsystem init
sei ;interrupts enable

;Main loop:

Main: rcall mEnc ;read encoder
;... process encoder messages
rcall mWdog ;watchdog restart
rjmp Main ;loop

;------------------------- Subroutines area: --------------------------------

;Internal watchdog init:

iWdog: wdr
ldi temp,(1< out WDTCR,temp
ldi temp,(1< out WDTCR,temp ;watchdog enable, period 260 mS

;Internal watchdog restart:

mWdog: bbrc FLAGS,WUpd,nu
clbr FLAGS,WUpd
wdr ;internal watchdog restart
nu: ret

;----------------------------------------------------------------------------

;Ports init:

iPorts: ldi temp,PUPB
out PORTB,temp ;init PORTB and on/off pullup
ldi temp,DIRB
out DDRB,temp ;set PORTB direction

ldi temp,PUPC
out PORTC,temp ;init PORTC and on/off pullup
ldi temp,DIRC
out DDRC,temp ;set PORTC direction

ldi temp,PUPD
out PORTD,temp ;init PORTD and on/off pullup
ldi temp,DIRD
out DDRD,temp ;set PORTD direction
ret

;----------------------------------------------------------------------------

;Variables init:

iVar: clr FLAGS ;clear flags
ret

;----------------------------------------------------------------------------

;System timer init:

iTimer: ldi temp,0
out TCCR1A,temp ;OC disable, PWM disable
ldi temp,(1< out TCCR1B,temp ;CTC, CK/1

ldi temp,byte2(T1Div-1)
out OCR1AH,temp ;compare register load
ldi temp,byte1(T1Div-1)
out OCR1AL,temp

in temp,TIMSK
ori temp,(1< out TIFR,temp ;clear pending interrupts
out TIMSK,temp ;output compare interrupt enable
ret

;System timer interrupt:

Timer: push temp
in temp,SREG ;save status register
push temp
push YL
push YH

stbr Flags,WUpd ;set watchdog update flag
rcall tEnc ;encoder control
;...

pop YH
pop YL
pop temp
out SREG,temp ;restore status register
pop temp
reti

;----------------------------------------------------------------------------

.include "Power.asm" ;link power control module
.include "Encoder.asm" ;link encoder control module
.include "Menu.asm" ;link menu processing module
.include "Display.asm" ;link display control module

;Encoder support module

;----------------------------------------------------------------------------

;Constantes:

.equ ENDEB = 300 ;encoder debounce delay, uS
.equ SWDEB = 50000 ;switch button debounce delay, uS
.equ ENCTMV = 100 ;encoder timer value, uS
.equ MAXV = 8 ;maximum encoder velocity

;----------------------------------------------------------------------------

;Derivated constantes:

.equ ENDEBV = ENDEB/100

.if ENDEBV > MAXBYTE
.error "out of range constant"
.endif

.equ SWDEBV = SWDEB/100

.if ENDEBV > MAXBYTE
.error "out of range constant"
.endif

;----------------------------------------------------------------------------

;Messages:

.equ msgNop = 0x00 ;no operation
.equ msgInc = 0x01 ;increment
.equ msgDec = 0x02 ;decrement
.equ msgMax = 0x03 ;set maximum
.equ msgMin = 0x04 ;set minimum
.equ msgKdn = 0x05 ;key down
.equ msgKup = 0x06 ;key up

;----------------------------------------------------------------------------

.DSEG ;Data segment

;----------------------------------------------------------------------------

.CSEG ;Code segment

;----------------------------------------------------------------------------

;Encoder subsystem init:

iEnc: ldi Msg,msgNop ;no operation
rcall EScan ;scan encoder
mov EncSt,temp ;save encoder state
clr EncS ;clear encoder step counter
clr EncV ;clear encoder velocity
ldi temp,ENCTMV ;encoder timer load
ret

;----------------------------------------------------------------------------

;Encoder read:

mEnc: rcall EScan ;scan encoder
mov Cnt,temp ;save encoder state
eor temp,EncSt ;check for changes
breq no_ch ;return, no changes

ldi temp,ENDEBV ;debounce delay for encoder
bbrc temp,2,no_sw
ldi temp,SWDEBV ;debounce delay for switch button
no_sw: rcall Delay

rcall EScan ;scan encoder
cp temp,Cnt ;check encoder state
brne no_ch ;return, bounce

mov temp,EncSt ;previous encoder state
mov EncSt,Cnt ;save new encoder state

;Switch button check:

bbrc temp,2,s_0
bbrs Cnt,2,q1x ;no changes
ldi Msg,msgKdn ;key down message
rjmp e_ret
s_0: bbrc Cnt,2,q1x ;no changes
ldi Msg,msgKup ;key up message
rjmp e_ret

;1x quadrature decoder:

q1x: bbrc temp,0,a_0
a_1: bbrc Cnt,0,a_10
rjmp no_ch
a_0: bbrs Cnt,0,a_01
rjmp no_ch
a_01: bbrc Cnt,1,pls
rjmp no_ch
a_10: bbrc Cnt,1,min
rjmp no_ch

pls: ldi Msg,msgInc ;send increment message
inc EncS ;increment encoder step counter
mov temp,EncV
cpi temp,MAXV ;check encoder velocity
brlt e_ret
ldi Msg,msgMax ;if EncV > MAXV then max message
rjmp e_ret

min: ldi Msg,msgDec ;send decrement message
dec EncS ;decrement encoder step counter
mov temp,EncV
cpi temp,-MAXV ;check encoder velocity
brge e_ret
ldi Msg,msgMin ;if EncV < -MAXV then min message
rjmp e_ret

no_ch: ldi Msg,msgNop ;send no operation message
e_ret: ret

;----------------------------------------------------------------------------

;Encoder timed task:

tEnc: dec EncTm
brne teret
ldi temp,ENCTMV
mov EncTm,temp ;encoder timer reload
mov EncV,EncS ;update encoder velocity
clr EncS
teret: ret

;----------------------------------------------------------------------------

;Scan encoder:
;Out: temp - encoder state

EScan: clr temp
Skip_if_Port_EF1_0
stbr temp,0
Skip_if_Port_EF2_0
stbr temp,1
Skip_if_Port_ESB_0
stbr temp,2
ret

;----------------------------------------------------------------------------

;Delay:
;Input: temp - delay [x100 uS]

Delay: push Cnt
de2: ldi Cnt,FCLK/100000
de1: dec Cnt ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
brne de1 ;2 = 10
dec temp
brne de2
pop Cnt
ret

;----------------------------------------------------------------------------

;Header file

;----------------------------------------------------------------------------

;Constantes:

.equ FCLK = 10000000 ;Fclk, Hz
.equ TSYS = 1000 ;time base, uS

;----------------------------------------------------------------------------

;Derivated constantes:

.equ MAXBYTE = 0xFF
.equ MAXWORD = 0xFFFF

.equ T1Div = ((((Fclk/1000)*Tsys)/100)+5)/10 ;CK/1

.if T1Div > MAXWORD
.error "out of range constant"
.endif

;----------------------------------------------------------------------------

;Port Definitions:

.equ DIRB = 0b11111111 ;Port B direction
.equ PUPB = 0b00000000 ;Port B pull-ups

.equ DIRC = 0b11001111 ;Port C direction
.equ PUPC = 0b00110000 ;Port C pull-ups
.equ EF2 = PC4 ; Encoder F2
.equ EF1 = PC5 ; Encoder F1

.equ DIRD = 0b11111110 ;Port D direction
.equ PUPD = 0b00000001 ;Port D pull-ups
.equ ESB = PD0 ; Encoder SB

;***** Ports lines control macros:

.macro Skip_if_Port_EF1_0 ;skip if EF1 = 0
sbic PINC,EF1
.endm

.macro Skip_if_Port_EF2_0 ;skip if EF2 = 0
sbic PINC,EF2
.endm

.macro Skip_if_Port_ESB_0 ;skip if ESB = 0
sbic PIND,ESB
.endm

;----------------------------------------------------------------------------

;Global Register Variables:

;r0, r1 used with mul instruction

.def EncSt = r2 ;store encoder state
.def EncS = r3 ;encoder step counter
.def EncV = r4 ;encoder velocity
.def EncTm = r5 ;encoder timer

.def temp = r16 ;temporary register temp
.def Cnt = r17 ;temporary register Cnt
.def Msg = r18 ;message code

.def FLAGS = r25 ;flags
.equ WUpd = 0 ;watchdog update flag

;r26,r27 used as X-register
;r28,r29 used as Y-register
;r30,r31 used as Z-register

;----------------------------------------------------------------------------

[/pre]

Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание

E-mail: info@telesys.ru