;From: andrew.mcmeikan at mitswa.com.au ;be carefull when assembling ;there is a lookup table that MUST NOT cross a ;256 byte boundry ---- CHECK IT ;thermal printer controler innerloop = 0ff lilloop = 01 bigloop =0ff strobe macro bt SETB $13.bt ;bit for strobe CLRB 0b.7 ;dont want interupts CALL outsr ;clock it out CALL lildly ;let it burn in SETB 0b.7 ;re-enable interupts CLRB $13.bt ;so next outsr clears it endm ORG $0000 JMP main ORG $0004 ;entry occurs in here when host pulls strobe signal low ;to indicate data that requires printing ;useing this int routine occupies two levels of stack ;one for the return address and one for outsr's return ;centronics pinouts ; pin 1 strobe is connected to RB0 ; pin 2 data1 " " RA1 ; pin 3 data2 " " RA2 ; pin 4 data3 " " RA3 ; pin 5 data4 " " RA4 ; pin 6 data5 " " RB1 ; pin 7 data6 " " RB2 ; pin 8 data7 " " RB3 ; pin 9 data8 " " RB4 ; pin10 ack " " Cap from BSY this dips low ; when want next byte ; pin11 busy is connected to RA0 High= offline ; pin12 Paper out is connected to photocell High=no paper ;pins 19 to 30 are signal grounds GND ; pin31 INT is connected to RESET (via diode) ; and is used to initialize printer SETB RA.0 ;say we are busy ;read both ports to get byte of data MOV W, >>RA ;read port a shifting data down one AND W, #0f ;only keep bottom bits MOV $16, W ;keep incomming data here MOV W, >>RB ;read port b shifting down one AND W, #0f ;wipe out extraneous bits MOV $17, W ;waste another register MOV W, <>$17 ;get 'b' data lower into upper W OR $16, W ;or top bits into data ;bit pattern from host now in 0x16 INC 0e ;increment our count of bytes ;clock data into thermal head MOV W, #08 ;for 8 bits MOV $17, W ;better keep count of it clkhd: RL $16 ;rotate it thru carry SETB $12.4 ;set data high SC ;check the carry flag CLRB $12.4 ;clear data if required CALL outsr SETB $12.5 ;clock that bit in CALL outsr CLRB $12.5 ;drop clock again CALL outsr DECSZ $17 ;have we finished loop yet ? JMP clkhd ;guess not ;no point doing the extra shift as we are just ;throwing the data away once it is in the head ;if byte count=max then lets latch and let the main routine ; print it MOV W, #$c0 ;try 192 ;216 max bytes per line 1728 bits MOV W, 0e-w ;check max against our byte count SZ ;the same? result of zero? JMP continue ;no its ok, head not full yet ;need to latch thermal head ; We do not not lower busy here ;as main routine will do so once it has reset ;the counter. SETB $12.6 ;latch bit for thermal head CALL outsr ;send- no one else better be using it CLRB $12.6 ;put back CALL outsr ;send that to JMP exint ;leave int handler continue: ;tell host we are no longer busy, get next byte CLRB RA.0 ;bring BSY low ;and fall thru to exit :) exint: ;now restore to before interupt RETI main ;thermal printer control program 192 dpi 9 inch 1728 pixels ;need to set up direction bits for ports ;and set initial pin levels MOV W, #$C0 MOV !OPTION, W ;set options RTW and RTI on so OptionX can be used ;pullups mov M, #$0E mov !RA,#$FF mov !RB,#$FF ;porta as input except RA.0 MOV RA, #$ff ;set all pins high on port a mov M, #$0F MOV W, #$FE ;RA0 as output ;portb interrupt on neg edge is the default MOV RB, #01f ;make bits 6,7 &5 low mov M, #$0F MOV !RB, #01f ;port b 5,6,7 as output MOV W, #$08 ;specify which phase to start on MOV $15, W ;store it somewhere safe CLR $0E ;zero byte count for head MOV W, #$00 ;phases off clk,lat,data, strb off MOV $12, W ;data for shift reg 1 MOV W, #00 ;all strobes off (low) MOV $13, W ;data for shift reg 2 CALL outsr ;set all pins high except for stepper MOV W, #$90 ;enable RB0 and GIE interupt bits MOV $0B, W ;interupts now turned on! CLRB RA.0 ;say we are not busy p1=8;9 ;1 p2=4;8 ;3 ;ok here are definitions of how the shift registers are wired p3=2;0c;2 ; ok on 0x12 bit0 stepper phase A p4=1;4 ;6 ; bit1 " " B p5=8;6 ;4 ; bit2 " " C p6=4;2 ;0c ; bit3 " " D p7=2;3 ;8 ; bit4 Data for thermal head p8=1;1 ;9 ; bit5 Clock for thermal Head ; bit6 Latch for thermal head ; bit7 strobe 1 for thermal head; ; 0x13 bit0 to bit7 rest of strobes for head mloop: ;this is the loopy bit of main ;we sit in here till we get a full head ;then we reset the counter, send an ack to the host ;print the line out and advance the paper, then we sit until ;the head is full again :) ;first check if the head is full MOV W, #$C0 ;try 192 ;216 max bytes per line 1728 bits MOV W, $0E-w ;check max against our byte count SZ ;the same? result of zero? JMP mloop ;no not yet keep waiting CLR $0E ;Ok we've spotted the head full ;need to strobe head drivers SETB $12.7 ;strb1 CLRB $0B.7 ;turn off interupts CALL outsr ;Fire! CALL lildly ;let it burn! SETB $0B.7 ;re-enable interupts CLRB $12.7 ;ok thats done strobe 0 strobe 1 strobe 2 strobe 3 strobe 4 strobe 5 strobe 6 strobe 7 CLRB $0B.7 ;turn off interupts CALL outsr ;yay! all strobes Fired! CLRB RA.0 ;ok we aren't busy any more SETB $0B.7 ;re-enable interupts CALL papadv ;move paper on to next line JMP mloop ;lets go back and see if another ;line is ready yet phlook: ;this routine looks up the value for a particular phase ;important that this lookup resides within a 256 byte block ;as PCL is directly modified. if called with value grater ;than 8 ,will cause who knows what kind of crash! ADD 02, W ;ok now its going to jump :) NOP ;err dont expect zero ?!?! RETW #p8 ;return with phase 8 RETW #p7 ;coz we are counting down RETW #p6 ;remember... see next routine! RETW #p5 RETW #p4 RETW #p3 RETW #p2 RETW #p1 SLEEP ;coz its all gone wrong if it ;gets here or past! ;check the listing to be sure ;it fits between page boundries! papadv: ;this routine is to activate a paper advance one step ;it will use register #15 to keep track of which ;point in the phase cycle it is MOV W, #0f0 ;prep mask CLRB $0b.7 ;diable interupts AND $12, W ;nock off bottom bits MOV W, $15 ;grab our phase number into W CALL phlook OR $12, W ;new pattern now set SETB $0b.7 ;ints re-enabled DEC $15 ;get next phase number SNZ ;did we hit zero? JMP recount ;yep need to reload the counter CLRB $0b.7 ;turn off interupts coz of (outsr) CALL outsr ;jump to out put new phase SETB $0b.7 ;turn on interupts again RET ;and go back recount: MOV W, #08 ;we hit zero reset it back to 8 MOV $15, W ;use it next time round CLRB $0b.7 ;clear interupt enable CALL outsr ;I know its just below us SETB $0b.7 ;but tis only way to keep RET ;the interupts rightly enabled outsr: ;this routine takes bytes at 0x12 and 0x13 ;and clocks them out onto the shift registers ;shift registers accessed on port b bits 5,6 & 7 ;bit 6 as clock - clocks data on POSITIVE edge ;bit 7 as data - non inverted ;bit 5 as strobe - latches data on NEGATIVE edge ; we are sending lsb first ie bit# 1 on shift register ; output pin #8 ; sending byte at address 0x12 first then 0x13 ; this puts 0x12 on the last shift register in line ;uses reg # 14 to keep count of bits ;since this code is NON-RE-ENTERENT, do NOT call it ;while interupts are enabled, coz the int handler ;calls this routine to access the thermal head. MOV W, #08 ;for 8 bits MOV $14, W ;better keep count of it shiftbits: RR $12 ;rotate it thru carry SETB 6.7 ;set data high SC ;check the carry flag CLRB 6.7 ;clear data if required SETB 6.6 ;clock that bit in CLRB 6.6 ;drop clock again DECSZ $14 ;have we finished loop yet ? JMP shiftbits ;guess not RR $12 ;preserve the data, shift the carry ;now we have finished one byte lets do the other MOV W, #08 ;for 8 bits MOV $14, W ;better keep count of it shiftbitsagain: RR $13 ;rotate it thru carry SETB 6.7 ;set data high SC ;check the carry flag CLRB 6.7 ;clear data if required SETB 6.6 ;clock that bit in CLRB 6.6 ;drop clock again DECSZ $14 ;have we finished loop yet ? JMP shiftbitsagain ;guess not RR $13 ;preserve the data, shift the carry ;now we have really finished clocking bits SETB 6.5 ;bring up the strobe line CLRB 6.5 ;and LATCH it RET ;back to where ever. lildly MOV W, #lilloop MOV $11, W JMP reload bigdly MOV W, #bigloop MOV $11, W reload MOV W, #innerloop MOV $10, W inloop NOP DECSZ $10 JMP inloop DECSZ $11 JMP reload RET ORG $2000 DATA 00 DATA 00 DATA 00 DATA 00 ORG $2007 DATA 0x19 ;fuse settings ORG $2100 ;data 00 ;data 00 ;data 00 END
file: /Techref/scenix/lib/io/dev/thprn_sx.htm, 10KB, , updated: 2004/12/29 12:33, local time: 2024/11/22 17:53,
18.119.133.206:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://sxlist.com/Techref/scenix/lib/io/dev/thprn_sx.htm"> SX Thermal Printer Controller </A> |
Did you find what you needed? |
Welcome to sxlist.com!sales, advertizing, & kind contributors just like you! Please don't rip/copy (here's why Copies of the site on CD are available at minimal cost. |
Welcome to sxlist.com! |
.