PDA

View Full Version : 16 bit PWM using CCP1



Normnet
- 13th December 2009, 04:39
I am trying to do 16 bit PWM as per Tip#10 16 bit Resolution PWM page 40 (3-10) Microchip Tips 'n Tricks
(http://ww1.microchip.com/downloads/en/DeviceDoc/01146B.pdf)
Basically when TM1 value equals the CCP1 (PWM duty) setting the CCP1 interrupt sets PORTC.2 low (works OK).
When the free running TM1 interrupts it is supposed to set PORTC.2 high (doesn't).

As a test CCP1 can be configured to toggle (this works OK as see in ISIS) but if configured
to set low for PWM the pin cannot be set high again even though CCP1 int is cleared.

The following code tries to set pin high in TM1 interrupt.

Norm


'FL PIC18F4520
; @ __CONFIG _CONFIG1H, _OSC_XT_1H
@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
@ __CONFIG _CONFIG2L, _BOREN_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H
@ __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L


DEFINE OSC 40

Clear

sSEROUT_PIN VAR PORTA.2
sBAUD CON 16416 '16416 = 19200 BAUD

wsave VAR BYTE bankA system ' Saves W
ssave VAR BYTE bankA system ' Saves STATUS
yTEMP VAR Byte
wDUTY VAR Word
wDUTY = 32768 '32768 = 50% DUTY PWM

'********************
'16 BIT CCP1 PWM
Input PORTC.2 ' Disable the HPWM output while things are being setup
RCON.7 = 0 ' 0 DISABLES PRIORITY LEVELS ON INTERRUPTS (16F COMPATABILITY)
T1CON = %10110000 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000101 ' enable CCP1, TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
Output PORTC.2 ' Set PORTC.2 (CCP1) to output

' CCP1CON = %00000010 'TOGGLE PORTC.2 ON MATCH TM1 WITH DUTY ********** OK ************
CCP1CON = %00001001 'LOW PORTC.2 ON MATCH TM1 WITH DUTY ?????????? NOT OK ???????????????

T3CON = %00000000

' CCPR1L = wDUTY.LOWBYTE
CCPR1H = wDUTY.HighByte
CCPR1L = wDUTY.LowByte


DEFINE INTHAND myint

Goto START 'Jump over the subroutines


'**** ASSEMBLY INTURRUPT ROUTINE ****
Asm
myint ;KEEP LEFT
; Save the state of critical registers
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS To W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
EndAsm

' yTEMP = yTEMP +1
' SerOut2 sSEROUT_PIN,sBAUD,["INT ",DEC yTEMP,13]

PIR1.2 = 0 ' CLEAR THE CCP1 INT FLAG
High PORTC.2 '???????????????? DOES NOT SET HIGH ?????????????????

Asm
bcf PIR1, 0 ; Clear interrupt flag

swapf ssave, W ; Retrieve the swapped STATUS value (swap To avoid changing STATUS)
movwf STATUS ; Restore it To STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it To W (swap To avoid changing STATUS)
retfie ; Return from interrupt
EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****



'***********************************************
'***********************************************
START:

PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]

T1CON.0 = 1 'TMR1 ON

MAIN:

yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500

Goto MAIN

End

Darrel Taylor
- 13th December 2009, 19:43
Hi Norm,

To set the pin High, simply clear the CCP1CON register, then load it<sub>(Bruce)</sub> with the compare mode again %00001001 (9).

And, only do it on a Timer1 interrupt. The CCP changes the pin low on its own, so you don't need to enable the CCP interrupt.

A few other things are either not needed or can be done differently.
Have a go at this ...
'FL PIC18F4520
; @ __CONFIG _CONFIG1H, _OSC_XT_1H
@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
@ __CONFIG _CONFIG2L, _BOREN_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H
@ __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L


DEFINE OSC 40
DEFINE INTHAND myint

Clear

sSEROUT_PIN VAR PORTA.2
sBAUD CON 16416 '16416 = 19200 BAUD

yTEMP VAR Byte

wDUTY VAR WORD EXT ' map wDuty to CCPR1L:H as a word
@wDUTY = CCPR1L

'***********************************************
START:
ADCON1 = $0F ' disable analog functions
CMCON = 7 ' disable comparators

'********************
'16 BIT CCP1 PWM
T1CON = %00110000 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000001 ' enable TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
CCP1CON = %00001001 ' LOW PORTC.2 ON MATCH TM1 WITH DUTY
OUTPUT PORTC.2 ' Set PORTC.2 (CCP1) to output, starts High

wDUTY = 32768 ' 32768 = 50% DUTY PWM
T1CON.0 = 1 ' TMR1 ON

PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]

'***********************************************

MAIN:
yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500
Goto MAIN


'**** ASSEMBLY INTERRUPT ROUTINE ****
Asm
myint
movlw 9 ; %00001001 compare mode, low on match
clrf CCP1CON ; clrf added per Bruce's suggestion
movwf CCP1CON ; Set Pin to default state (High)
bcf PIR1,0 ; Clear Timer Int Flag
retfie FAST ; Return from interrupt with shadow regs
EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****


