3
\$\begingroup\$

I am trying to get the PWM subsystem on a PIC16F887 working. I've gone over this several times and just cant seem to find my problem.
This is part of a larger program, but for simplicity I re-wrote just the PWM portion. I am using the datasheet as my guide for configuring the PWM subsystem, specifically page 131. I am not really worried about getting a specific frequency or duty cycle out. I am just trying to see some kind of waveform out of the PWM pins.
Code compiles fine, but I get no output from RC2.

Thanks for any help
Not sure why the tabbing of the code got a little mangled when pasted into this question.

Board: PIC16F887 c/w 44-pin demo board (Microchip).
Programmer: PICkit3
Compiler: gpasm

;*******************************************************
;Notes
;PWM is used on CCP1 which is P1A which is RC2
;********************************************************
    INCLUDE registers.asm
    __CONFIG 0X2EFF20E5

    ORG 0x00
    GOTO    MAIN

;******************************************************
;Main Program Loop
;******************************************************
    ORG 0X05
MAIN
    CALL    SETUP
    CALL    SETUP_PWM
wait
    BTFSS   PIR1,1  ;TEST TR2IF
    GOTO    wait
    BSF STATUS,5    ;Select Bank1
    CLRF    TRISC   ;START PWM
    BCF STATUS,5    ;Select Bank0
    BSF PORTD,0     ;ENTERING MAIN LOOP
main_loop
    GOTO    main_loop

;****************************************************************
;Setup Subroutine
;general setup
;****************************************************************
SETUP
    BSF STATUS,6    ;SELECT BANK 3
    BSF STATUS,5
    MOVLW   0X00
    MOVWF   ANSELH  ;CONFIGURE ALL PINS FOR DIGITAL IO
    MOVWF   ANSEL  
    BCF STATUS,6    ;SELECT BANK1
    BSF OSCCON,4    ;OSCILLATOR TO LOW SPEED
    BSF OSCCON,5
    BSF OSCCON,6
    MOVLW   0XFF    
    CLRF    INTCON  ;DISABLE INTERRUPTS
    CLRF    TRISD   ;PORTD AS OUTPUT  
    BCF STATUS,5    ;SELECT BANK0
    RETURN  
;********************************************************
;SETUP PWM MODULE 
;********************************************************
SETUP_PWM
    BCF STATUS,6    ;SELECT BANK1
    BSF STATUS,5
    MOVLW   0XFF    ;DEFINE PORT B AS INPUT
    MOVWF   TRISC   ;PORT C INPUT
    MOVWF   PR2     ;SET PWM PERIOD TO 33ms

    BCF STATUS,5    ;SELECT BANK0
    MOVLW   0X0C    ;SET FOR SINGLE OUTPUT ON P1A AND
    MOVWF   CCP1CON ;ACTIVE HIGH. LSBS OF DUTY =0
    MOVLW   0X25
    MOVWF   CCPR1L  ;SET HIGH BITS FOR DC=50% (Roughly)
    BCF PIR1,1      ;CLEAR TMR2IF
    BCF T2CON,0     ;SET TIMER2 PRESCALER TO 1
    BCF T2CON,1
    BSF T2CON,2     ;START TMR2
    RETURN  
    END

As Requested, registers.asm

;*******************************************
;ANY BANK
;*******************************************
STATUS  equ 0x03    
INTCON  equ 0x0B

;*******************************************
;Bank 0 Registers
;*******************************************
PORTB   equ 0x06    
PORTC   equ 0x07    
PORTD   equ 0x08
PIR1    equ 0x0c    
T2CON   equ 0x12    
CCPR1L  equ 0x15    
CCPR1H  equ 0x16    
CCP1CON equ 0x17
CCPR2L  equ 0x1b    
CCPR2H  equ 0x1c    
CCP2CON equ 0x1d

