Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Assembly PWM module not working

Status
Not open for further replies.

Cantafford

Member
Hey,

I'm trying to set up the CCP1CON module of the PIC16f870 microcontroller in PWM mode. I wrote this simple code that's supposed to send a 100% duty cycle on the CCP1CON(RC2) pin. I have attached a dc motor interfaced with a L293D driver to test the duty cycle's value. I have calculated the values for the registers using this PWM calculator:

https://www.micro-examples.com/public/microex-navig/doc/097-pwm-calculator.html

This is the code:
Code:
#include "p16F870.inc"

; CONFIG
; __config 0xFF3A
 __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_ALL

cblock 20h
  d1
  d2
  d3
endc 


RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG CODE                      ; let linker place main program

START
   
    bsf 03h, 5 ; select bank1
    bcf 03h, 6
    movlw b'00000000' ; PORTB made as output
    movwf 86h
    call _pwm_init
    movlw h'01' ;direction assigned for the motor
    movwf 06h
   
loop ; loop forever
   
   
   
   
goto loop

   
_delay_1s
        movlw    0x2D
    movwf    d1
    movlw    0xE7
    movwf    d2
    movlw    0x0B
    movwf    d3
_delay_1s_0
    decfsz    d1, f
    goto    $+2
    decfsz    d2, f
    goto    $+2
    decfsz    d3, f
    goto    _delay_1s_0
        return 
   
_pwm_init
    bcf 87h, 2 ;make RC2 bit an output
    movlw b'11001111' 
    movwf 92h   ;PR2
    bcf 03h, 5 ; select bank0
         bcf 03h, 6
    movlw b'00000111' 
    movwf 12h   ;T2CON
    movlw b'01100111'
    movwf 15h   ;CCPR1L
    movlw b'00111100'
    movwf 17h   ;CCP1CON
    return
    END

My CCP1CON(RC2) pin won't initialise. It stays in 0 logic no matter what duty cycle I send. What am I missing? I calculated a pwm frequency of 1.5khz and a duty cycle of 100%

1tmwqb.png
 
Last edited:
I'm starting to think there is an issue with your sim..

The code and schematic work fine for me...

Two screenshots.... one with CCPR1L at 11001111
And CCPR1L at 0100111..

The scope said it all...
 

Attachments

  • cant1.png
    cant1.png
    124 KB · Views: 231
  • cant2.png
    cant2.png
    122.8 KB · Views: 227
I have wrote this code for the PIC18F2550(basically same thing re-written for this MCU) which has an internal oscillator. Now everything works fine. So I'm guessing my problems arised because of the way ISIS or my program was intepreting the external oscillator which I was feeding the PIC16F. I'm aslo guessing the other programs which did not work for me but worked for you would work now as well.

Code:
; PIC18F2550 Configuration Bit Settings

; ASM source line config statements

#include "p18F2550.inc"

; CONFIG1L
  CONFIG  PLLDIV = 1            ; PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
  CONFIG  CPUDIV = OSC1_PLL2    ; System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
  CONFIG  USBDIV = 1            ; USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

; CONFIG1H
  CONFIG  FOSC = INTOSCIO_EC    ; Oscillator Selection bits (Internal oscillator, port function on RA6, EC used by USB (INTIO))
  CONFIG  FCMEN = OFF           ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
  CONFIG  IESO = OFF            ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

; CONFIG2L
  CONFIG  PWRT = OFF            ; Power-up Timer Enable bit (PWRT disabled)
  CONFIG  BOR = OFF             ; Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
  CONFIG  BORV = 3              ; Brown-out Reset Voltage bits (Minimum setting 2.05V)
  CONFIG  VREGEN = OFF          ; USB Voltage Regulator Enable bit (USB voltage regulator disabled)

; CONFIG2H
  CONFIG  WDT = OFF             ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
  CONFIG  WDTPS = 32768         ; Watchdog Timer Postscale Select bits (1:32768)

