************************************************************* * Switched Capacitor LCD Driver Routines * Alec Bath HC11 Version ************************************************************* * 8.00 MHz/4/8 = 250kHz, 4uS = Timer Count Rate * For 1 Khz, 250 kHz/ 1 khz = 250 cts, * 125 cts / half wave, ~12 cts / 5% duty cycle * * Counts(Hi/Lo) Hex (Hi/Lo) % Duty Cycle * ------------- ------------- ------------- * 197 / 53 $00C5 / $0035 80 * 185 / 65 $00B9 / $0041 75 * 173 / 77 $00AD / $004D 70 * 161 / 89 $00A1 / $0059 65 * 149 / 101 $0095 / $0065 60 * 137 / 113 $0089 / $0071 55 * 125 / 125 $007D / $007D 50 * 113 / 137 $0071 / $0089 45 * 101 / 149 $0065 / $0095 40 * 89 / 161 $0059 / $00A1 35 * 77 / 173 $004D / $00AD 30 * 65 / 185 $0041 / $00B9 25 * 53 / 197 $0035 / $00C5 20 ************** Register Equates ******************** * Register Equates offset from $1000 (X-register) PORTA equ $00 ; Port A TOC2 equ $18 ; Output Compare Register 2, Low Byte TCTL1 equ $20 ; Timer Control Register 1 TMSK1 equ $22 ; Timer Mask Register 1 TFLG1 equ $23 ; Timer Flag Register 1 TMSK2 equ $24 ; Timer Mask Register 2 ****************** RAM Equates ********************* RAM_START org $0000 ; Start of RAM DUMMY1 rmb 1 ; Dummy MSB Byte SWCAP_HI rmb 1 ; Hi Freq PWM RAM location DUMMY2 rmb 1 ; Dummy MSB Byte SWCAP_LO rmb 1 ; Lo Freq PWM RAM location ****************** Subroutines ********************** * Descriptions: * * SWCAP_ON: Enable Voltage Inverter, 50% duty * SWCAP_OFF: Disable Voltage Inverter * SWCAP_INT: Interrupt Rtn for Timer Output Compare * 47 cycles max * SWCAP_SWITCH: Contrast Switch subroutine, Up/Down * * 79 bytes total ROM space, 4 bytes RAM org $f800 ; start of code SWCAP_ON ; enable output ldaa #!125 ; 1 kHz freq, 50% duty cycle staa SWCAP_HI ; store high-side pulse byte staa SWCAP_LO ; store low-side pulse byte bset TMSK2,X,$02 ; divide by 8 prescaler ldaa #%01000000 ; staa TCTL1,X ; toggle OC2 on successful ; compare staa TMSK1,X ; enable OC2 interrupt staa TFLG1,X ; clear flag cli ; enable interrupts rts ; exit subroutine SWCAP_OFF ; disable output bclr TCTL1,X,$40 ; disable OC2 output bclr TMSK1,X,$40 ; disable OC2 interrupt rts ; exit subroutine SWCAP_INT ; update OC2 settings ldx #$1000 ; register offset brclr PORTA,X,$40,SWCAP_INT_HI ; H/L level? SWCAP_INT_LO ; update for low-side pulse ldd TOC2,X ; load OC2 addd SWCAP_LO-1 ; add low-side pulse value std TOC2,X ; update bra SWCAP_INT_DONE ; exit SWCAP_INT_HI ; update for high-side pulse ldd TOC2,X ; load OC2 addd SWCAP_HI-1 ; add high-side pulse value std TOC2,X ; update SWCAP_INT_DONE ; exit bclr TFLG1,X,$BF ; clear OC2F rti ; return from interrupt SWCAP_SWITCH ; increment OC2 duty cycle 5% ldaa SWCAP_HI ; load high-side pulse value cmpa #!197 ; 80% ? beq SWCAP_SW_OVER ; rollover if max'ed out ldaa SWCAP_HI ; load high-side pulse value adda #!12 ; 12 counts / 5% duty cycle change staa SWCAP_HI ; update high-side pulse value ldaa SWCAP_LO ; load low-side pulse value suba #!12 ; 12 counts / 5% duty cycle change staa SWCAP_LO ; update low-side pulse value rts ; exit subroutine SWCAP_SW_OVER ; rollover (20% duty cycle) ldaa #!53 ; high-side pulse value = 53 counts staa SWCAP_HI ; update ldaa #!197 ; low-side pulse value = 197 counts staa SWCAP_LO ; update SWCAP_SW_DONE ; finished rts ; exit subroutine