;*******************************************
;Bank 1 Registers
;*******************************************
OPTION_REG  equ 0x81
TRISB   equ 0x86    
TRISC   equ 0x87    
TRISD   equ 0x88    
PIE1    equ 0x8c
OSCCON  equ 0x8f
PR2 equ 0x92    
WPUB    equ 0x95    

;*******************************************
;Bank 3 Registers
;*******************************************
ANSEL   equ 0x0188
ANSELH  equ 0x0189
\$\endgroup\$
  • \$\begingroup\$ please post your registers.asm file. \$\endgroup\$ – Standard Sandun Jan 5 '13 at 2:54
  • \$\begingroup\$ done, although I couldn't seem to separate the two blocks of code. \$\endgroup\$ – Michael Jan 5 '13 at 3:00
  • 1
    \$\begingroup\$ 'MOVWF PR2 ;SET PWM PERIOD TO 33ms' check that line back. I think you didn't load 33 to it. \$\endgroup\$ – Standard Sandun Jan 5 '13 at 3:15
  • \$\begingroup\$ you are correct. I messed up the OSCCON setting. Strange that it would have prevented the PWM from running though...Seems to work now though. Put your response in an answer and I will accept. \$\endgroup\$ – Michael Jan 5 '13 at 3:18
  • \$\begingroup\$ Just as a side not, straight assembly is the devil. Glad you got it working, maybe @sandundhammika will post his answer. Without the @ and his name though he is not notified that you responded. \$\endgroup\$ – Kortuk Jan 7 '13 at 15:37
1
\$\begingroup\$

This is a project in other compiler (MPASM) and other PIC16, but it could help you, note the configuration of the register. The next code is used to control the speed of a motor using a H-bridge, I hope that it works for you:

`   ;use of the CCP module to control motor speed using PWM 
           include p16F877A.inc `

`cntr equ 20
cntr1 equ 21 `


` __CONFIG _RC_OSC & _CP_OFF & _WDT_OFF 
               org 00
             goto start
               org 04
             goto ISR
               org 06
;main program************************************* 
start       bsf STATUS, RP0
            bcf STATUS, RP1 ; select bank 1
            movlw 00
            movwf TRISC 
            movlw B'11111111'
            movwf TRISB
            movwf PR2 ; 255 to PR2
            bcf OPTION_REG, 7 ; active pull-up
            bcf STATUS, RP0 ; select bank 0
            movlw 00
            movwf PORTC
            movlw B'00001100' ; enable PWM
            movwf CCP1CON
            movlw D'128'
            movwf CCPR1 ; 50% duty cycle(motor off)
            bsf T2CON, TMR2ON ; shoot tmr2 without post nor preescale 
            bsf T2CON, T2CKPS1 ; prescaler in 16
            movlw B'10001000' ; INTCON pattern
            movwf INTCON
            goto $
;*************************************************
;SUBROUTINE DELAY*********************************
;*************************************************
delay       movlw D'255'
            movwf cntr
     del1   movlw D'10'
            movwf cntr1
     del    decfsz cntr1
            goto del  
            decfsz cntr
            goto del1
            return
;************************************************`

`;************************************************* 
;INTERRUPT SERVICE ROUTINE************************
;************************************************* 
ISR         btfss PORTB, RB4
            goto incSpeed
            btfss PORTB, RB5
            goto decSpeed
            goto exit`

`incSpeed    movlw D'255'
            xorwf CCPR1, W
            btfsc STATUS, Z ;test increment limit
            goto exit     
            call delay
            movlw D'1'
            addwf CCPR1, F
            btfss PORTB, RB4
            goto incSpeed
            goto exit`

`decSpeed    movlw 0
            xorwf CCPR1, W
            btfsc STATUS, Z ;test decrement limit
            goto exit     
            call delay
            movlw D'1'
            subwf CCPR1, F
            btfss PORTB, RB5
            goto decSpeed
            goto exit`

`exit        bcf INTCON, RBIF
            retfie 
;********************************************  `            
           ` end `

I suggest programming in C compiler

look at the hardw(ISIS PROTEUS): enter image description here

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.