; CONFIG3H
  CONFIG  CCP2MX = ON           ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
  CONFIG  PBADEN = OFF          ; PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
  CONFIG  LPT1OSC = OFF         ; Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
  CONFIG  MCLRE = OFF           ; MCLR Pin Enable bit (RE3 input pin enabled; MCLR pin disabled)

; CONFIG4L
  CONFIG  STVREN = ON           ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
  CONFIG  LVP = ON              ; Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
  CONFIG  XINST = OFF           ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

; CONFIG5L
  CONFIG  CP0 = OFF             ; Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
  CONFIG  CP1 = OFF             ; Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
  CONFIG  CP2 = OFF             ; Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
  CONFIG  CP3 = OFF             ; Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

; CONFIG5H
  CONFIG  CPB = OFF             ; Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
  CONFIG  CPD = OFF             ; Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

; CONFIG6L
  CONFIG  WRT0 = OFF            ; Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
  CONFIG  WRT1 = OFF            ; Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
  CONFIG  WRT2 = OFF            ; Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
  CONFIG  WRT3 = OFF            ; Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

; CONFIG6H
  CONFIG  WRTC = OFF            ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
  CONFIG  WRTB = OFF            ; Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
  CONFIG  WRTD = OFF            ; Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

; CONFIG7L
  CONFIG  EBTR0 = OFF           ; Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
  CONFIG  EBTR1 = OFF           ; Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
  CONFIG  EBTR2 = OFF           ; Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
  CONFIG  EBTR3 = OFF           ; Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

; CONFIG7H
  CONFIG  EBTRB = OFF           ; Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
 
ES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG CODE                      ; let linker place main program

START
    BANKSEL OSCCON       ;internal 8Mhz oscillator
    movlw b'01110111'
    movwf OSCCON
 
    movlw b'01010010'
    movwf PR2
 
    movlw b'00000111'
    movwf T2CON
 
    BANKSEL CCPR1L
    movlw b'00101001'
    movwf CCPR1L
 
    movlw b'00011100'
    movwf CCP1CON
 
    BANKSEL TRISC
    clrf TRISC
    bsf LATC, 0
    bcf LATC, 1
   
    loop                          ; loop forever
 
 
    goto loop

    END

Thank you Ian Rogers for answering all my questions like always :D
 
Last edited:
My Sim had some issues with how the config word was setup and the start vector. I use MPASMWIN compiler.
Anyway, with a few minor setup alterations everything seems fine.:)

Code:
list     p=16F870         ; list directive to define processor
   #include "p16F870.inc"

; CONFIG
   __config 0xFF3A
;   __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_ALL
;
   cblock 20h
   d1
   d2
   d3
   endc


   ORG  0x0000  ; processor reset vector
     GOTO  START  ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED
   Org   0x04   ; interrupt vector reserved space
   
   START
   
     bsf 03h, 5 ; select bank1
     bcf 03h, 6
     movlw b'00000000' ; PORTB made as output
     movwf 86h
     call _pwm_init
     movlw h'01' ;direction assigned for the motor
     movwf 06h
   
loop ; loop forever
   
     goto loop

   
_delay_1s
     movlw  0x2D
     movwf  d1
     movlw  0xE7
     movwf  d2
     movlw  0x0B
     movwf  d3
_delay_1s_0
     decfsz  d1, f
     goto  $+2
     decfsz  d2, f
     goto  $+2
     decfsz  d3, f
     goto  _delay_1s_0
       return
   
_pwm_init
     bcf 87h, 2 ;make RC2 bit an output
     movlw b'11001111'
     movwf 92h  ;PR2
     bcf 03h, 5 ; select bank0
     bcf 03h, 6
     movlw b'00000111'
     movwf 12h  ;T2CON
     movlw b'01100111'
     movwf 15h  ;CCPR1L
     movlw b'00111100'
     movwf 17h  ;CCP1CON
     return
  END
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top