AVR Atmega328p マイクロコントローラーのコードを作成中です。マイクロコントローラーは、エンコーダーを読み取り、エンコーダーの回転に基づいて r23 をインクリメントまたはデクリメントすることになっています。残念ながら、現時点では、エンコーダーを回す方向に関係なく、出力は 0 に達するまでしか減少せず、その後 255 から始まります。
私のコードは非常に単純で、エンコーダーの以前の状態と現在の状態を組み合わせたテーブル ルックアップ値に基づいています。前の状態と現在の状態を組み合わせて有効なターンを作成しない場合、エラーが返され、コードは何もしません。有効な状態変化が発生すると、1 または -1 が r24 を介して r23 に追加されます。
マイクロコントローラーにエンコーダーを読み取らせるのに問題はありませんが、r23 のオーバーフローを防ぐ方法がわかりません。私の問題は、255 をヒットして 1 を追加すると、レジスタがオーバーフローして 0 になることです。レジスタがゼロになるのは望ましくありません。エンコーダーを反対方向に回転させるまで、255 のままにしておきます。0 についても同じ問題があります。レジスタが 0 で -1 を追加した場合、レジスタを 255 にしたくないので、反対方向に回転するまで 0 のままにしておきます。
固定観念にとらわれずに考えることに問題はありません。解決策やアイデアがあれば、お気軽に投稿してください。
;**** A P P L I C A T I O N N O T E *************************************
;*
;* Title:
;* Version:
;* Last updated:
;* Target: AVR Dragon
;*
;*
;* DESCRIPTION
;*
;*.device ATmega328P @ 1M clock speed
;*
;* This is a simple program to test an optical encoder
;***************************************************************************
.include "m328Pdef.inc"
.org 0x0000
jmp RESET ;Reset Handle
.org 0x0008
jmp Interrupt1 ; PCINT1 Handler
enc_states:
.db 0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0
RESET:
;Setup stack pointer
ldi temp, low(RAMEND)
out SPL, temp
ldi temp, high(RAMEND)
out SPH, temp
//Set Port B pins to output
ser temp ; Set Register Rd <-- 0xff (output)
out DDRB,temp ; set all PORTB bits as output
//Clear analog input pins and enable pull ups on Pin 0 and 1 (Port C)
clr temp
out DDRC, temp ;all pins input
ldi temp, (1<<PC1)|(1<<PC0)
out PORTC,temp ;Enable pullups on Pin 0 and 1
//Set Port D pins to output
ser temp ; Set Register Rd <-- 0xff
out DDRD,temp ; set all PORTD bits as output
//Enable encoder pins interrupt sources (Encoder 1)
ldi temp, (1<<PCINT9)|(1<<PCINT8)
sts PCMSK1, temp
//Enable encoder pins interrupt sources (Encoder 2)
// ldi temp, (1<<PCINT11)|(1<<PCINT10)
// sts PCMSK1, temp
//Enable pin change interrupts
ldi temp, (1<<PCIE1)
sts PCICR, temp
//Enable global interrupts
sei
//Lookup table initial value
ldi ZL, 0x00 ;lookup table index and initial state
.def temp = r16
clr r25
clr r24
clr r23
loop:
out PORTB, r23
jmp loop
Interrupt1:
// Push SREG, etc
in r25, PORTC ;encoder value from PORTC
ldi ZH, High(enc_states*2) ; setup Z pointer hi
ldi ZL, Low (enc_states*2) ; setup Z pointer lo
rol r22 ;remember previous state and shift left twice
rol r22
cbr r25, 0xFC ;clear encoder bits 7:2
mov r21,r25
or r25, r22 ;combine encoder bits with old bits
cbr r25, 0xF0 ;clear bits 7:4 for table lookup
mov r22, r25 ;save table lookup value
mov ZL, r25 ;load index value into table
lpm r24, z ;get result
add r23,r24
// Pop SREG, etc.
reti