2007年10月19日金曜日

中間報告 (その1) -- 7seg LED Clock --



LEDの表示部分の動作を確認しました。バックグランドでSRAMにデータを書き込むとそれを表示します。ハーフトーンのフィルムを貼ってそれをすかしてLEDだけ光っているように仕上げたかったのですが、思ったほど見た目LEDが輝いていません。フィルムの透過率が思ったよりも低かった事、LEDが高輝度でない事、ダイナミック点灯でやはり輝度を落している事、などが原因として考えられます。割り込みでLED表示ルーチンをまわす当初の目論見は崩れ、表示部分がメインでぐるぐるまわってます。現在、RTC(秋月電子のRTC-8564NB)とのインタフェース部分を書いています。I2C初挑戦です。プラス、4つのタクトスイッチをつかったユーザーインターフェースです。

実験中のファームなので最終形には必要の無い部分があります。約1秒おきに2種類の数字が交互に表示されればOKです。

;;; 7seg LED clock ver 0.07 ;;;
;;; initial check for LED on/off ;;;
;;; store data into SRAM ;;;
;;; read out data from SRAM, ;;;
;;; serial parallel conversion, ;;;
;;; and put it on LED ;;;
;;; timer interval : 1 second ;;;
;;; as of Oct/18/2007 ;;;

; 0 1 2 3 4 5 6 7
; SCK (PB2): ~~~\_/~\_/~\_/~\_/~\_/~\_/~\_/~\_/~~~~~~~
; SegBit (PB1): --------[g]-[f]-[e]-[d]-[c]-[b]-[a]_*1___
; Trans (PB0): ____________________________________/~\__
;
; *1 SegBit=0 (1st cycle), SegBit=1(2nd-7th cycle)

.device ATtiny2313

.equ SramUse = 8
.equ STACKTOP = RAMEND - SramUse
.equ SCK = 2
.equ SegBit = 1
.equ Trans = 0

;;; Below 8 bytes are the register for ;;;
;;; contents of the LED digit data ;;;
.dseg
.org RAMEND - (SramUse - 1)
Digits:
.byte 8 ; data container of LED

.cseg
RJMP RESET ; 00 reset handler
RETI ; 01 external interupt0 handler
RETI ; 02 external interupt1 handler
RETI ; 03 timer1 capture handler
RETI ; 04 timer1 compare A handler
RJMP Timer1Int ; 05 timer1 overflow handler
RJMP Timer0Int ; 06 timer0 overflow handler
RETI ; 07 USART0 RX complete handler
RETI ; 08 USART0 UDR empty handler
RETI ; 09 USART0 TX complete handler
RETI ; 0A Analog comparator handler
RETI ; 0B Pin change interrupt
RETI ; 0C timer1 compare B handler
RETI ; 0D timer0 compare A handler
RETI ; 0E timer0 compare B handler
RETI ; 0F USI start handler
RETI ; 10 USI overflow handler
RETI ; 11 EEPROM ready handler
RETI ; 12 watchdog overflow handler


RESET:
ldi r16, STACKTOP
out SPL, r16 ; set low end address for stack pointer
ldi r16, 0b10000010 ; enable timer-0&1 overflow interrupt request
out TIMSK, r16
sei ; enable global interrupt

;;; Port Setting ;;;
;;; PB0-PB7 is used for LED output ;;;
;;; PD0-PD6 is set as input ;;;
ldi r16, 0b11111111 ; set all PORTB as Output
out DDRB, r16 ;
ldi r16, 0x00
out PORTB, R16
ldi r16, 0x00
out DDRD, r16
ldi r16, 0x7F ; set all PORTD Pull-up Active
out PORTD, r16

rcall DataForm

ldi r24, 0 ;;; Temp for TEST
rcall Timer1Set ;;; Temp for TEST

;*******************************************************************
;;; Main Loop ;;;
MAIN:
rcall LEDdisp
rjmp MAIN


;*******************************************************************
;;; Data Formatting ;;;
;;; r16 point out 7seg data ;;;
;;; r17 point out SRAM store address ;;;
DataForm:
ldi r16, 9 ; set data = 9
ldi r17, 0 ; set address = 0
rcall DataSet
ldi r16, 7 ; set data = 7
ldi r17, 1 ; set address = 1
rcall DataSet
ldi r16, 5 ; set data = 5
ldi r17, 2 ; set address = 2
rcall DataSet
ldi r16, 3 ; set data = 3
ldi r17, 3 ; set address = 3
rcall DataSet
ldi r16, 8 ; set data = 8
ldi r17, 4 ; set address = 4
rcall DataSet
ldi r16, 6 ; set data = 6
ldi r17, 5 ; set address = 5
rcall DataSet
ldi r16, 4 ; set data = 4
ldi r17, 6 ; set address = 6
rcall DataSet
ldi r16, 2 ; set data = 2
ldi r17, 7 ; set address = 7
rcall DataSet
ret

;*******************************************************************
;;; Data Formatting ;;; T E M P T E M P
;;; r16 point out 7seg data ;;;
;;; r17 point out SRAM store address ;;; T E M P T E M P
DataForm2:
ldi r16, 8 ; set data = 8
ldi r17, 0 ; set address = 0
rcall DataSet
ldi r16, 9 ; set data = 9
ldi r17, 1 ; set address = 1
rcall DataSet
ldi r16, 9 ; set data = 9
ldi r17, 2 ; set address = 2
rcall DataSet
ldi r16, 9 ; set data = 9
ldi r17, 3 ; set address = 3
rcall DataSet
ldi r16, 4 ; set data = 4
ldi r17, 4 ; set address = 4
rcall DataSet
ldi r16, 8 ; set data = 8
ldi r17, 5 ; set address = 5
rcall DataSet
ldi r16, 0 ; set data = 0
ldi r17, 6 ; set address = 6
rcall DataSet
ldi r16, 4 ; set data = 4
ldi r17, 7 ; set address = 7
rcall DataSet
ret
;;; T E M P T E M P T E M P T E M P T E M P T E M P ;;;