End

P.S. Using both CCP's with this method would make a great 2 channel hardware driven servo driver.
Dutycycles between 2500-5000 would give pulses between 1-2ms at ~40hz.

Darrel Taylor
- 13th December 2009, 23:47
And since you made me think of it ... :)

Here's a 2 channel Hardware Servo Driver, that uses Timer1 and both CCP modules in Compare mode.
With an 18F.

Servo outputs are the CCP? pins.
Pulses will be continuous at ~40hz, regardless of MainLoop activity.

Cheers ...
'************************************************* **************************
'* Name : 2CH_Servo.pbp
'* Author : Darrel Taylor
'* Date : 12/13/2009
'* Notes : 18F's only
'************************************************* **************************
@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
@ __CONFIG _CONFIG2L, _BOREN_OFF_2L
@ __CONFIG _CONFIG2H, _WDT_OFF_2H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L

CLEAR

DEFINE OSC 40
DEFINE INTHAND myint

;----[User Selections]------------------------------------------------------
MoveSpeed CON 3 ' movement speed smaller = faster
PosRange CON 900 ' position is 0-900, 0.0-90.0 degrees
' 450 is Center
CCP1pin VAR PORTC.2 ' Specify the pin that CCP1 uses
CCP2pin VAR PORTC.1 ' Specify the pin that CCP2 uses

;----[Variables and Aliases]------------------------------------------------
Servo1 VAR WORD ' Position for Servo1
Servo2 VAR WORD ' Position for Servo2
DutyHold1 VAR WORD BANK0 SYSTEM ' holds next dutycycle, synch with PWM
DutyHold2 VAR WORD BANK0 SYSTEM '
TempW VAR WORD ' temporary variable
POS VAR WORD ' loop counter variable

TMR1IE VAR PIE1.0 ' Timer1 Interrupt Enable
TMR1IF VAR PIR1.0 ' Timer1 Interrupt Flag
TMR1ON VAR T1CON.0 ' Timer1 ON bit
GIE VAR INTCON.7 ' Global Interrupt Enable
PEIE VAR INTCON.6 ' Peripheral Interrupt Enable

;----[Initialization]-------------------------------------------------------
Init:
T1CON = %00100000 ' Timer1 off, Prescaler 1:4 (40mhz)
' 1:2 (20mhz), 1:1 (10mhz)
TMR1IE = 1 ' Enable TMR1 overflow interrupt
TMR1IF = 0 ' Clear TMR1 interrupt flag
PEIE = 1 ' Enable peripheral interrupts
GIE = 1 ' Enable global interrupts
CCP1CON = 9 ' Low on match TMR1 with DUTY1
CCP2CON = 9 ' Low on match TMR1 with DUTY2
OUTPUT CCP1pin ' Set CCP1 pin to output, starts High
OUTPUT CCP2pin ' Set CCP1 pin to output, starts High

Servo1 = PosRange/2 ' Start at Center Position
Servo2 = PosRange/2
GOSUB SetServos
TMR1ON = 1 ' turn ON TMR1
PAUSE 2000 ' allow time for servo to Home


;----[Main Program Loop]----------------------------------------------------
Main:
FOR POS = 0 TO PosRange ' move both from one end to the other
Servo1 = POS
GOSUB SetServo1 ' Set servo1's position
Servo2 = POS
GOSUB SetServo2 ' Set servo2's position
PAUSE MoveSpeed ' movement speed
NEXT POS

FOR POS = PosRange TO 0 STEP -1 ' move servo1 back to home
Servo1 = POS
GOSUB SetServo1
PAUSE MoveSpeed
NEXT POS

FOR POS = PosRange TO 0 STEP -1 ' move servo2 back to home
Servo2 = POS
GOSUB SetServo2
PAUSE MoveSpeed
NEXT POS

PAUSE 1000
Goto Main ' rinse and repeat

;----[Convert Position in degrees to dutycycle]-----------------------------
SetServos: ' Set both Servo's dutycycles
GOSUB SetServo1

SetServo2: ' scale Posistion to 2500 Dutycycle
TempW = Servo2 * 2500
TempW = DIV32 PosRange + 2500
GIE = 0 ' no ints during variable update
DutyHold2 = TempW
GIE = 1
RETURN

SetServo1:
TempW = Servo1 * 2500
TempW = DIV32 PosRange + 2500
GIE = 0
DutyHold1 = TempW
GIE = 1
RETURN

;----[Dual Servo Driver - Interrupt Service]--------------------------------
Asm
myint
movlw 9 ; %00001001 compare mode, low on match
clrf CCP1CON ; clrf added per Bruce's suggestion
movwf CCP1CON ; Set Pins to default state (High)
clrf CCP2CON ; clrf added per Bruce's suggestion
movwf CCP2CON
movf DutyHold1+1,W ; update current position's dutycycle
movwf CCPR1H ; for both servos
movf DutyHold1,W
movwf CCPR1L
movf DutyHold2+1,W
movwf CCPR2H
movf DutyHold2,W
movwf CCPR2L
bcf PIR1,0 ; Clear Timer Int Flag
retfie FAST ; Return from interrupt with shadow regs
EndAsm

