Migration from an F877 to an F887 is pretty simple. The configuration fuses and the init routine should be all you have to change.
Differences between the two PICs -
F877/F877A - Writing to the ADCON1 SFR changes the analog/digital I/O modes for the ADC and PORT pins
F887 - Has 2 dedicated SFR's for controlling the analog input/digital I/O modes for each ADC/PORT pin (ANSEL and ANSELH). These registers reside in register bank 3 on the PIC
Even though the F887 has an on chip oscillator, it is not stable enough for the MIDI bit rate. With the on chip oscillator, there is anywhere from a 1-3% error per bit, which exceeds the allowable tolerance spec in the MIDI specification (translates to a 10-30% error per byte). From experience, I would periodically get framing errors when sending/receiving MIDI data while using the internal oscillator. For best results, use a crystal oscillator. You will have 0% error with a crystal oscillator.
The minimum xtal speed to use is 4MHz. You can use a 1MHz but you will have to run the UART in high speed BRG mode (TXSTA,BRGH = 1) and you would load SPBRG with the value of 0x01 in this scenario. Here are some BRG values for 31.25Kbps -
If TXSTA,BRGH = 0, then use -
4MHz - SPBRG = 0x01
8MHz - SPBRG = 0x03
12MHz - SPBRG = 0x05
16MHz - SPBRG = 0x07
20MHz - SPBRG = 0x09
If TXSTA,BRGH = 1, then use -
1MHz - SPBRG = 0x01
4MHz - SPBRG = 0x07
8MHz - SPBRG = 0x0F
12MHz - SPBRG = 0x17
16MHz - SPBRG = 0x1F
20MHz - SPBRG = 0x27
Configuration Word - I use this for the F887 -
;*************************************************************************************************
;*************************************************************************************************
;** **
;** Header Information **
;** **
;*************************************************************************************************
;*************************************************************************************************
list p=16F887, r=dec, w=-302
include <P16F887.INC>
__config _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOREN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
;Debug Off (default)
;Low Voltage Programming Off
;Fail Safe Clock Monitor Off
;Internal External Switchover Mode off
;Brown Out Reset off
;Data Code Protect off (default)
;Program Code Protect off (default)
;RE3 is MCLRE (default)
;Power Up Timer on
;Watchdog Timer off
;Standard Xtal Oscillator
;If using xtal from 1-4MHz, replace FOSC_HS in the configuration word with FOSC_XT (standard crystal oscillator)
You don't have to play with _CONFIG2 unless you plan to use brown out reset or you want to write protect the program ROM space from being written to in code.
A basic init routine for a 16F887 running a 16MHz xtal, all ports in output mode and all ADC lines set up for digital I/O -
;*************************************************************************************************
;*************************************************************************************************
;** **
;** Initialization Routine **
;** **
;*************************************************************************************************
;*************************************************************************************************
org 0x000 ;reset vector
goto START
org 0x004 ;interrupt vector
; goto ISR ;uncomment this line if you plan to use interrupts
START clrf PORTA ;init port latches
clrf PORTB
clrf PORTC
clrf PORTD
clrf PORTE
banksel ANSEL ;select RAM bank 3
clrf ANSEL ;AN0 - AN7 digital I/O mode
clrf ANSELH ;AN8 - AN13 digital I/O mode
banksel TRISA ;select RAM bank 1
clrf TRISA ;PORTA all outputs
clrf TRISB ;PORTB all outputs
movlw b'11000000' ;RC0-RC5 outputs
movwf TRISC ;RC6 UART TX, RC7 UART RX
clrf TRISD ;PORTD all outputs
clrf TRISE ;PORTE all outputs
;UART init
movlw 0x07 ;bit rate = 31.25Kbps for MIDI
movwf SPBRG ;w/16MHz crystal
movlw b'00100000' ;asynchronous serial, enable UART tx
movwf TXSTA
banksel 0 ;select RAM bank 0
movlw b'10010000' ;enable serial port
movwf RCREG ;enable continuous rx
If you're coding in Hitech C and assuming you're using Hitech C v9.83 (the header file definitions seem to change from one Hitech C release to the next...not sure why), the same code would look like such (again using 16MHz xtal and all ports set to output) -
/*
**********************************************************************************
**********************************************************************************
** **
** Header Information **
** **
**********************************************************************************
**********************************************************************************
*/
/*
* Hitech C v9.83 - consult your Hitech C p16f887.h file for the correct config word
* mnemonics if using an older version of Hitech C
*/
#include <htc.h>
__CONFIG(LVP_OFF & FCMEN_OFF & IESO_OFF & BOREN_OFF & PWRTE_ON & WDTE_OFF & FOSC_HS);
/*
* Debug Off (default)
* Low Voltage Programming Off
* Fail Safe Clock Monitor Off
* Internal External Switchover Mode off
* Brown Out Reset off
* Data Code Protect off (default)
* Program Code Protect off (default)
* RE3 is MCLRE (default)
* Power Up Timer on
* Watchdog Timer off
* Standard Xtal Oscillator
* If using xtal from 1-4MHz, replace FOSC_HS in the configuration word with FOSC_XT (standard crystal oscillator)
*/
/*
**********************************************************************************
**********************************************************************************
** **
** Interrupt Handler **
** **
**********************************************************************************
**********************************************************************************
*/
void interrupt isr(void)
{
//place interrupt handler code here (if applicable)
}
/*
**********************************************************************************
**********************************************************************************
** **
** Main Code Block **
** **
**********************************************************************************
**********************************************************************************
*/
void main(void)
{
PORTA = 0x00; //init port latches prior to switching to output mode
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
PORTE = 0x00;
ANSEL = 0x00; //AN0 - AN7 digital I/O mode
ANSELH = 0x00; //AN8 - AN13 digital I/O mode
TRISA = 0x00; //RA0 - RA5 all outputs
TRISB = 0x00; //RB0 - RB7 all outputs
TRISC = 0b11000000; //RC0 - RC5 outputs, RC6 UART TX, RC7 UART RX
TRISD = 0x00; //RD0 - RD7 all outputs
TRISE = 0x00; //RE0 - RE2 all outputs
//UART initialization
SPBRG = 0x07; //31.25Kbps for MIDI w/16MHz xtal
TXSTA = 0b00100000; //enable asynchronous mode, enable transmit
RCSTA = 0b10010000; //enable serial port, enable continuous rx
//main code goes here
}
Other than that, the rest of your 877A code should remain the same. Hope this helps.