This was mostly a learning opportunity to teach myself how to use a low-level programing language in programming a microcontoller. I have always been fascinated with early programming languages, but assembly code had always seemed to be like a complete alien language compared to all other coding languages. Assembly is as close to the processor as one can get writing code without literally writing the ones and zeros that computers understand. Although most of us will never use it, getting just a lesson or two in it help understand how programing languages interact with the physical component of the computer.

This project was fairly simple in its nature but writing it in assembly and programming the microchip made it far more interesting. Using a Microchip PIC18F45K20 microcontroller set on breadboard connected to a micro tact switch and 4 LEDs, assembly code was written for a 4-bit binary counter. Each LED represents a 0 or 1 by being in the off or on state, e.g. (off,off,off,off =0000= 0) and (on,on,on,on)=1111=15). To increment the binary counter the tactile switch was used as input, each push sent a signal to the microcontroller counter which would output the new binary value to the user through the LEDs. Once the 4-bit counter reached 15 or 1111 the counter would reset back to 0 to repeat the process.

PIC18F45K20 Pinout
  • Pins 11,12 and 32,31 used for supply and ground of the rail.
  • Pins 1,40 and 39 are used for communication (programming the chip using MPLAB PICkit4)
  • Pin 33 was used for input, push button switch (all b ports were set to input)
  • Pin 19,20,21,22 were used for output, 4 LEDs at each pin in series with a 220Ω resistor going to ground.

Below is the assembly code for this project. Note that the code can be configured for 2 buttons one to increment and decrement the binary counter, or it can be changed to remove the push button to make the 4bit binary counter cycle on its own without user input, but a longer delay (1 second) would be needed to allow the LED’s to noticeably change.

List	p=18f452, f=inhx32		;Initalization
	#include<p18f452.inc>		;Header file for SFRs and other parameters
		
;Declare variables
count		EQU	0x30		;count reg
timer		EQU 	0x31		;timer reg
button		EQU	0x32		;button reg

;Start Binary Counter Program
		org	0x20		;reset vector
		movlw	b'11111111'	;set port b as input button
		movwf	TRISB		;set port b as input 
		movlw 	button		;move wreg to button
		movff	PORTB,button	;movw wreg to portB
		movwf	TRISD	        ;set portd as output
rset		clrf	count		;reset counter after '1111'
Loop		btfsc	button,0,0	;bit test skip if clear
		goto	loop1ms		;delay call can be adjusted
		movlw	count		;move count into wreg
		movff	count,PORTD	;movw wreg to PORTD
		call	loop1ms		;delay call
		incf	count,f		;increment the count by 1
		movlw	16h		;wreg 16 for full count of 4bit 0-15
		xorwf	count,w		;check w 16 xor count (logical XOR)
		btfss	STATUS,Z	;check if the zero flag is set
		goto	Loop		;if count is not zero go back to increment
		goto	rset		;if zero flag reset go to reset
		
;Short Delay Subroutine (4Mhz clock) change based on need, delay for offsetting debounce
		
delay1ms	movlw	d'250'		;initial value  
		nop		        ;no operation
loop1ms		addlw	d'255'		;dec W
		btfss	STATUS,Z	;check if zero flag is set
		goto	loop1ms		;loop back, increasing the clock cycle = time
		return			;jump out of the loop when done.
		END			;stop assembly