Bruce
- 14th December 2009, 02:28
Hi Darrel,

Pretty cool stuff. Have you tested this on other 18F parts? I don't have a 4520 to test
with, but I couldn't get this to work without clearing CCP1CON before moving 9 to it on
a 452 or 4431.

Had to do this;


ASM
MyInt
clrf CCP1CON ; 18F452 & 18F4431 require this before it changes CCP1 output
movlw 9
movwf CCP1CON
bcf PIR1,TMR1IF ; clear TMR1 int flag
retfie FAST ; use RETFIE FAST to restore WREG, STATUS & BSR
ENDASM
On an 18F452 or 18F4431, the above works fine, but only if I clear CCP1CON first.

This works on a 452 & 4431 with CCP1 & TMR1 ints enabled on any output pin;


ASM
MyInt
btfss PIR1,TMR1IF ; TMR1 interrupt?
bra CCP ; no - service CCP interrupt
bcf PIR1,TMR1IF ; yes - clear TMR1 int flag
bsf LATB,0 ; set RB0 on TMR1 interrupt
retfie FAST ; return
CCP
bcf PIR1,CCP1IF ; clear CCP1 int flag
bcf LATB,0 ; clear RB0 on compare interrupt
retfie FAST ; use RETFIE FAST to restore WREG, STATUS & BSR
ENDASM
I was just wondering if this might be a fluke with the 4520 part - since none of the other
18F parts I've tested will toggle CCP1 with just the movlw 9, movwf CCP1CON?

Darrel Taylor
- 14th December 2009, 02:53
Hmmm, very interesting.

I had not tried it on any other chips, and with the 4520 you definitely don't have to clear it first.

But I just tried an 18F452, and you are absolutely correct.
It doesn't work unless you clear the CCPCON register first.

Very interesting indeed,
Thanks Bruce.
<br>

Bruce
- 14th December 2009, 03:03
Thanks. I was just curious. I had fought with this one before on a servo driver, and just
couldn't get it to work without both ints enabled, or clearing CCP1CON first.

I'm thinking it may be due to the huge number of problems Mchip had (see erratas') on
ECCP & CCP with this one?

Darrel Taylor
- 14th December 2009, 03:30
I'm thinking it may be due to the huge number of problems Mchip had (see erratas') on ECCP & CCP with this one?

No doubt!

BTW, I like the any Output Pin variation too. http://www.picbasic.co.uk/forum/images/icons/icon14.gif
<br>

Normnet
- 14th December 2009, 03:57
Works good!
Thanks Darrel

Would it be correct to say the maximum PWM frequency for a 40 MHz PIC is 152 Hz?
To slow for music.
Know of any > 10 bit PWM PIC's?

Norm

Darrel Taylor
- 14th December 2009, 04:54
Yup, that's what mister-e's calculator says with 40mhz, 1:1, and 16-bit. 152 hz.

The PIC18F2331/2431/4331/4431 series has a bunch of 14-bit PWM modules. But they are completely different from the CCP module.

Bruce has done a few examples, but I don't think any of them were for music. :eek:

best regards,

Normnet
- 14th December 2009, 05:52
PIC18F2331/2431/4331/4431:

FOSC 40 MHz
MIPS 10
PWM Resolution 14 bits
PWM Frequency 2.4 kHz

14 bit to slow for CD quality music.
10 bit sounds good though.

A dsPIC would be ideal.

On my first post my code included saving the state of the critical registers.
Would this be required in a longer program?

Norm

Darrel Taylor
- 14th December 2009, 06:32
Maybe you'd be better off with an R2R network as a Digital to Analog Converter.

Something like what Steven Wright did here (Not PBP).
SDMMCWavPlayer
http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.SDMMCWavPlayer


And no, you won't need to save STATUS, WREG and BSR, unless you start using Low Priority interrupts.
The Shadow registers automatically save and restore them in hardware for High priority ints on 18F's.
<br>

