email@micahcarrick.com wrote: > Crystal Oscillator = 8.000 MHz > Tosc = 125nS Yes, but the timers are incremented every Tcy (if so set up), not Tosc. Tcy is 4x Tosc = 500nS. > Prescaler = 1:16 > PR2 = 199 (0xC7) 500nS x 16 x 200 = 1.6mS > Therefore, my period is 1.6mS (625 Hz). OK, I guess you figured out about the Tcy part but didn't show it. > __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _XT_OSC & > _WRT_OFF & > _LVP_OFF & _CPD_OFF You might get away with XT oscillator mode at 8MHz, but you should probably be using HS. For the 16F877 XT was only recommended up to 4MHz. Maybe that has changed for the 16F877A, but you might want to check it. > ;***** VARIABLE DEFINITIONS > w_temp EQU 0x71 ;variable used for context saving Learn the right habits now. Don't use absolute mode and don't define hard variable addresses in the code. > status_temp EQU 0x72 ;variable used for context saving > pclath_temp EQU 0x73 ;variable used for context saving If you do things just the right way in the interrupt routine, you don't need the STATUS and PCLATH save areas to be in the global RAM. After a while you will find that these 16 bytes are precious and anything that doesn't really need to be global usually shouldn't be. See my interrupt routine template QQQ_INTR.ASPIC at http://www.embedinc.com/pic. > ORG 0x000 ;processor reset vector > nop ;nop required for icd > goto main ;go to beginning of program This will only work if MAIN is in the first page, and then only on reset where PCLATH can be counted on to contain 0. You really should set PCLATH to the high address byte of MAIN before the GOTO. > ORG 0x004 ;interrupt vector location > > movwf w_temp ;save off current W register contents > movf STATUS, w ;move status register into W register > movwf status_temp ;save off contents of STATUS register > movf PCLATH, w ;move pclath register into w register > movwf pclath_temp ;save off contents of PCLATH register You probably want to add CLRF STATUS and CLRF PCLATH here to select known banks and page. Again see my interrupt routine template. > ; isr code can go here or be located as a call subroutine elsewhere Don't forget to set PCLATH before any CALL. > main > clrwdt ;clear watch dog timer and prescaler Why? WDT is disabled. > movlw 0xC7 ;1. Set the PWM period > movwf PR2 Huh? And where did C7h come from? First, if it is a magic number it should be clearly documented. Second, it shouldn't be burried down in the code. If it's a tweak constant it should have a symbol up top with clear documentation on what it does. Third, if it's a derived constant as this is, derive it from the original factors. In this case it should be derived from the oscillator frequency and your desired PWM frequency. Especially since this is dependent on oscillator frequency, you should let the assembler do the math. Imagine what a pain it will be to update your code to a different oscillator frequency as it is now. When done right, you only change one number and rebuild. For an example of this, see my TIMER2_USEC macro in STD.INS.ASPIC. > bcf STATUS, RP0 ;select bank 0 No, this only guarantees banks 0 or 2. Imagine inserting some instructions above that leave RP1 set. Now the code below it will break. This is a dangerous way to set banks. There are better ways of manging banks, but that's for another discussion. I'm going to quit here since I see a lot of the same things I mentioned above happening below. ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist