PIC16F628A  connected to 8 LEDs.

Microchip PIC16F628 Assembly Code Programs Tutorial

by Lewis Loflin

In this section we will explore how to use the Microchip PIC mostly the 16F628A and the 12F683. While the previous section on the PIC18F2550 was written in C, here I'll use only assembly language.

Related YouTube Video: Home Built PIC Dev. Board.

Why assembly? It's produces fast and efficient coding over C for basic functions related to electronics control. This enables one to really access the powerful features of the PIC. As a RISC processor it has only 35 instructions to learn. They operate at the register and bit levels.

These were developed using MPLAB v8.88.

In addition the PIC16F628A has an internal 4 mHz oscillator meaning no need for an external crystal.

The projects concentrate on using the PIC16F628 that has the following features:

  • 2048 bytes of flash RAM
  • 224 bytes of data SRAM
  • 16 programmable IO pins
  • Three timers two 8-bit and one 16-bit
  • Pulse width modulation unit
  • Operation to 20 mHz


And so much more. While 2048 bytes may not sound like much, none of the first seven demos used more than 75 bytes! That includes operating a bipolar stepper motor and reading an external analog to digital converter, which the 16F628 lacks. The 12F683 has ADC, but only six IO pins. (8 pins total.)

PICs utilize the Harvard architecture in which instructions and data operate on separate sources, which simplifies timing and microcircuit design. While they can be programmed in circuit, I used a separate programmer and a ZIP socket in my home built development board.

The example demos will use all three timers, pwm unit, interrupts, etc. The idea being to present working debugged code so the novice can learn more on their own. The following example counts in binary-coded decimal (BCD) on 8 LEDs connected to PORTB with the following example code:


main
	; count 0-99 in BCD displayed on 8 LEDS PORTB
	MOVFW CNT
	ANDLW 0x0F ; mask out 4 upper bits
	SUBLW 0x0A ; test lower nibble
	BTFSS STATUS, Z ; test for dec 10
	GOTO LOC1 
	MOVFW CNT
	ADDLW 0x06
	MOVWF CNT
	; test upper nibble
	MOVWF TEMP
	SWAPF TEMP ; swap nibbles
	MOVFW TEMP
	ANDLW 0x0F  ; mask off upper 4 bits
	SUBLW 0x0A ; test for 0x0A
	BTFSS STATUS, Z ; test for dec 10
	GOTO LOC1
	MOVFW CNT ; upper nibble = 0xA0 add 0x60
	ADDLW 0x60
	MOVWF CNT
LOC1
 	MOVFW  CNT  ; display result
	MOVWF  PORTB
	CALL TMR0_DEL ; any delay routine
	INCF CNT ; CNT = CNT + 1	

	goto main 

What the code does is check each half-byte (nibble) to see if it is 10 (0x0A) which we then add 0x06 to the lower nibble or 0x60 to the upper nibble and the count continues and is sent to PORTB LEDs.

Full code F628a_BCD.asm

Related Videos, Links