Normnet
- 14th December 2009, 06:48
R2 ladder done here PIC iPod wav player (http://www.picbasic.org/forum/showthread.php?t=10662)

Now would like to port to PBP a basic PWM low pin count low part count wave player.
The code is 8,069 program bytes possibly less if optimized.
Are their < 28 pin 18F PICs supported by compiler 2.50C?

Norm

Mike, K8LH
- 28th October 2010, 16:09
.... Pulses will be continuous at ~40hz ....

How do you get ~40-Hz?

<added>

Oops! Sorry! I see it. Timer 1 rollover every 26.2144 msecs (38.14697265625 Hz)... I need another cup o' coffee (grin)...

talatsahim
- 20th August 2014, 20:30
Hi Everyone,
Talat from Istanbul here. Please help wıth my PWM problem.
My code is runnıng BUT I get only 1 or 2 output pulses from port B3 on startup then no output after that.
What am ı doıng wrong?
Thanks ın advance fo you help.
Talat

'************************************************* ***************
'* Name : *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 09.08.2014 *
'* Version : 1.0 *
'* Notes : 16F1827 *
'* : *
'************************************************* ***************
' DEVİCE 16F1827

ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
ENDASM
CLEAR
DEFINE OSC 32
OSCCON=%01110000 '32

DEFINE INTHAND PWM_INT

PWM_VAL VAR WORD BANK0 SYSTEM
VALUE VAR WORD

INIT:
APFCON0 = 0 'SET PORTB.3 TO CCP1
T1CON = %00100000 'Prescaler 1:4

PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
INTCON.7 = 1 'GIE Global Interrupt Enable
INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
CCP1CON = 9 'compare mode
OUTPUT PORTB.3 'CCP PIN


T1CON.0 = 1 'TMR1ON SET TMR1
PAUSE 1000
VALUE=1000

MLOOP:
VALUE=VALUE+1
PWM_VAL = VALUE
Goto MLOOP


Asm
PWM_INT
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
movf PWM_VAL+1,W ; hb
movwf CCPR1H ; put
movf PWM_VAL,W ; lb
movwf CCPR1L ; put
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

END

talatsahim
- 20th August 2014, 20:38
Hi Darrel & Everyone,
Talat from Istanbul here. Please help with my PWM problem.
My code is running(?) BUT I get only 1 or 2 output pulses from port B3 on startup then no output after that.
What am I doıng wrong?
Thanks in advance fo you help.
Talat

'************************************************* ***************
'* Name : *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 09.08.2014 *
'* Version : 1.0 *
'* Notes : 16F1827 *
'* : *
'************************************************* ***************
' DEVİCE 16F1827

ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
ENDASM
CLEAR
DEFINE OSC 32
OSCCON=%01110000 '32

DEFINE INTHAND PWM_INT

PWM_VAL VAR WORD BANK0 SYSTEM
VALUE VAR WORD

INIT:
APFCON0 = 0 'SET PORTB.3 TO CCP1
T1CON = %00100000 'Prescaler 1:4

PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
INTCON.7 = 1 'GIE Global Interrupt Enable
INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
CCP1CON = 9 'compare mode
OUTPUT PORTB.3 'CCP PIN


T1CON.0 = 1 'TMR1ON SET TMR1
PAUSE 1000
VALUE=1000

MLOOP:
VALUE=VALUE+1
PWM_VAL = VALUE
Goto MLOOP


Asm
PWM_INT
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
movf PWM_VAL+1,W ; hb
movwf CCPR1H ; put
movf PWM_VAL,W ; lb
movwf CCPR1L ; put
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

END

Acetronics2
- 20th August 2014, 20:43
Hi, Talatsahim

First have a look to how PBP shares its variables with asm ...

Alain

Archangel
- 21st August 2014, 01:47
Hi, Talatsahim

First have a look to how PBP shares its variables with asm ...

Alain_WhatsThat ?

Dave
- 21st August 2014, 11:42
For starters, There is NO 16 bit compare register for PWM use. The upper byte is shared with a few other bits of config. There is ONLY 10 bit's available for PWM use in hardware. Read the data sheet for the processor you are using.

talatsahim
- 21st August 2014, 12:46
Hi, Acetronics2

This is part of code. Variable sharing, what is wrong?

Thanx

talatsahim
- 21st August 2014, 12:54
Thanx Dave,

I use 10 bit hardware PWM. But I need more resulation. I such a little trick :)

Talat

Dave
- 22nd August 2014, 11:52
What Acetronics2 is trying to say is, when accessing PBP variables inside of an ASM routine you need to prefix an underscore before the variable name such as "movf _PWM_VAL,W ; lb"
As far as getting more resolution from the PIC processor, Your out of luck. You can always build your own digital pwm circuit with hardware if you are so inclined.

talatsahim
- 22nd August 2014, 13:16
Hi Dave,
This is just copy-paste error..
What's interesting is that, these codes do not work to as 8-bit (10 bit too)
Thanx

HenrikOlsson
- 22nd August 2014, 13:22
Hi,

As far as getting more resolution from the PIC processor, Your out of luck.
So, Microchip themselves and previous posters in the this thread (Darrel, Bruce, Norm) are wrong then, what am I missing?

When using the CCP module in PWM mode it's limited to 10bits resolution. But if you use it in compare mode, the way that the application note describes you can get 16bit resolution but:
1) You won't be able to get 100% dutycycle
2) The maximum output frequency will be limited to ~122Hz @32MHz.
3) You'll get some CPU load from the interrupt processing.
4) You need to deal with assembly code in the ISR (or deal with more "CPU load" if using DT-Ints)

/Henrik.

EarlyBird2
- 23rd August 2014, 06:41
What Acetronics2 is trying to say is, when accessing PBP variables inside of an ASM routine you need to prefix an underscore before the variable name such as "movf _PWM_VAL,W ; lb"
As far as getting more resolution from the PIC processor, Your out of luck. You can always build your own digital pwm circuit with hardware if you are so inclined.

But Darrel did not do this in his code, prefix with "_". Also as Talat has said he is following Darel's example for "16 bit PWM using CCP1" which obviously worked for Darrel, Bruce and Norm.

