Pwm portb in pic 16f628 in same time


Closed Thread
Results 1 to 23 of 23

Hybrid View

  1. #1
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: Pwm portb in pic 16f628 in same time

    Quote Originally Posted by dragan77 View Post
    Can you ask you for this code,why i cant compile this code?
    What is wrong?
    Code:
    define OSC 20
    
    define SPWMFREQ  100           ' PWM frequency in Hz    
    
    DutyCycle1   VAR  byte    ' 0-255  0=Idle Low   255=Idle High
    DutyCycle2   VAR  byte 
    DutyCycle3   VAR  byte    
    
    SPWM1PIN  VAR PORTB.0          ' SPWM channel 1
    define SPWM1VAR  _DutyCycle1
    
    SPWM2PIN  VAR PORTB.1          ' SPWM channel 2
    define SPWM2VAR  _DutyCycle2
    
    SPWM3PIN  VAR PORTB.2          ' SPWM channel 3
    define SPWM3VAR  _DutyCycle3
     
    Include "Multi_SPWM.pbp"
    
    DutyCycle1 = 0
    DutyCycle2 = 127
    DutyCycle3 = 255
    
    Loop:
       Pause 100
    Goto Loop
    What error do you get?

  2. #2
    Join Date
    May 2010
    Posts
    43


    Did you find this post helpful? Yes | No

    Default Re: Pwm portb in pic 16f628 in same time

    I get this error.
    Code:
    ERROR: Variable wsave3 position request 416 beyond RAM_END 335.

  3. #3
    Join Date
    Feb 2006
    Location
    Gilroy, CA
    Posts
    1,530


    Did you find this post helpful? Yes | No

    Default Re: Pwm portb in pic 16f628 in same time

    Quote Originally Posted by dragan77 View Post
    I get this error.
    Code:
    ERROR: Variable wsave3 position request 416 beyond RAM_END 335.
    Somewhere in your include file, mysteriously named "Multi_SPWM.pbp" is a DT_INTS file that still has

    wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3

    and it is not commented out.
    </pre>

  4. #4
    Join Date
    May 2010
    Posts
    43


    Did you find this post helpful? Yes | No

    Default Re: Pwm portb in pic 16f628 in same time

    This is this Multi_SPWM.pbp file:



    Code:
    '****************************************************************
    '*  Name    : Multi_SPWM.pbp                                    *
    '*  Author  : Darrel Taylor                                     *
    '*  Notice  : Copyright (c) 2003                                *
    '*  Date    : May 16, 2004                                      *
    '****************************************************************
    
    DEFINE INTHAND INT_CODE                 ' Tell PBP Where the code starts on an interrupt
    
    wsave       var byte    $20     SYSTEM          ' location for W if in bank0
    
    ' --- IF any of these three lines cause an error ??  Simply Comment them out to fix the problem ----
    wsave1      var byte    $A0     SYSTEM          ' location for W if in bank1
    wsave2      var byte    $120    SYSTEM          ' location for W if in bank2
    wsave3      var byte    $1A0    SYSTEM          ' location for W if in bank3
    ' ------------------------------------------------------------------------------
    
    ssave       var byte    BANK0   SYSTEM          ' location for STATUS register
    psaveU      var byte    BANK0   SYSTEM          ' location for PCLATU register
    psave       var byte    BANK0   SYSTEM          ' location for PCLATH register
    bsave       var byte    BANK0   SYSTEM          ' location for BSR register
    
    DutyCount   VAR byte
    
    
    ASM
        ifdef SPWMFREQ
    FOSC4 = OSC * 1000000 / 4
    IntFREQ = SPWMFREQ * 256
    TimerCount = FOSC4 / IntFREQ
    TimerConst = 65536 - TimerCount + 7
        endif
    ENDASM
    
    ASM
    InitPin  macro  Port, Pin
        MOVE?CT 0, Port, Pin                  ; Make Port.Pin LOW
        ifdef BSR  ; if chip is 16-bit        ; Set TRIS to output
            MOVE?CT 0, ((Port) + 12h), Pin
        else       ; chip is 14-bit
            MOVE?CT 0, ((Port) + 80h), Pin    
        endif
        endm
    ENDASM
    
    ASM
    SPWMActive = 0
    ; ----------------------------------------------------------------------------1-    
    SPWM1used = 0
        ifdef  _SPWM1PIN
            ifdef SPWM1VAR
    SPWM1used = 1
    SPWMActive = 1
            InitPin  _SPWM1PIN
            else
                error "SPWM1VAR must be defined to use SPWM1PIN"
            endif
        else
            ifdef SPWM1VAR
                error "SPWM1PIN must be defined to use SPWM1VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------2-    
    SPWM2used = 0
        ifdef  _SPWM2PIN
            ifdef SPWM2VAR
    SPWM2used = 1
    SPWMActive = 1
            InitPin  _SPWM2PIN
            else
                error "SPWM2VAR must be defined to use SPWM2PIN"
            endif
        else
            ifdef SPWM2VAR
                error "SPWM2PIN must be defined to use SPWM2VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------3-    
    SPWM3used = 0
        ifdef  _SPWM3PIN
            ifdef SPWM3VAR
    SPWM3used = 1
    SPWMActive = 1
            InitPin  _SPWM3PIN
            else
                error "SPWM3VAR must be defined to use SPWM3PIN"
            endif
        else
            ifdef SPWM3VAR
                error "SPWM3PIN must be defined to use SPWM3VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------4-    
    SPWM4used = 0
        ifdef  _SPWM4PIN
            ifdef SPWM4VAR
    SPWM4used = 1
    SPWMActive = 1
            InitPin  _SPWM4PIN
            else
                error "SPWM4VAR must be defined to use SPWM4PIN"
            endif
        else
            ifdef SPWM4VAR
                error "SPWM4PIN must be defined to use SPWM4VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------5-    
    SPWM5used = 0
        ifdef  _SPWM5PIN
            ifdef SPWM5VAR
    SPWM5used = 1
    SPWMActive = 1
            InitPin  _SPWM5PIN
            else
                error "SPWM5VAR must be defined to use SPWM5PIN"
            endif
        else
            ifdef SPWM5VAR
                error "SPWM5PIN must be defined to use SPWM5VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------6-    
    SPWM6used = 0
        ifdef  _SPWM6PIN
            ifdef SPWM6VAR
    SPWM6used = 1
    SPWMActive = 1
            InitPin  _SPWM6PIN
            else
                error "SPWM6VAR must be defined to use SPWM6PIN"
            endif
        else
            ifdef SPWM6VAR
                error "SPWM6PIN must be defined to use SPWM6VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------7-    
    SPWM7used = 0
        ifdef  _SPWM7PIN
            ifdef SPWM7VAR
    SPWM7used = 1
    SPWMActive = 1
            InitPin  _SPWM7PIN
            else
                error "SPWM7VAR must be defined to use SPWM7PIN"
            endif
        else
            ifdef SPWM7VAR
                error "SPWM7PIN must be defined to use SPWM7VAR"
            endif
        endif
    ; ----------------------------------------------------------------------------8-    
    SPWM8used = 0
        ifdef  _SPWM8PIN
            ifdef SPWM8VAR
    SPWM8used = 1
    SPWMActive = 1
            InitPin  _SPWM8PIN
            else
                error "SPWM8VAR must be defined to use SPWM8PIN"
            endif
        else
            ifdef SPWM8VAR
                error "SPWM8PIN must be defined to use SPWM8VAR"
            endif
        endif
    EndASM
    
    ASM
    ; -----------------  ADD TimerConst to TMR1H:TMR1L
    ADD2_TIMER   macro
        CHK?RP  T1CON
        BCF     T1CON,TMR1ON           ; Turn off timer
        MOVLW   LOW(TimerConst)        ;  1
        ADDWF   TMR1L,F                ;  1    ; reload timer with correct value
        BTFSC   STATUS,C               ;  1/2
        INCF    TMR1H,F                ;  1
        MOVLW   HIGH(TimerConst)       ;  1
        ADDWF   TMR1H,F                ;  1
        endm
    ENDASM
    
    ASM
    ; -----------------  ADD TimerConst to TMR1H:TMR1L and restart TIMER1 
    RELOAD_TIMER  macro
     ADD2_TIMER
        BSF     T1CON,TMR1ON           ;  1    ; Turn TIMER1 back on
        CHK?RP  PIR1
        bcf     PIR1, TMR1IF           ; Clear Timer1 Interrupt Flag
        endm
    ENDASM
    
    ASM
    ; -----------------  Load TimerConst into TMR1H:TMR1L 
    LOAD_TIMER  macro
        MOVE?CB  0, T1CON              ; Turn OFF Timer1
        MOVE?CB  0, TMR1L              ; Reset Timer1 to 00:00
        MOVE?CB  0, TMR1H
        ADD2_TIMER
        endm
    EndAsm
    
    ; -----------------  Start PWM's (IF active)  ----------------------------------    
    ASM
        ifdef SPWMFREQ
            if SPWMActive == 1
                LOAD_TIMER
                CHK?RP  PIE1
                bsf   PIE1, TMR1IE    ; Enable Timer1 Interrupts
                CHK?RP  INTCON
                bsf   INTCON, PEIE    ; Turn ON peripheral interrupts
                bsf   INTCON, GIE     ; Turn ON global interrupts
                CHK?RP  PIR1
                bcf   PIR1, TMR1IF
                bsf   T1CON, TMR1ON  ; Turn ON Timer1
            else
                messg  "SPWMFREQ has been defined, but no SPWM channels are allocated"
            endif
        else
            if SPWMActive == 1
                error "SPWMFREQ must be defined to use any SPWM channels"
            else
                messg "Multi_SPWM included but no Channels have been defined"
            endif
        endif  
    ENDASM
    
       Goto Over_Code
    Asm
    INT_START  macro
        ifdef BSR                  ; if chip is 16-bit
            movff   WREG, wsave          ;6   Wreg
    ;        movff   PCLATU, psaveU       ;8   PCLATU
    ;        movff   PCLATH, psave        ;10  PCLATH
            movff   STATUS, ssave        ;12  STATUS
            movff   BSR, bsave           ;14  BSR
    SaveCycles = 10        
        else                       ; chip is 14-bit
            if (CODE_SIZE <= 2)          ;4  cycles to push PC and jump to Int_Code
                movwf   wsave            ;5  copy W to wsave register
                swapf   STATUS,W         ;6  swap status reg to be saved into W
                clrf    STATUS           ;7  change to bank 0 regardless of current bank
                movwf   ssave            ;8  save status reg to a bank 0 register
                movf    PCLATH,w         ;9  move PCLATH reg to be saved into W reg
                movwf   psave            ;10 save PCLATH reg to a bank 0 register
            endif
    SaveCycles = 10        
        endif
        endm
    EndAsm
    
    
    Asm
    INT_RETURN   macro
        ifdef BSR                  ; if chip is 16-bit
            movff   bsave, BSR           ;2   BSR
            movff   ssave, STATUS        ;4   STATUS
    ;        movff   psaveU, PCLATU       ;6   PCLATU
    ;        movff   psave, PCLATH        ;8   PCLATH
            movff   wsave, WREG          ;6  WREG
    RestoreCycles = 10                   ;10 - add 4 to POP and return
        else                       ; chip is 14-bit
    ;        movf    psave,w              ;1  Restore the PCLATH reg
    ;        movwf   PCLATH               ;2
            swapf   ssave,w              ;1  Restore the STATUS reg			
            movwf   STATUS               ;2
            swapf   wsave,f              ;3
            swapf   wsave,w              ;4  Restore W reg
    RestoreCycles = 8                    ;8 - add 4 to POP and return
        endif
        retfie                           ; Return from Interrupt
        endm
    EndAsm
    
    ASM
    SPWMint  macro Port, Pin, DutyVar   ; Interrupt code for each Pin
      local  NotIdle, IdleHigh, SPWMdone, StartAdd1, EndAdd1, StartAdd2, EndAdd2
    StartAdd1 = $
        MOVE?BA   DutyVar              ; Copy DutyVar to W reg
        btfss     STATUS, Z            ; if DutyVar = 0
        goto      NotIdle              ; No, Skip Idle
    EndAdd1 = $
        CHK?RP    Port                 ; YES, then idle Low
        bcf       Port, Pin            ; Set Pin Low
        goto      SPWMdone
    NotIdle
    StartAdd2 = $
        MOVE?BA   _DutyCount           ; Copy DutyCount to W reg
        CHK?RP    DutyVar              ; Select proper bank
        subwf     DutyVar, W           ; Subtract DutyVar from DutyCount
        MOVE?TT   STATUS,C, Port,Pin   ; Copy carry bit to Port/Pin
    EndAdd2 = $
    SPWMdone
    
      ifdef BSR        ; if chip is 16-bit core
    InstCount = InstCount + ((EndAdd1 - StartAdd1 + EndAdd2 - StartAdd2) / 2)  
      else             ; chip is 14-bit core
    InstCount = InstCount + (EndAdd1 - StartAdd1 + EndAdd2 - StartAdd2)
      endif
        endm
    ENDASM
    
    
    ; ------- Interrupt Code ------------------------------------------------------- 
    ASM
    INT_CODE
    InstCount = 0
        INT_START
        CHK?RP  PIR1
        btfss   PIR1, TMR1IF
        goto    NoTMR1Int
        RELOAD_TIMER
        if SPWM1used == 1
            SPWMint  _SPWM1PIN, SPWM1VAR
        endif
        if SPWM2used == 1
            SPWMint  _SPWM2PIN, SPWM2VAR
        endif
        if SPWM3used == 1
            SPWMint  _SPWM3PIN, SPWM3VAR
        endif
        if SPWM4used == 1
            SPWMint  _SPWM4PIN, SPWM4VAR
        endif
        if SPWM5used == 1
            SPWMint  _SPWM5PIN, SPWM5VAR
        endif
        if SPWM6used == 1
            SPWMint  _SPWM6PIN, SPWM6VAR
        endif
        if SPWM7used == 1
            SPWMint  _SPWM7PIN, SPWM7VAR
        endif
        if SPWM8used == 1
            SPWMint  _SPWM8PIN, SPWM8VAR
        endif
        CHK?RP   _DutyCount
        incf     _DutyCount, F
    NoTMR1Int
    ; ---- Test for other interrupts here (If needed) ------------------------------
       
        INT_RETURN
    ENDASM
    ; ------- End of Interrupt Code ------------------------------------------------
    
    ASm
    InstCount = InstCount + SaveCycles + RestoreCycles
    BetweenInts = TimerCount - InstCount
      if (BetweenInts < 0)
          error Current SPWM configuration is INVALID - There is no time left between interrupts
          messg 1 - "Try using a SPWMFREQ lower than" SPWMFREQ
          messg 2 - Use a faster cyrstal than OSC Mhz
          messg 3 - Use fewer SPWM channels
      endif
    ENDASM
    
    Over_Code:
    
    [TabIndex]
    Value=0

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts