ON 20030829@7:18:53 PM at page: http://www.sxlist.com/techref/scenix/lib/io/index.htm KM-AAA-31 Ken Mathis Code:
;FILE NAME: 4 byte shift out short ver. ;date:8/28/03 ;Programmer:Ken Mathis ;Purpose of this program is to expand the number of SX28 output ;ports using a 74HC595 serial shift register. Using 3 output pins of the ;SX will add 29 additional output ports. These additional output ports are ;used for non-critical timing applications, such as controlling an LED matrix ;or 4 seven segment displays. ;data is shifted out of the SX into the 74HC595's ;rc ports used to control the shift register and send data out to the 595's ;pin 13 of '595 (Output Enable\) hard wired to ground ;pin 10 of '595 (Master Reset\) hard wired to +5 via 10k ohms ;pin 9 (Q7') of the most significant '595 is connected to the next lower '595 ;pin 14 (data input) and each sucessive pin 9 connects to the next lower ;'595 pin 14 (data input). The Q7' output of the most significant '595 is the ;input to the next lower '595 ;sx connections to most significant'595: rc.7 (data) >>> '595 pin14 ;rc.5 (latch) >>> '595 pin12 - (all 595's) ;rc.4 (clock) >>> '595 pin11 - (all 595's) ;--------------------------- ;4 byte data is loaded into temporary registers temp1 and the following 3 ;addresses (temp1+1, temp1+2, temp1+3) -- MOST SIGNIFICANT BYTE is temp1+3 ;data is shifted out Least Significant Byte first. The 595's present each byte ;with the least significant bit on Q7 and the most significant bit on Q0 ;--------------------------- ;DELAY ROUTINE generated by using the Delay Code Generator, courtesy of ;NICKOLAI GOLOVCHENKO ifdef __SASM DEVICE SX28L, STACKX, OPTIONX IRC_CAL IRC_FAST FREQ 50_000_000 else DEVICE SX28AC, OPTIONX endif DEVICE TURBO, OSCHS2, WATCHDOG RESET START ;place variables here org $08 temp1 ds 4 ;used to hold 4 bytes to shift out temp2 ds 1 ;used to count down 8 bits temp3 ds 1 ;used to count down 4 bytes d1 ds 1 ;used in delay routine d2 ds 1 ;ditto d3 ds 1 ;ditto data = rc.7 ;assign data to rc.7 clock = rc.4 ;assign clock to rc.4 latch = rc.5 ;assign latch to rc.5 ;any calls should be placed on first page between org $000 and org $100 org $000 ;-----5 uS delay (courtesy of Nickolai Golovchenko) del_5uS mov w, #$3d mov d1, w del_5uS_0 decsz d1 jmp del_5uS_0 nop nop ret ;-----clock pulse generation to shift data out of SX shift_out call del_5uS ;5 uS set-up time setb clock ;make clock (rc.4) high call del_5uS ;5 uS hold time clrb clock ;make clock low ret ;return ;-----move bit to shift out into carry rotate rr ind ;move into carry lsb of file register pointed to by ;current value if fsr jc high ;if carry is high jump to "high" and make data (rc.7) high clrb data ;if carry is low make data (rc.7) low jmp out ;skip over next line high setb data ;make data (rc.7) high out ret ;return org $100 Start ;port initialization mov !ra,#$0 ;ra outputs mov !rb,#$FF mov !rb,#$01 ;rb inputs mov !rc,#$00 ;rc outputs again clrb clock ;make clock pin low clrb data ;make data pin low clrb latch ;make latch pin low ;-----These lines of code used to verify operation of program by ;loading known values into the 4 bytes that will be shifted out of ;the SX28 into the four (4) 74HC595's. Change values as needed to ;test program mov w,#$93 mov temp1,w mov w,#$11 mov temp1+1,w mov w,#$44 mov temp1+2,w mov w,#$7e mov temp1+3,w ;-----End of test section ;prepare fsr to load fsr with the register that will hold the ;lease significant byte. EXAMPLE, the least significant byte will be in ;register $08, therefore fsr must start at $08 mov w,#$08 mov fsr,w ;load fsr with register $08 mov temp2,w ;load 8 bit countdown with $08 mov temp3,w ;load 4 byte countdown with $08 (will be changed ;to 4 later clc ;ensure carry is zero rr temp3 ;change value from $08 to $04 call rotate ;move ls bit into carry and set data to reflect ;carry was high or low (done inside rotate sub-routine) call shift_out ;generate clock pulses to shift data out decsz temp2 ;decrement 8 bit countdown until zero jmp $-3 ;go up three lines to "call rotate" inc fsr ;increment fsr so ind now refers to the next highest byte mov w,#$08 mov temp2,w ;reload 8 but countdown clc ;clear carry flag (if not cleared 4 byte countdown may ;not work correctly if carry was set from last shiftout) decsz temp3 ;decrement 4 byte countdown jmp $-9 ;go up 9 lines to "call rotate" call del_5uS ;wait 5 uS setb latch ;move data from '595 internal registers to ouput registers call del_5uS ;5 uS hold time clrb latch ;make latch low nop ; jmp again ;do it again - or continue with the rest of the "real program" END ;end of the program