So Talat 16 bit PWM is possible. I have read the whole thread and the datasheets for the 18F452 and the chip you are using 16F1827.

The first possible issue Darell said his code was for 18F's only in post 3 does anyone know why not 16F's? The 16F has CCPx compare mode.
With regard to the 16F1827 I think CCP4 has the required features needed and CCP1 does not but I need more time to re-read the datasheet but in the meantime it would be helpful if some one could confirm which CCPx should be used.

richard
- 23rd August 2014, 07:33
in dt's code the var is declared in a asm routine and as EXT in pbp


wDUTY VAR WORD EXT ' map wDuty to CCPR1L:H as a word
@wDUTY = CCPR1L
if you declare a var in pbp and wish to refer to it in asm it must be prefixed with an underscore as others have stated

EarlyBird2
- 23rd August 2014, 08:02
in dt's code the var is declared in a asm routine and as EXT in pbp


if you declare a var in pbp and wish to refer to it in asm it must be prefixed with an underscore as others have stated

That is from post #1 but in #3 which Talat is using


DutyHold1 VAR WORD BANK0 SYSTEM ' holds next dutycycle, synch with PWM
DutyHold2 VAR WORD BANK0 SYSTEM '

is the way they are declared and again "_" is not used.

EarlyBird2
- 23rd August 2014, 08:21
Found the answer in the manual of all places!


Modifiers can be used to specify certain attributes of the variable when created:
address A numeric address may be used as a modifier. This instructs PBP where to locate the variable in RAM.
BANKx Instructs PBP to locate the variable in a specific bank of RAM.
SYSTEM The default behavior of PBP is to append a prefix underscore character when creating the variable in Assembly Language. The SYSTEM modifier inhibits this behavior so that the variable name will be identical in PBP code and Assembly code.

Does anyone read the manual, me included obviously?

richard
- 23rd August 2014, 08:43
when all else fails

EarlyBird2
- 23rd August 2014, 08:46
The first possible issue Darell said his code was for 18F's only in post 3 does anyone know why not 16F's? The 16F has CCPx compare mode.
With regard to the 16F1827 I think CCP4 has the required features needed and CCP1 does not but I need more time to re-read the datasheet but in the meantime it would be helpful if some one could confirm which CCPx should be used.

Having dealt with the "_", wild goose chase, which had nothing to do with the problem any ideas?

richard
- 23rd August 2014, 11:20
I'm trying to get this idea to fly on a 16f1825
the code when converted to C works fine (I get a nice pwm waveform at 60.85 hz)
but it won't fly with pbp3 yet




/*
* File: newmain.c
* Author: richard
*
* Created on 23 August 2014, 7:25 PM
*/


#include <xc.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = ON // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

typedef unsigned char byte;
#define bit_time 100 // 9600 ok @8mhz
#define serout_pin PORTAbits.RA0

#define _XTAL_FREQ 32000000



void send_serial( char data);
void ser_str(char *buff);
byte prnb[20];
uint16_t duty;

void main(void) {

OSCCON=0X70;
ANSELA=0;
ANSELC=0;

TRISA = 0b001110;
TRISC=0b11111001;
PORTA=255;
__delay_ms(2000);
T1CON = 0b00000000 ;
PIE1 = 0b00000001;
INTCON = 0b11000000;
CCP4CON = 0b00001001;

duty = 32768 ;
CCPR4H=duty>>8;
CCPR4L=duty;

T1CONbits.TMR1ON=1;




strcpy(prnb,"ready");
ser_str(prnb);

INTCON=0xc0;
while(1){

strcpy(prnb," loop ");
ser_str(prnb);
sprintf(prnb,"%4x",duty) ;
duty+=200;
ser_str(prnb);
CCPR4H=duty>>8;
CCPR4L=duty;
__delay_ms(2000);


}




return;
}


void interrupt ISR (void) {
CCP4CON=0;
CCP4CON=9;

PIR1bits.TMR1IF=0;
PORTCbits.RC2=!PORTCbits.RC2; // just to check interrupt


}







void send_serial( char data){ // bit_time 200us 4800 baud ,100 us 9600 ,400us 2400 (NOT INVERTED)
uint8_t i;

i=8; // 8 data bits to send
// di();
serout_pin = 0; // make start bit
__delay_us(bit_time);
while(i) // send 8 serial bits, LSB first
{
if(data&1) serout_pin = 1; // invert and send data bit
else serout_pin = 0;

data >>=1 ;//(data >> 1); // rotate right to get next bit
i--;
__delay_us(bit_time); // wait for baud
}

serout_pin = 1; // make stop bit
// ei();
__delay_us(bit_time);

}
void ser_str(char *buff){
char k = strlen(buff);
for (int j=0;j< k;j++){
send_serial(buff[j]);
}
}

richard
- 23rd August 2014, 13:22
A pbp version


'************************************************* ***************
'* Name : PWM16.BAS *
'* Author : RICHARD *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 8/23/2014 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG



include "dt_ints-14.bas"


