Erweiterung der Steuerung mit Augenbewegung durch Servos.

Belegung | Bedeutung | Pin | Pin | Bedeutung | Belegung | |
---|---|---|---|---|---|---|
MOSI | (MOSI) PB0 | 1 | A T t i n y 26 |
20 | PA0 | |
MISO | (MISO) PB1 | 2 | 19 | PA1 | ||
SCK | (SCK) PB2 | 3 | 18 | PA2 | ||
PB3 | 4 | 17 | PA3 | |||
Vcc | VCC | 5 | 16 | GND | Gnd | |
Gnd | GND | 6 | 15 | AVCC | Vcc | |
PB4 | 7 | 14 | PA4 | |||
ServoR | PB5 | 8 | 13 | PA5 | ||
ServoL | PB6 | 9 | 12 | PA6 | ||
Reset | (!Reset) PB7 | 10 | 11 | PA7 |
Kodierung der Augenbewegungen
Zwei Figuren sollen die Augen bewegen. Vier Augenpositionen reichen aus. Eine Augenbewegung soll in einem Byte gespeichert werden.
BIt | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Belegung | Zeit | S-L | S-R |
Hex | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Augenposition Links Rechts | 0 0 | 0 1 | 0 2 | 0 3 | 1 0 | 1 1 | 1 2 | 1 3 | 2 0 | 2 1 | 2 2 | 2 3 | 3 0 | 3 1 | 3 2 | 3 3 |
Programmieradapter
Bedeutung | Pin | 6 Pol | Pin | Bedeutung |
---|---|---|---|---|
MISO | 1 | 2 | VTG (VCC) | |
SCK | 3 | 4 | MOSI | |
Reset | 5 | 6 | GND |
;****** Augenzwinker 0.1 (c) Oliver Mezger 31.05.2007.
.include "tn26def.inc"
;********* Hardware-Verbindungen
;*** PortB
.equ BlinkLED = 6
.equ sLo = 5 ;Pin von linkem Servo-Ausgang
.equ sRo = 4 ;Pin von rechtem Servo-Ausgang
.equ selfTest = 3
;********* Software
.def stat = R3 ;Speichern des Status waehrend Interrupt
.def itempL = R4 ;Temoraere Register fuer Interrupts
.def temp = R16 ;Temp-Register zum Arbeiten
.def temp2 = R17
.def servoL = R18 ;Position von ServoL
.def servoR = R19 ;Position von ServoR
.def itemp = R20 ;Temoraere Register fuer Interrupts
.def sysTick = R21 ;Zaehlt die Timer1 Ueberlaeufe
.def sysTime = R22 ;Interne Zeit
.def eyeWait = R23
.def eyeData = R24
.set cpuClock = 1 ;Frequenz 1 MHz
.set timePrescale = 64
.set timeBase = timePrescale / cpuClock
.set servoNeutralTime = 1420 ;Mittelstellung in mikroSec
.set servoMi = servoNeutralTime / timeBase ;Mittelstellung der Servos
.set sysTimeDiv = 500000 / 256 / timeBase ;damit SysTime
rjmp init ;Reset
reti ;IRQ0
reti ;IRQ1
rjmp T1_Comp ;T1 Compare A
reti ;T1 Compare B
rjmp T1_Over ;T1 Overflow
reti ;T0 Overflow
init:
ldi temp,0b01110000
out DDRB,temp ;PortB als Ausgang
ldi temp,0b11001111
out PORTB,temp
ldi temp,0xff
out PORTA,temp ;Alle Pull-Up an
ldi temp,RAMEND ;Oberste RAM-Adresse holen
out SP, temp ;Stack-Pointer initialisieren
ldi servoL,servoMi
ldi servoR,servoMi
timer1_first_set:
ldi temp,7
out TCCR1B,temp ;PreScaler /64
ldi temp,0b01000100 ;Timer1 Overflow Interupt Flag
out TIMSK,temp ;Timer-Interrupt freigeben
ldi ZH,high(serPositionen*2)
ldi ZL,low(serPositionen*2)
ldi XH,high(serPos)
ldi XL,low(serPos)
ladeSerPositionen:
lpm temp,Z
cpi temp,0
breq endeLade
adiw Z,1
st X+,temp
rjmp ladeSerPositionen
endeLade:
rcall ladeMoves
ldi itemp,8
startwarte:
sbi PORTB,BlinkLED
rcall wait
cbi PORTB,BlinkLED
rcall wait
dec itemp
brne startwarte
sbi PORTB,BlinkLED
ldi eyeWait,2
sei ;Interrupts global freigeben (I-Bit)
rjmp main
T1_Over:
in stat,SREG ;Statusregister retten
inc sysTick ;
cpi sysTick,sysTimeDiv
brmi t1over1
clr sysTick
inc sysTime
t1over1:
mov itempL,servoL ;Linker Servo
rcall T1_timeMark ;Ende Marke setzen
sbi PORTB,sLo ;Linger Servo start
t1overout:
out SREG,stat ;Statusregister herstellen
reti
T1_Comp:
in stat,SREG ;Statusregister retten
sbic PORTB,sLo ;Test, ob ServoL set
rjmp serLfin ;Ja, dann zu ServoL-Finish
sbic PORTB,sRo ;Test, ob ServoR set
rjmp serRfin ;Ja, dann zu ServoR-Finish
rjmp T1_fin ;Hier weitere Servos einfuegen
serLfin:
cbi PORTB,sLo ;Bit ServoL clear
mov itempL,servoR ;Weiter mit ServoR
rcall T1_timeMark ;Ende Marke setzen
sbi PORTB,sRo ;ServoR set
rjmp T1_fin
serRfin:
cbi PORTB,sRo ;Bit ServoR clear
T1_fin:
out SREG,stat ;Statusregister herstellen
reti
T1_timeMark:
in itemp,TCNT1 ;Counter1 Low einlesen
add itempL,itemp ;Addiere zu Counter1
out OCR1A,itempL ;ins Compare1 Register schreiben
ret
main:
sbrc sysTime,1 ;wenn Bit 1 gesetzt
rjmp ma_setled ;setze Leds
cbi PORTB,BlinkLED ;sonst loesche ledS
rjmp mainEye
ma_setled:
sbi PORTB,BlinkLED ;LED Spain leuchtet
mainEye:
cp sysTime,eyeWait
brlo main
clr sysTime
lpm eyeData,Z
cpi eyeData,0
breq eyeVonAnfang
adiw Z,1
mov eyeWait,eyeData
swap eyeWait
andi eyeWait,$0f
mov temp2,eyeData
asr temp2
asr temp2
andi temp2,3
ldi XH,high(serPos)
ldi XL,low(serPos)
add XL,temp2
ld temp,X
mov servoL,temp
mov temp2,eyeData
andi temp2,3
ldi XH,high(serPos)
ldi XL,low(serPos)
add XL,temp2
ld temp,X
mov servoR,temp
rjmp main
eyeVonAnfang:
rcall ladeMoves
rjmp main
wait:
ldi temp,100 ;aeusseren Zaehler laden: 80 bei 4MHz
wl1:
ldi temp2,250 ;inneren Zaehler laden
wl2:
nop
dec temp2 ;temp2--
brne wl2 ;Sprung wenn nicht null
dec temp ;temp--
brne wl1 ;Sprung wenn nicht null
ret
ladeMoves:
sbis PINB,selfTest
rjmp normalMoves
ldi ZH,high(testMoves*2)
ldi ZL,low(testMoves*2)
ret
normalMoves:
ldi ZH,high(eyeMoves*2)
ldi ZL,low(eyeMoves*2)
ret
serPositionen: .db servoMi*0.75,servoMi*0.85,servoMi*1.0,servoMi*1.15,0 ; Servo Positionen
testMoves: .db $45,$4a,$45,$40,$4f,$60,$65,$6f,0
eyeMoves: .db $25,$2a,$2f,$23,$24,$3a,$44,$22,$51,$32,$21,$15,$12,$3c,$3a,$2d,$1c,$1d,$1c,$1d,$1c,0
.dseg ;Datenbereich
serPos: .byte 4
Am Anfang das Material: