I got my PC boards from OSH Park. The top boards are just some SOT23 breakouts to make breadboarding easier. Soldering wire legs onto SOT23s is a little difficult, and they don't hold up well to plugging and unplugging.

The bottom boards are my PIC10F322 general purpose board. OSH Park shorted me one board, so I only have five. Looks like I need to work on my text label placement and sizing. I don't know if it's my fault or if Eagle 7.3.0 is buggy, but a lot of my labels got cut off partway. Gotta work on that next time...

I quickly soldered one together. That went well - no problems at all. Next time I go surface mount for the diode too. The old toothbrush I used to scrub the flux off was pretty dirty. It left the board looking a bit grubby. I'll have to shine it up later (never).

You can see where I added "a bit more solder" on one end of the diode. You know, "The bigger da blob, da better da job!" Wouldn't hurt to clean that up too.

Here's the back side. Not much to see here except one little decoupling cap.

A closer view. That's a 402 cap on 603 pads. I wondered if that would work. It does, but 402s are really kind of too small for my old eyes to deal with.

Plugged in and running the same program as on the prototype. All works fine so far. Wiring the thing is a whole lot simpler now.

Below is the code that's running in the pics.

I experimented a bit and found that:

  1. Unlike the prototype, I can program the 10F322 board (with what's connected in the pics above) without using my program/run switch. That almost certainly won't be true with some other connected circuits.
  2. The code below can be run at up to 16MHz. I thought for sure the LCD would choke if I didn't adjust the delays but it keeps up perfectly fine.
processor 10f322
include "p10f322.inc"
__config _CP_OFF & _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _LVP_OFF

  cblock  0x40
  i,nyb,rs,letter,count,count2,flag,temp,saves,savew,binh,binl,ascii_1,ascii_2,ascii_3,ascii_4,d1,d2,d3
  endc

CLK     equ     0
DAT     equ     1

org     0x00
goto    start

;-------------------------
;interrupt service routine
org     0x04
movwf   savew           ;save context (w & status)
swapf   STATUS,w
movwf   saves
  btfsc   IOCAF,3         ;is RA3 IOC flag set?
  goto    buttisr         ;yes, go to button code
blink:                      ;no, must be Timer0
  movlw   0x04            ;toggle LED pin RA2
 xorwf   LATA,f
  bcf     INTCON,TMR0IF   ;clear interrupt flag
  goto    done
buttisr:
  incf    flag,f          ;yes, flag = 1
  bcf     IOCAF,3         ;clear the RA3 IOC flag
done:
swapf   saves,w         ;restore context
movwf   STATUS
swapf   savew,f
  swapf   savew,w
retfie

;-------------
; main program
start:
  movlw   b'01010000'     ;4MHz clock
  movwf   OSCCON
  clrf    ANSELA          ;all pins digital
  clrf    TRISA           ;led pins outputs
  movlw   b'10000111'     ;setup Timer0,1:256
  movwf   OPTION_REG
  bsf     INTCON,TMR0IE   ;enable Timer0 interrupt
  clrf    flag            ;zero my IOC flag
  bsf     IOCAN,3         ;enable IOC on RA3
  bsf     INTCON,IOCIE    ;enable interrupt on change
  bsf     INTCON,GIE      ;enable interrupts
  bcf     LATA,CLK
  bcf     LATA,DAT
  clrf    count
  clrf    count2
  call    lcd_init

  call    line1
bleh:
  movf    count,w     ;count = table pointer
  call    table1      ;get byte from table
  xorlw   0x00        ;returned zero?
  btfsc   STATUS,Z
  goto    next        ;yes, then done
  movwf   letter      ;no, output byte to LCD
  call    lcd_char
  incf    count,f     ;increment table pointer
  goto    bleh        ;and go again

next:
  clrf    count
  clrf    count2
blah:
  call    delay250ms
  btfsc   flag,0      ;has button been pushed?
  call    rset        ;yes, go handle it

  movf    count,w     ;set up and go convert
  movwf   binh        ;to ascii for display
  movf    count2,w
  movwf   binl
  call    bin2hex16

  call    line2       ;display the four hex digits
  movf    ascii_1,w
  movwf   letter
  call    lcd_char
  movf    ascii_2,w
  movwf   letter
  call    lcd_char
  movf    ascii_3,w
  movwf   letter
  call    lcd_char
  movf    ascii_4,w
  movwf   letter
  call    lcd_char

  incf    count2,f    ;increment low byte
  btfss   STATUS,Z    ;is zero set, meaning wrapped around?
  goto    blah        ;no, goto blah
  incf    count,f     ;yes, increment high byte
  goto    blah        ;and go again

;---------------------
; table
table1  addwf   PCL,f
  retlw 'P'
  retlw 'I'
  retlw 'C'
  retlw '1'
  retlw '0'
  retlw 'F'
  retlw '3'
  retlw '2'
      retlw   '2'
  retlw ' '
  retlw 'L'
  retlw 'C'
  retlw 'D'
  retlw 0x00
;---------------------
; subroutines
rset:
  clrf    flag
  clrf    count
  clrf    count2
  return
;---------------------
;16-bit binary passed in binh/binl
;Ascii hex values returned in ascii_1 thru ascii_4
bin2hex16:
  swapf   binh,w
  andlw   0x0f
  movwf   ascii_1
  movlw   0x0a
  subwf   ascii_1,w
  movlw   0x30
  btfsc   STATUS,C
  movlw   0x37
  addwf   ascii_1,f
;-----------
  movf    binh,w
  andlw   0x0f
  movwf   ascii_2
  movlw   0x0a
  subwf   ascii_2,w
  movlw   0x30
  btfsc   STATUS,C
  movlw   0x37
  addwf   ascii_2,f
;-----------
  swapf   binl,w
  andlw   0x0f
  movwf   ascii_3
  movlw   0x0a
  subwf   ascii_3,w
  movlw   0x30
  btfsc   STATUS,C
  movlw   0x37
  addwf   ascii_3,f
;-----------
  movf    binl,w
  andlw   0x0f
  movwf   ascii_4
  movlw   0x0a
  subwf   ascii_4,w
  movlw   0x30
  btfsc   STATUS,C
  movlw   0x37
  addwf   ascii_4,f

  return
;---------------------
lcd_cmd:
  movf    letter,w        ;do high nybble first
  movwf   temp
  swapf   temp,w
  movwf   nyb
  clrf    rs              ;set rs bit low
  call    lcd_nybble
  movf    letter,w        ;now do low nybble
  movwf   nyb
  call    lcd_nybble
  return
;---------------------
lcd_char:
  movf    letter,w        ;do high nybble first
  movwf   temp
  swapf   temp,w
  movwf   nyb
  movlw   0x01            ;set rs bit high
  movwf   rs
  call    lcd_nybble
  movf    letter,w        ;now do low nybble
  movwf   nyb
  call    lcd_nybble
  return
;---------------------
lcd_nybble:
  bcf     LATA,DAT        ;clear the 174
  movlw   6               ;with 6 zero bits
  movwf   i
lcdloop1:
  call    pulse           ;clock out a bit
  decfsz  i,f             ;finished 6 bits?
  goto    lcdloop1        ;no, go again

  bsf     LATA,DAT        ;output the AND value
  call    pulse

  btfss   rs,0            ;is RS bit 0 set?
  goto    yup             ;no, go to yup
  bsf     LATA,DAT        ;yes, set data pin high
  goto    yup1
yup:
  bcf     LATA,DAT        ;no, set data pin low
yup1:
  call    pulse

  movlw   4               ;output the nybble
  movwf   i               ;set loop counter
lcdloop2:
  btfsc   nyb,3           ;check if high bit is 1
  goto    one             ;yes, goto one
  bcf     LATA,DAT        ;no, set DAT pin low
  goto    sendbit         ;go send it
one:
  bsf     LATA,DAT        ;set DAT pin high
sendbit:
  call    pulse           ;send the bit
  rlf     nyb,f           ;move next bit into line
  decfsz  i,f             ;finished 4 bits?
  goto    lcdloop2        ;no, go again
  call    e_togg          ;latch data
  return
;---------------------
line1:
  movlw   0x80
  movwf   letter
  call    lcd_cmd
  return
;---------------------
line2:
  movlw   0xc0
  movwf   letter
  call    lcd_cmd
  return
;---------------------
pulse:
  bsf     LATA,CLK        ;pulse clock
  nop
  bcf     LATA,CLK
  return
;---------------------
lcd_init:
  call    delay250ms
  movlw   0x03
  movwf   nyb
  clrf    rs
  call    lcd_nybble
  call    delay5ms
  call    e_togg
  call    delay160us
  call    e_togg
  call    delay160us
  movlw   2
  movwf   nyb
  call    lcd_nybble
  call    delay160us
  movlw   0x28            ;set 4-bit mode and 2 lines
  movwf   letter
  call    lcd_cmd
  call    delay160us
  movlw   0x10            ;cursor move & shift left
  movwf   letter
  call    lcd_cmd
  call    delay160us
  movlw   0x06            ;entry mode = increment
  movwf   letter
  call    lcd_cmd
  call    delay160us
  movlw   0x0c            ;display on - cursor blink off
  movwf   letter
  call    lcd_cmd
  call    delay160us
  movlw   0x01            ;clear display
  movwf   letter
  call    lcd_cmd
  call    delay250ms      ;30ms is enough
  return
;---------------------
e_togg:                     ;pulse data pin to latch data
  bsf     LATA,DAT
  nop
  bcf     LATA,DAT
  return
;---------------------
delay160us:
movlw   0x33
movwf   d1
Delay_10:
decfsz  d1,f
goto    Delay_10
goto    $+1
return
;---------------------
delay5ms:
movlw   0xE6
movwf   d1
movlw   0x04
movwf   d2
Delay_02:
decfsz  d1,f
goto    $+2
decfsz  d2,f
goto    Delay_02
goto    $+1
nop
return
;---------------------
delay250ms:
movlw   0x4E
movwf   d1
movlw   0xC4
movwf   d2
Delay_01:
decfsz  d1,f
goto    $+2
decfsz  d2,f
goto    Delay_01
goto    $+1
nop
return
;---------------------
delay500ms:
movlw   0x03
movwf   d1
movlw   0x18
movwf   d2
movlw   0x02
movwf   d3
Delay_20:
decfsz  d1, f
goto    $+2
decfsz  d2, f
goto    $+2
decfsz  d3, f
goto    Delay_20
goto    $+1
return
;---------------------
delay1s:
movlw   0x07
movwf   d1
movlw   0x2F
movwf   d2
movlw   0x03
movwf   d3
Delay_4:
decfsz  d1, f
goto    $+2
decfsz  d2, f
goto    $+2
decfsz  d3, f
goto    Delay_4
goto    $+1
goto    $+1
goto    $+1
return
;---------------------

end

Next Post Previous Post