asm
INT_LIST macro




INT_HANDLER TMR1_INT, _Tm1, asm,yes
endm
INT_CREATE



ENDASM


DEFINE OSC 32




sSEROUT_PIN VAR PORTA.0
sBAUD CON 84 '16416 = 19200 BAUD

yTEMP VAR Byte

wDUTY VAR WORD


'***********************************************
START:
' disable analog functions
OSCCON=$70
ANSELA=0
ANSELC=0

'********************
'16 BIT CCP1 PWM
T1CON = 0 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000001 ' enable TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
' LOW PORTC.2 ON MATCH TM1 WITH DUTY
ccp4con=0
wDUTY = 32768 ' 32768 = 50% DUTY PWM
T1CON.0 = 1 ' TMR1 ON
CCPR4H=$80;
CCPR4L=0;
PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]
trisc = %11111001
'***********************************************
CCP4CON = %00001001
MAIN:
yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500
Goto MAIN


'**** ASSEMBLY INTERRUPT ROUTINE ****
Tm1:
Asm
bsf PORTC ,2
CHK?RP CCP4CON
clrf CCP4CON
movlw 9
movwf CCP4CON
banksel 0
bcf PORTC ,2

EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****
@ INT_RETURN
End

EarlyBird2
- 24th August 2014, 07:04
A pbp version


'************************************************* ***************
'* Name : PWM16.BAS *
'* Author : RICHARD *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 8/23/2014 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************

#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CP_OFF & _WDTE_ON & _PWRTE_ON & _MCLRE_ON & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG



include "dt_ints-14.bas"


asm
INT_LIST macro




INT_HANDLER TMR1_INT, _Tm1, asm,yes
endm
INT_CREATE



ENDASM


DEFINE OSC 32




sSEROUT_PIN VAR PORTA.0
sBAUD CON 84 '16416 = 19200 BAUD

yTEMP VAR Byte

wDUTY VAR WORD


'***********************************************
START:
' disable analog functions
OSCCON=$70
ANSELA=0
ANSELC=0

'********************
'16 BIT CCP1 PWM
T1CON = 0 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000001 ' enable TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
' LOW PORTC.2 ON MATCH TM1 WITH DUTY
ccp4con=0
wDUTY = 32768 ' 32768 = 50% DUTY PWM
T1CON.0 = 1 ' TMR1 ON
CCPR4H=$80;
CCPR4L=0;
PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]
trisc = %11111001
'***********************************************
CCP4CON = %00001001
MAIN:
yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500
Goto MAIN


'**** ASSEMBLY INTERRUPT ROUTINE ****
Tm1:
Asm
bsf PORTC ,2
CHK?RP CCP4CON
clrf CCP4CON
movlw 9
movwf CCP4CON
banksel 0
bcf PORTC ,2

EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****
@ INT_RETURN
End

Impressive Richard!

What was the difference CCP4?

richard
- 24th August 2014, 07:28
no any ccp will work I tested it on 2,3 and 4 , the issue was the Bank selection a pic18 doesn't need it a pic16 will die without it

EarlyBird2
- 24th August 2014, 09:47
'************************************************* ***************
'* Name : *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 09.08.2014 *
'* Version : 1.0 *
'* Notes : 16F1827 *
'* : *
'************************************************* ***************
' DEVİCE 16F1827

ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
ENDASM
CLEAR
DEFINE OSC 32
OSCCON=%01110000 '32

DEFINE INTHAND PWM_INT

PWM_VAL VAR WORD BANK0 SYSTEM
VALUE VAR WORD

INIT:
APFCON0 = 0 'SET PORTB.3 TO CCP1
T1CON = %00100000 'Prescaler 1:4

PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
INTCON.7 = 1 'GIE Global Interrupt Enable
INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
CCP1CON = 9 'compare mode
OUTPUT PORTB.3 'CCP PIN


T1CON.0 = 1 'TMR1ON SET TMR1
PAUSE 1000
VALUE=1000

MLOOP:
VALUE=VALUE+1
PWM_VAL = VALUE
Goto MLOOP


Asm
PWM_INT
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
movf PWM_VAL+1,W ; hb
movwf CCPR1H ; put
movf PWM_VAL,W ; lb
movwf CCPR1L ; put
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

END

Now we know that what you want to do is possible, thanks to Richard. Can anyone work out what is wrong with Talat's code?

richard
- 24th August 2014, 10:09
I didn't pickup what ver of pbp talat was using , and I'm not sure if the chk?rp macro exists in early versions


but try

Asm
PWM_INT
CHK?RP CCP1CON
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
CHK?RP PWM_VAL
movf PWM_VAL+1,W ; hb
CHK?RP CCPRIL
movwf CCPR1H ; put
CHK?RP PWM_VAL
movf PWM_VAL,W ; lb
CHK?RP CCPRIL
movwf CCPR1L ; put
banksel 0
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

if that fails try

banksel CCP1CON OR WHATERVER SFR

OR
read data sheet and find what bank each sfr is in


with all that bank switching the effort may be pointless