;*******************************************************************
;;; Data Setting ;;;
;;; from program domain (flash) : r16 ;;;
;;; to SRAM domain (memory) : r17 ;;;
;;; called via r16(data) & r17(adrs) ;;;
DataSet:
ldi ZH, high(2*LEDdata) ; get data address on the program domain
ldi ZL, low(2*LEDdata)
ldi YH, high(Digits) ; get data address on the SRAM domain
ldi YL, low(Digits)

add ZL, r16 ; set target 7seg data
add YL, r17 ; set destination address of SRAM

lpm r18, Z ; load program memory to r18
st Y, r18 ; r18 data store into SRAM (no post inc.)
ret

;*******************************************************************
;;; C A U T I O N ;;;
;;; Do NOT change other of PB0/1/2 ;;;
;;; Need to keep state for SCL & SDA ;;;

;;; LED Display Update ;;;
;;; 1) disable any interrupts this term ;;;
;;; 2) load 1digit(8bit) data from SRAM ;;;
;;; 3) 7segment data transfer (loop2) ;;;
;;; 4) serial to parallel, Disp. update ;;;
;;; 5) cyclic func. for 8digits (loop1) ;;;
;;; 6) accept interrupt after Disp. ;;;
LEDdisp:
cli ; disable any interrupts
in r21, PORTB ; load data in PORTB register
sbi PORTB, SCK ; set bit2 for SCK high
ldi r16, 7 ; set number of digits
ldi r18, 7 ; set distination number for comparison
ldi YH, high(Digits) ; get data address on the program domain
ldi YL, low(Digits)
LEDdisp_loop1:
ldi r17, 7 ; set number of segment
ld r20, Y+ ; store data into r20, and post increment
LEDdisp_loop2:
cbi PORTB, SCK ; clear bit2 for SCK falling edge
bst r20, 7 ; MSB of r20 put into T-flg
bld r21, SegBit ; T-flg store into Segment Bit of r21
out PORTB, r21 ; output segment sequential data
sbi PORTB, SCK ; set bit2 for SCK rising edge
rol r20 ; rotate left through carry
dec r17 ; decrement segment loop counter
brge LEDdisp_loop2 ; finish all segment data sending?
ori r21, 0b00000010
; sbr r21, SegBit ; sent 1 to sifter on other digit
cp r16, r18
brne LEDDataTrans ; 1st digit or other?
andi r21, 0b11111101
; cbr r21, SegBit ; sent 0 to sifter on 1st digit
LEDDataTrans:
out PORTB, r21 ; set segment bit
sbi PORTB, Trans ; Serial to Parallel transfer start
cbi PORTB, Trans ; Serial to Parallel transfer end
dec r16
brge LEDdisp_loop1
ldi r16, 34 ; for equalize the brightness
LEDFinalize: ; among each digits of LED
dec r16 ;
brge LEDFinalize
sbi PORTB, SegBit ; set bit2 = 1
sbi PORTB, Trans ; shift digit position counter by 1
cbi PORTB, Trans ; for turnning off last digit LED
sei ; enable interrupts
ret

;*******************************************************************
;;; Set Timer0 for 250000us(250ms) ;;;
;;; fosc = 1MHz ;;;
;;; 1.0usec * 1024 * 244 = 249856usec ;;;
;;; 1/1024 prescale, 244cycle ;;;
Timer0Set:
ldi r16, 0x0C ; 256 - 244 = 12(0x0C)
out TCNT0, r16 ; set counter value : 0x0C
ldi r16, 0b00000101 ; prescaler : 1/1024
out TCCR0B, r16 ; set timer0
ret

;*******************************************************************
;;; Set Timer-1 for 1000000us(1s) ;;;
;;; fosc = 1MHz ;;;
;;; 1.0usec * 256 * 3907 = 1000192usec ;;;
;;; 1/256 prescale, 3907cycle ;;;
Timer1Set:
ldi r16,0xF0 ; 65535 - 3907 = 61628(0xF0BC)
out TCNT1H,r16 ; set upper counter value : 0xF0
ldi r16,0xBC ; 65535 - 3907 = 61628(0xF0BC)
out TCNT1L,r16 ; set lower counter value : 0xBC
ldi r16,0b00000100 ; prescaler : 1/256
out TCCR1B,r16 ; set timer1
ret

;*******************************************************************
Timer0Int:
reti

;*******************************************************************
Timer1Int:
in r19, SREG
rcall Timer1Set ;;; Temp for TEST

cpi r24, 0
breq Fin
rcall DataForm
ldi r24, 0
rjmp End
Fin:
rcall DataForm2
ldi r24, 1
End:
out SREG, r19
reti

;*******************************************************************
LEDdata:
; 0,1,2,3,4,5,6,7,8,9 --- already reversed...
;.db 0x77,0x06,0x5b,0x1f,0x2e,0x3d,0x7d,0x27,0x7f,0x3f
.db 0x88,0xf9,0xa4,0xe0,0xd1,0xc2,0x82,0xd8,0x80,0xc0

3 件のコメント:

まちゅう さんのコメント...

出来上がって実際に使っているんですが、まだ中間報告(その2)が書けていません。そのうちに書きます。

匿名 さんのコメント...

てすと

匿名 さんのコメント...

てすと2

++ Myself ++

普通(?)のサラリーマン -- 生活のすきま時間にキーボードとはんだごてを持ち替えてプログラミングと電子工作してます