PIC16F877A - More Microcontroller Features

PIC16F877A

We have managed to blink an LED and use interrupts and timers with the PIC16F84A. Sadly, that’s almost all we can do with that microcontroller as it lacks features that most microcontrollers or Arduino have. From here on, we will now be using the PIC16F877A.

The PIC16F877A is a 40-pin (DIP) microcontroller which Microchip describes as powerful based on having a 200 nanosecond instruction speed. It’s old and Microchip itself is not recommending it for new designs but its features and price make it still a popular microcontroller.

 

PIC16F877A Specs

Here are a few of its specifications:

  • Bus width - 8 bits
  • Pin Count - 40 (PDIP, SOIC) / 44 (QFN, PLCC, TQFP)
  • Program Memory - 14.3 kilobytes
  • CPU Speed - 5 million instructions per second
  • RAM Size - 368 bytes
  • EEPROM Size - 256 bytes

Obviously, the PIC16F877A trumps the PIC16F84A based on the numbers above. But what separates this microcontroller are these features:

  • 10-bit, up to 8-channel Analog-to-Digital
    Converter (A/D)
  • Synchronous Serial Port (SSP) with SPI™
    (Master mode) and I2C™ (Master/Slave)
  • Universal Synchronous Asynchronous Receiver
    Transmitter (USART/SCI) with 9-bit address
    detection

We will discuss each of these features as we continue with this tutorial.

LED Blink Code in Assembly

For now, we will create a simple assembly language program using the PIC16F877A.
The code is very similar to the one using PIC16F84A:

#INCLUDE <P16F877A.INC>
    
 __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
   
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

    CBLOCK 0x0C
	COUNT1
	COUNT2
    ENDC
    
MAIN_PROG CODE                      ; let linker place main program

START
    BSF STATUS, RP0
    CLRF TRISB
    BSF TRISA,0
    BCF STATUS, RP0
    
MAIN
    BSF PORTA,0
    CALL DELAY
    BCF PORTA,0
    CALL DELAY
    GOTO MAIN
    
DELAY
LOOP1   DECFSZ COUNT1,1
	GOTO LOOP1
	DECFSZ COUNT2,1
	GOTO LOOP1
	RETURN
	
    END

The code above simply toggles the state of pin RB0. So when an LED is attached to this pin, it will blink. You can simulate this code in Proteus using the schematic diagram below:

PIC16F877A Blink a LED circuit

Of course, the advantage of using this microcontroller is you can attach a lot more LEDs!

Switch an LED in Assembly

For input using a switch, you can freely use any pin except those that have AN labels. These analog pins including all PORTA and PORTE pins are meant for analog-to-digital conversion and need a bit of additional code to make them digital.

To turn these analog pins to digital, we must write 0x07 or 0x06 to the ADCON1 register. Details about this are found in my analog-to-digital conversion tutorial.

Here’s a code that uses a switch to RA0 to turn on/off a LED:

#INCLUDE <P16F877A.INC>
    
 __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF
   
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

    CBLOCK 0x0C
	COUNT1
	COUNT2
    ENDC
    
MAIN_PROG CODE                      ; let linker place main program

START
    BSF STATUS, RP0
    CLRF TRISB
    MOVLW 0x07
    MOVWF ADCON1
    MOVLW 0x01
    MOVWF TRISA
    BCF STATUS, RP0
    
MAIN
    BTFSC PORTA,0
    GOTO OFF
    GOTO ON
    GOTO MAIN
    
ON  BSF PORTB,0
    GOTO MAIN  
    
OFF BCF PORTB,0
    GOTO MAIN
    
DELAY
LOOP1   DECFSZ COUNT1,1
	GOTO LOOP1
	DECFSZ COUNT2,1
	GOTO LOOP1
	RETURN
	
    END

Here’s the schematic diagram for the code above:

PIC16F877A LED Switch circuit

Those are the basic assembly language programs we can do with the PIC16F877A. Up next, we will look at the features that separate this microcontroller from the PIC16F84A, starting with serial communication.