richard
- 25th August 2014, 01:33
a warning to anybody trying to use this idea , its not fool proof and apart from the limitations as described by henrik its a bit risky too.


if you try to set the pwm duty below the number of timer ticks taken up during the interrupt latency the pwm pin will be driven high and may cause unexpected results

my tests indicate a minimum pwm duty of 30
caveat emptor

richard
- 25th August 2014, 02:56
post 35 is wrong pie1 is not in bank0 either


Asm
PWM_INT
CHK?RP CCP1CON
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
CHK?RP PWM_VAL
movf PWM_VAL+1,W ; hb
CHK?RP CCPRIL
movwf CCPR1H ; put
CHK?RP PWM_VAL
movf PWM_VAL,W ; lb
CHK?RP CCPRIL
movwf CCPR1L ; put
banksel 0
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
CHK?RP PIE1
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
BANKSEL 0
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm


it just gets worse

talatsahim
- 26th August 2014, 02:52
Richard and EarlyBird,
Thank you very much for your generosity and support.
I'm using version 3.0.1.4.

:)
Talat

EarlyBird2
- 26th August 2014, 09:44
Talat

I do not understand why you included the lines in red in you ISR



'************************************************* ***************
'* Name : *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 09.08.2014 *
'* Version : 1.0 *
'* Notes : 16F1827 *
'* : *
'************************************************* ***************
' DEVİCE 16F1827

ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
ENDASM
CLEAR
DEFINE OSC 32
OSCCON=%01110000 '32

DEFINE INTHAND PWM_INT

PWM_VAL VAR WORD BANK0 SYSTEM
VALUE VAR WORD

INIT:
APFCON0 = 0 'SET PORTB.3 TO CCP1
T1CON = %00100000 'Prescaler 1:4

PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
INTCON.7 = 1 'GIE Global Interrupt Enable
INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
CCP1CON = 9 'compare mode
OUTPUT PORTB.3 'CCP PIN


T1CON.0 = 1 'TMR1ON SET TMR1
PAUSE 1000
VALUE=1000

MLOOP:
VALUE=VALUE+1
PWM_VAL = VALUE
Goto MLOOP


Asm
PWM_INT
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
movf PWM_VAL+1,W ; hb
movwf CCPR1H ; put
movf PWM_VAL,W ; lb
movwf CCPR1L ; put
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

END

As I do not have a 16F1827 I can not do any testing. But after some thought I used an 18F452 to test your code and it did not work. I then compared data sheets for the 16F1827 and 18F452 and finding no reason for the lines in red I commented them out reprogramed the 18F452 and it ran. But I had to add a pause 10 in the main loop so my voltmeter could display the readings.

Here is my version



'************************************************* ***************
'* Name : *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 09.08.2014 *
'* Version : 1.0 *
'* Notes : 16F1827 *
'* : *
'************************************************* ***************
' DEVİCE 16F1827

ASM
__config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
__config _CONFIG2, _PLLEN_ON & _LVP_OFF & _LVP_OFF & _STVREN_OFF; & _VCAPEN_OFF
ENDASM
CLEAR
DEFINE OSC 32
OSCCON=%01110000 '32

DEFINE INTHAND PWM_INT

PWM_VAL VAR WORD BANK0 SYSTEM


INIT:
APFCON0 = 0 'SET PORTB.3 TO CCP1
T1CON = %00100000 'Prescaler 1:4

PIE1.0 = 1 'TMR1IE TMR1 Interrupt Enable
PIR1.0 = 0 'TMR1IF TMR1 Interrupt Flag
INTCON.7 = 1 'GIE Global Interrupt Enable
INTCON.6 = 1 'PEIE Peripheral Interrupt Enable
CCP1CON = 9 'compare mode
OUTPUT PORTB.3 'CCP PIN


T1CON.0 = 1 'TMR1ON SET TMR1
PAUSE 1000


MLOOP:
PWM_VAL = PWM_VAL+1
PAUSE 10
Goto MLOOP


Asm
PWM_INT
movlw 9 ; compare mode
clrf CCP1CON ; clear reg
movwf CCP1CON ; Set reg
movf PWM_VAL+1,W ; hb
movwf CCPR1H ; put
movf PWM_VAL,W ; lb
movwf CCPR1L ; put
bcf PIR1,0 ; TMR1IF = 0 Clear Timer1 Int Flag

RETFIE ; Return from Interrupt
EndAsm

END

I am very interested to know if my version works on the 16F1827 that you have.

richard
- 26th August 2014, 09:55
your version cannot work since CCP1CON and CCPR1H are not in bank 0

and yes the code you marked red serves no purpose in the given example

EarlyBird2
- 26th August 2014, 09:58
your version cannot work since CCP1CON and CCPR1H are not in bank 0

and yes the code you marked red serves no purpose in the given example

My point was that the code in red stopped it working and I could not work out why it was there.

richard
- 26th August 2014, 10:02
the code in red just wastes time ,it's not what stopped the program from working . the problem is the changing sfr's in the wrong bank.

EarlyBird2
- 26th August 2014, 10:03
the code in red just wastes time ,it's not what stopped the program from working . the problem is the changing sfr's in the wrong bank.

