We have managed to blink a LED, 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 an Arduino has. 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.[the_ad id="3059"]
Here’s 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
- Synchronous Serial Port (SSP) with SPI™
(Master mode) and I2C™ (Master/Slave)
- Universal Synchronous Asynchronous Receiver
Transmitter (USART/SCI) with 9-bit address
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_ad id="3059"]
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:
Of course, the advantage of using this microcontroller is you can attach a lot more LEDs!
Switch a LED in Assembly
For input using a switch, you can freely use any pin except those that have AN labels. These analog pins that includes all PORTA and PORTE pins are meant for analog to digital conversion and needs 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 is found on 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:
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.