Here is a pic of the unit I built:
[I'm not sure of the] partnumbers for the print head, but most are interchangeable in that they are esentially large shiftregisters with multiple output strobes (if all several 1000 odd outputs drove at once you would need a massive psu)
From: email@example.com Sent: Tuesday, September 21, 1999 5:00 PM To: firstname.lastname@example.org Subject: Re: send file thprn.asm ;be carefull when assembling ;there is a lookup table that MUST NOT cross a ;256 byte boundry ---- CHECK IT LIST P=16C84, F=INHX8M ;thermal printer controler innerloop = 0ff lilloop = 01 bigloop =0ff strobe macro bt bsf 0x13,bt ;bit for strobe bcf 0b,7 ;dont want interupts call outsr ;clock it out call lildly ;let it burn in bsf 0b,7 ;re-enable interupts bcf 0x13,bt ;so next outsr clears it endm ORG 0x0000 GOTO main ORG 0x0004 ;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 movwf 0c ;save 'W' in reg file 0c swapf 3,w ;grab the flags movwf 0d ;in reg 'd' ;should now be safe to continue! bsf 5,0 ;say we are busy ;read both ports to get byte of data rrf 5,w ;read port a shifting data down one andlw 0f ;only keep bottom bits movwf 0x16 ;keep incomming data here rrf 6,w ;read port b shifting down one andlw 0f ;wipe out extraneous bits movwf 0x17 ;waste another register swapf 0x17,w ;get 'b' data lower into upper W iorwf 0x16,f ;or top bits into data ;bit pattern from host now in 0x16 incf 0e,f ;increment our count of bytes ;clock data into thermal head movlw 08 ;for 8 bits movwf 0x17 ;better keep count of it clkhd: rlf 0x16,f ;rotate it thru carry bsf 0x12,4 ;set data high btfss 3,0 ;check the carry flag bcf 0x12,4 ;clear data if required call outsr bsf 0x12,5 ;clock that bit in call outsr bcf 0x12,5 ;drop clock again call outsr decfsz 0x17,f ;have we finished loop yet ? goto 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 movlw 0xc0 ;try 192 ;216 max bytes per line 1728 bits subwf 0e,w ;check max against our byte count btfss 3,2 ;the same? result of zero? goto 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. bsf 0x12,6 ;latch bit for thermal head call outsr ;send- no one else better be using it bcf 0x12,6 ;put back call outsr ;send that to goto exint ;leave int handler continue: ;tell host we are no longer busy, get next byte bcf 5,0 ;bring BSY low ;and fall thru to exit :) exint: ;now restore to before interupt swapf 0d,w ;put flags back in order in W movwf 3 ;stickem bick in flags swapf 0c,f ;flip saved W swapf 0c,w ;flip it back into W bcf 0b,1 ;clear INTF flag so we can get more RETFIE main ;thermal printer control program 192 dpi 9 inch 1728 pixels ;need to set up direction bits for ports ;and set initial pin levels movlw 0 ;pullups and interrupt on neg edge option ;set options movlw 0ff movf 5,f ;set all pins high on port a movlw 0fe ;RA0 as output tris 5 ;porta as input except RA0 movlw 01f ;make bits 6,7 &5 low movf 6,f movlw 01f ;port b 5,6,7 as output tris 6 ;make it so ! movlw 08 ;specify which phase to start on movwf 0x15 ;store it somewhere safe clrf 0e ;zero byte count for head movlw 00 ;phases off clk,lat,data, strb off movwf 0x12 ;data for shift reg 1 movlw 00 ;all strobes off (low) movwf 0x13 ;data for shift reg 2 call outsr ;set all pins high except for stepper movlw 0x90 ;enable RB0 and GIE interupt bits movwf 0b ;interupts now turned on! bcf 5,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 movlw 0xc0 ;try 192 ;216 max bytes per line 1728 bits subwf 0e,w ;check max against our byte count btfss 3,2 ;the same? result of zero? goto mloop ;no not yet keep waiting clrf 0e ;Ok we've spotted the head full ;need to strobe head drivers bsf 0x12,7 ;strb1 bcf 0xb,7 ;turn off interupts call outsr ;Fire! call lildly ;let it burn! bsf 0b,7 ;re-enable interupts bcf 0x12,7 ;ok thats done strobe 0 strobe 1 strobe 2 strobe 3 strobe 4 strobe 5 strobe 6 strobe 7 bcf 0b,7 ;turn off interupts call outsr ;yay! all strobes Fired! bcf 5,0 ;ok we aren't busy any more bsf 0b,7 ;re-enable interupts call papadv ;move paper on to next line goto 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! addwf 02,f ;ok now its going to jump :) nop ;err dont expect zero ?!?! retlw p8 ;return with phase 8 retlw p7 ;coz we are counting down retlw p6 ;remember... see next routine! retlw p5 retlw p4 retlw p3 retlw p2 retlw 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 movlw 0f0 ;prep mask bcf 0b,7 ;diable interupts andwf 0x12,f ;nock off bottom bits movf 0x15,w ;grab our phase number into W call phlook iorwf 0x12,f ;new pattern now set bsf 0b,7 ;ints re-enabled decf 0x15,f ;get next phase number btfsc 3,2 ;did we hit zero? goto recount ;yep need to reload the counter bcf 0b,7 ;turn off interupts coz of (outsr) call outsr ;jump to out put new phase bsf 0b,7 ;turn on interupts again return ;and go back recount: movlw 08 ;we hit zero reset it back to 8 movwf 0x15 ;use it next time round bcf 0b,7 ;clear interupt enable call outsr ;I know its just below us bsf 0b,7 ;but tis only way to keep return ;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. movlw 08 ;for 8 bits movwf 0x14 ;better keep count of it shiftbits: rrf 0x12,f ;rotate it thru carry bsf 6,7 ;set data high btfss 3,0 ;check the carry flag bcf 6,7 ;clear data if required bsf 6,6 ;clock that bit in bcf 6,6 ;drop clock again decfsz 0x14,f ;have we finished loop yet ? goto shiftbits ;guess not rrf 0x12,f ;preserve the data, shift the carry ;now we have finished one byte lets do the other movlw 08 ;for 8 bits movwf 0x14 ;better keep count of it shiftbitsagain: rrf 0x13,f ;rotate it thru carry bsf 6,7 ;set data high btfss 3,0 ;check the carry flag bcf 6,7 ;clear data if required bsf 6,6 ;clock that bit in bcf 6,6 ;drop clock again decfsz 0x14,f ;have we finished loop yet ? goto shiftbitsagain ;guess not rrf 0x13,f ;preserve the data, shift the carry ;now we have really finished clocking bits bsf 6,5 ;bring up the strobe line bcf 6,5 ;and LATCH it return ;back to where ever. lildly movlw lilloop movwf 0x11 goto reload bigdly MOVLW bigloop MOVWF 0x11 reload MOVLW innerloop MOVWF 0x10 inloop NOP DECFSZ 0x10 , f GOTO inloop DECFSZ 0x11 , f GOTO reload RETURN ORG 0X2000 DATA 00 DATA 00 DATA 00 DATA 00 ORG 0x2007 DATA 0x19 ;fuse settings org 0x2100 ;data 00 ;data 00 ;data 00 END
|file: /Techref/microchip/thprn_asm.htm, 15KB, , updated: 2005/10/12 13:04, local time: 2022/5/22 21:43,
|©2022 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://www.massmind.org/techref/microchip/thprn_asm.htm"> PIC Terman Printer Controller</A>
|Did you find what you needed?|
Welcome to massmind.org!
Welcome to www.massmind.org!