It did stop it working on my 18F452 though.

richard
- 26th August 2014, 10:18
bsf INTCON,7 ;GIE = 1
bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1


intcon bits 6 and 7 should already be set , setting them again should do no harm
pie1.0 is also set , setting it again can't hurt

it just wastes 12 cpu cycles

the problem lies elsewhere, PWM_VAL must be > 30 ,values from 0-29 wont work could that have happened

EarlyBird2
- 26th August 2014, 10:36
intcon bits 6 and 7 should already be set , setting them again should do no harm
pie1.0 is also set , setting it again can't hurt

That is exactly what I thought and could not find anything to indicate otherwise in the datasheet.


the problem lies elsewhere, PWM_VAL must be > 30 ,values from 0-29 wont work could that have happened

No I started PWM_VAL for zero and incremented up in steps of 1 and it worked all the way rolling over and starting from 0. If 0-29 does not work I could not detect it with my voltmeter.

richard
- 26th August 2014, 11:00
just tried your "red" code in the isr on a pic18f45k20

you are right

bsf INTCON,6 ;PEIE = 1 Enable peripheral interrupts
bsf PIE1,0 ; TMR1IE= 1 Enable TMR1
these two lines lock it up. can't see why yet

it looked harmless but its not ,its much worse than useless

richard
- 26th August 2014, 11:07
N
o I started PWM_VAL for zero and incremented up in steps of 1 and it worked all the way rolling over and starting from 0. If 0-29 does not work I could not detect it with my voltmeter
I'm using a cro those <30ish pwm's cause the output pin to be permanently high when you expect a very small pw , in real life that could be nasty
try a loop range yourself of 0 to say 28

EarlyBird2
- 26th August 2014, 11:07
The point of coming here is to learn and I am now comparing the architecture of the 18F452 and the 16F1827. They are completely different, not surprise there.

I have found the sfrs are in bank 5 on the 16F1827 but I have no idea how to use this information.

EarlyBird2
- 26th August 2014, 11:18
N
I'm using a cro those <30ish pwm's cause the output pin to be permanently high when you expect a very small pw , in real life that could be nasty
try a loop range yourself of 0 to say 28

Just tried it no problem 0 gave 0 volts 9 gave 3 mV.

richard
- 26th August 2014, 11:22
CALLS TO ASM always set bank 0

pbp has a macro you can use "chk?rp sfr" it will ckeck that the appropriate bank is set (see status or bank sfr)
the mpasm assembler can also do a " BANKSEL SFR"

BEFORE YOU RETURN T0 PBP YOU MUST SET BANK BACK TO BANK 0

richard
- 26th August 2014, 11:33
not on a cro

using a main loop like this
MAIN:

PWM_VAL = PWM_VAL+1
PAUSE 500
if pwm_val > 29 then pwm_val=0
toggle portd.1
Goto MAIN

EarlyBird2
- 26th August 2014, 11:38
not on a cro


What is a cro?

richard
- 26th August 2014, 11:40
oscilloscope

depending on your age , in the old days a cathode ray oscilloscope, cro for short

EarlyBird2
- 26th August 2014, 11:50
N
I'm using a cro those <30ish pwm's cause the output pin to be permanently high when you expect a very small pw , in real life that could be nasty
try a loop range yourself of 0 to say 28

I will take your word for it as I have no instrument that will replicate your results, and as I have found in the past just because I can not see it does not mean it is not there.

richard
- 26th August 2014, 11:59
the 30 figure came from the pic16f1825 using dt_ints14
for a pic18f45k20 the figure is 25 using dt_ints18
for a pic18f45k20 using DEFINE INTHAND the figure is 11
seems dt_ints introduces more latency

point is 0 is not off and pwm < latency is not a small pw

talatsahim
- 26th August 2014, 14:36
your version cannot work since CCP1CON and CCPR1H are not in bank 0

and yes the code you marked red serves no purpose in the given example

Richard,
Thanks for your reply.
Yes, you're right. 103 error occurs after compiling. Banksel command is used, will you?

Talat

talatsahim
- 26th August 2014, 14:51
Thanks :)
Yes, you're right.
My first version was like you, did not work. To better understand the problem I have added including red lines.
I tried again and the result is the same version. In the start-up process produces two pulses and then stops.

talatsahim
- 26th August 2014, 16:25
I installed the PBP trial version 3.0.7 to try. Nothing's changed. Error 113 continues (Post 56, I wrote 103, it's wrong)


74247424

HenrikOlsson
- 26th August 2014, 17:46
Hi,
Check your spelling of CCPR1H and CCPR1L.

/Henrik.

talatsahim
- 27th August 2014, 00:46
Hi,
Henrik, congratulations for being careful, thank you.
This is a completely copy-paste disaster :)
Talat

EarlyBird2
- 27th August 2014, 08:13
Hi,
Henrik, congratulations for being careful, thank you.
This is a completely copy-paste disaster :)
Talat

That error comes from post #35 and #37 is there anyway these posts can be corrected?