Paso 5: Ejemplo #2: código
Este código es mucho más pequeño y más sencillo que el ejemplo anterior, porque esta vez no estamos utilizando el ADC. Como se puede ver, subrutina SEND_BYTE no ha cambiado y bastante mucho la misma cosa.
/* * Shift register demo #2 * ATTiny13A Running * * PIN ASSIGNMENT: * PB0 - Shift Register Clock * PB1 - Shift Register Serial Data * PB2 - Shift Register Latch(Store) * PB3 - Digital input(bit match) * PB4 - LED * PB5 - RST * */ .include "tn13Adef.inc" .def A = R16 ; g.p. variable and/or function argument .def B = R17 ; Used in SEND_BYTE and ADC_START as temporary storage .def LED = R18 ; stores current LED output .def BCT = R19 ; Bit counter for SEND_BYTE .def TIM = R20 ; Stores how many iterations of TOV0 have passed .def TMP = R21 .equ SRCK = 0 ; PB0 = Clock .equ SRDA = 1 ; PB1 = Serial Data .equ SRLC = 2 ; PB2 = Latch /* INTERRUPT VECTORS */ .org 0x0000 ; Reset interrupt rjmp RESET .org 0x0003 rjmp TC0_OV ; Timer0 Overflow interrupt /* * START!!! */ RESET: /* SETUP STACK */ ldi A, low(RAMEND) ; Set stack pointer out SPL, A /* SETUP PINS */ ldi A,0b0001_0111 ; Set output pins PB0..PB2(CLK,DATA,LATCH) out DDRB,A ; PB4 - LED output /* SETUP TIMER0 */ ldi A,0b0000_0101 ; Set Timer Prescaler 1/1024 out TCCR0B,A ; Interrupt every ~27ms ldi A,0b00000010 ; Enable Timer0 Overflow Interrupt out TIMSK0,A ; /* RESET REGISTERS */ ldi A,0x00 ; clear A ldi LED,0x10 ; Default blink speed(~1Hz) sei ; Enable interrupts /* Main loop */ MAIN: ldi A,1 ; Set the first bit ldi TMP,0 ; Temporary storage for new LED delay next: rcall SEND_BYTE ; Send A to Shift Reg. sbic PINB,3 ; Check for match or TMP,A ; Add it to result clc ; Clear carry rol A ; Rotate A breq check ; If A==0, check and start over rjmp next ; else get next bit check: ; Only assign non-zero values tst TMP ; TMP==0? breq MAIN ; skip mov LED,TMP ; else assign new LED delay rjmp MAIN /* * Sends 8-bit data from A register to Shift Register * (Same as in the prev. example) */ SEND_BYTE: ldi BCT,0b1000_0000 ; Set Bit counter next_bit: mov B,A ; Move data byte to temp and B,BCT ; Check bit breq zero ; Skip if 0 sbi PortB,SRDA ; Send Data rjmp shift ; shift right zero: cbi PortB,SRDA shift: sbi PortB,SRCK ; CLK up nop cbi PortB,SRCK ; CLK down clc ; Clear Carry flag ror BCT ; Shift bit counter brne next_bit ; Next iteration sbi PortB,SRLC ; When done, Latch nop cbi PortB,SRLC ret ; Done /* Timer 0 overflow interrupt */ TC0_OV: inc TIM ; TIM++ cp TIM,LED ; TIM>LED? brlo early ; too early push TMP ; Save old TMP value in TIM, PINB ; Read current port state ldi TMP, 0x10 ; eor TIM,TMP ; Toggle PB4 out PORTB, TIM ; ldi TIM,0 ; Reset counter pop TMP ; Restore TMP early: reti ; return