Get Your Digitial On, and Off

Digital vs. Analog in Electronics: Digital electronic information is discrete numbers or bits. An analog signal is a continuous signal. An ADC (Analog to Digital Converter) converts a continuous signal, for instance a microphone signal, to discrete numbers that a computer can understand. That's the best I can explain on the spot. Dan and Tom say (I'm paraphrasing) that if you're asking yes or no, it's digital, if you're asking "how much" it's analog.

So, we're working with digital signals, which means we're going to tell whether something is on or off. Switches are good for this. It'll give us a taste of how to deal with inputs to the PIC, since we've already done digital output

Wiring

Wiring for this section is easy. We'll take a toggle switch, of which there are many varieties, attach the power to your board's +5V, and the other end to a port pin on the PIC. The electricity will flow from +5V to one pole of your switch, which will either let it through or stop it. Then, if the switch is open, it will flow to your PIC. The PIC basically is in a loop that says "Is there current on that pin? Yes? Do this. No? Do this." It's that easy.

Coding

I never actually did this in asm, I did it in JAL, so the code below is untested. It's simple code though, so if this doesn't work I'm sure you'll figure it out (if it is wrong let me know and I'll actually get it right. God I'm lazy. It probably has more to do with lots of work at the end of term right now. Anyway, moving on).

Start as usual with your beautiful header. I won't repeat it right here, but I'll include it in the final for completeness. The program is going to be a simple variation on your LED blinker. That is, each loop it will check the switch and turn the LED on or off correspondingly. You could just attach the LED to the switch, but this way makes it easy to add features like, you need to flip the switch three times before the LED goes on. I'll leave such innovations to you.

The first thing after your org statement should be setting up the ports for i/o. Recall from the LED Chaser that clearing a bit in a TRIS register sets the corresponding pin to output. In the LED Chaser we set the whole port to output, but here I'm assuming your LED is on RD1, and your switch is on RD2, so you can't set the whole D TRIS, you need to set each bit so that RD1 is output and RD2 is input. This could be done with a bit set and bit clear instruction like this:

    org 0x0000

    bcf TRISD, RD1 ; set pin D1 to output
    bsf TRISD, RD2 ; set pin D2 to output

A more elegant (I think) way to do this would be soemthing like this:

    org 0x0000

    movlw B'00100000' ; set only pin 2 to input (numbering starts at 0)
    movwf TRISD

I think this is better for two reasons. First, it lets you see the port setting right there, I think it's more readable than a bunch of bsf and bcf statements. Second, you can set all the pins with two instructions. Since we're only setting two pins there's no savings, but if you're setting more pins it can save a lot of time.

Next, open your main loop with the label "Main". This loop will simply have a conditional that checks the value of PORTD, RD2 (where the switch is) to see if it's 1, if it is, it turns on the light, otherwise it turns it off.

Main
    btfss PORTD, RD2 ; check RD2 bit is set, skip next line if yes.
    bcf   PORTD, RD1 ; turn off the LED
    bsf	  PORTD, RD1 ; turn on the LED
    goto Main        ; loop

It's that easy. The hardest part for me was getting the wiring on the switch. I had just taped it for testing, and I kept thinking my program wasn't working, but then realized that sometimes the contacts were touching, sometimes not. It may be best to solder the wires to the switch just to eliminate the possibilities. Here's the final code:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; digital_io.asm: Basic digital in/out for a PIC 18F452
;; 
;; By Ian Smith-Heisters ian{remove this}\at 0x09{remove this}.com
;;   12-07-2004: Started
;;   12-07-2004: version 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    title "Get your digital on"
    List p=18f452,f=inhx32
    #include <p18f452.inc>
    
    __CONFIG    _CONFIG1H, _OSCS_ON_1H & _XT_OSC_1H ; External Clock on OSC1 & OSC2
    __CONFIG    _CONFIG2L, _BOR_ON_2L & _BORV_20_2L & _PWRT_OFF_2L ; Brown out reset on at 2.0V, no power-up timer
    __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H ; watchdog off, postscaler count to 128
    __CONFIG    _CONFIG3H, _CCP2MX_ON_3H ; CCP2 pin Mux enabled. What is this?
    __CONFIG    _CONFIG4L, _STVR_ON_4L & _LVP_ON_4L & _DEBUG_OFF_4L ; Stack under/overflow reset on, LVP on, debug off
    __CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L ; all protection off
    __CONFIG    _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
    __CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
    __CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
    __CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
    __CONFIG    _CONFIG7H, _EBTRB_OFF_7H

    org 0x0000

    movlw B'00100000' ; set only pin 2 to input (numbering starts at 0)
    movwf TRISD

Main
    btfss PORTD, RD2 ; check RD2 bit is set, skip next line if yes.
    bcf   PORTD, RD1 ; turn off the LED
    bsf	  PORTD, RD1 ; turn on the LED
    goto Main        ; loop

    end


off Switched off

on Switched on