CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

How to set the 10bit PWM Duty Cycle in 16F684

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Skipper



Joined: 20 Nov 2004
Posts: 12
Location: Austria

View user's profile Send private message Send e-mail

How to set the 10bit PWM Duty Cycle in 16F684
PostPosted: Wed Dec 08, 2004 6:11 am     Reply with quote

Hi,

I am working with the 16F684. How can I set the PWM Duty Cycle with 10 bit at the easiest way in C ?
Because the CCPR1L contains the eight MSB�s and the CCP1CON contains the two LSB�s.

With a macro ?
With a function ?

Can anybody help me, or have anybody a short example code ?

Thanks !

Skipper
Ttelmah
Guest







Re: How to set the 10bit PWM Duty Cycle in 16F684
PostPosted: Wed Dec 08, 2004 8:42 am     Reply with quote

Skipper wrote:
Hi,

I am working with the 16F684. How can I set the PWM Duty Cycle with 10 bit at the easiest way in C ?
Because the CCPR1L contains the eight MSB�s and the CCP1CON contains the two LSB�s.

With a macro ?
With a function ?

Can anybody help me, or have anybody a short example code ?

Thanks !

Skipper

set_pwm1_duty(val);

Provided the variable passed to this is a 16bit value, in the range 0 to 1023, the compiler automatically splits it and puts it into the required register bits. If you only pass it an 8bit value, the two LSB's in the PWM value are left as '0', and the 8 bit value is put into CCPR1L.
So if you say:
set_pwm1_duty(128);
CCPR1L, will receive 128, and the LSB's will be set to zero.
However if you say:
set_pwm1_duty(128L);
This forces the value to be passed as a 'long', and CCPR1L, will receive the 6 most significant bits, and the two LSB's will be put into CCP1CON.
If you use:

int8 var;
var=128;
set_pwm1_duty(var);

This will function like the first example above, and the 8bit value will be put into CCPR1L. If instead you use:

int16 var;
var=128;
set_pwm1_duty(var);

This will fuction like the second example (the 8bit constant '128', will automatically be converted to a 16bit value, when it is transferred into 'var', and the compiler will know that a long value is available in 'var'.

Best Wishes
Skipper



Joined: 20 Nov 2004
Posts: 12
Location: Austria

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 8:57 am     Reply with quote

Thanks for your answer, but I tried it so like your way yesterday.
I am working with MPLab an when I start the Debugger with the MAPLab SIM and the Debugger comes to the line "set_pwm1_duty(450);" for example, it changes the CCP1CON Register to "112" and at the same time the TMR2 Register is set to "5".

But it changes not the CCPR1L Register.

Is the simulation with MPLab not possible ?
ttelmah
Guest







PostPosted: Wed Dec 08, 2004 9:30 am     Reply with quote

What compiler version?.
There have been a number of 'issues' with the support of the ECCP module on various compiler versions. Look at the assembler generated. You should see something like:
.................... set_pwm1_duty(450L);
0060: MOVLW 70
0061: MOVWF 13
0062: MOVF 15,W
0063: ANDLW CF
0064: IORLW 20
0065: MOVWF 15

It will be pretty obvious if the compiler is writing to the correct registers (13, and 15), or not...

Best Wishes
Skipper



Joined: 20 Nov 2004
Posts: 12
Location: Austria

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 10:12 am     Reply with quote

That�s the generated code:

180: duty = 1011;
0000ED 3003 MOVLW 0x3
0000EE 0AF MOVWF 0x2f
0000EF 30F3 MOVLW 0xf3
0000F0 0AE MOVWF 0x2e
181: set_pwm1_duty(duty);
0000F1 82F MOVF 0x2f, W
0000F2 0A2 MOVWF 0x22
0000F3 82E MOVF 0x2e, W
0000F4 0A1 MOVWF 0x21
0000F5 CA2 RRF 0x22, F
0000F6 CA1 RRF 0x21, F
0000F7 CA2 RRF 0x22, F
0000F8 CA1 RRF 0x21, F
0000F9 CA2 RRF 0x22, F
0000FA 821 MOVF 0x21, W
0000FB 095 MOVWF 0x15
0000FC CA2 RRF 0x22, F
0000FD C22 RRF 0x22, W
0000FE 3930 ANDLW 0x30
0000FF 0A0 MOVWF 0x20
000100 817 MOVF 0x17, W
000101 39CF ANDLW 0xcf
000102 420 IORWF 0x20, W
000103 097 MOVWF 0x17

MPLab 6.62
CCS 3.190

So, now I will check the code.

Thank�s for help !
Ttelmah
Guest







PostPosted: Wed Dec 08, 2004 3:16 pm     Reply with quote

The code is writing to registers 15, and 17. This is a compiler bug in the version you are using. Moan to CCS... :-(
You can (obviously), code round this pretty easily, with something like:
Code:

#byte CCPR1L=0x13
#byte CCP1CON=0x15

void my_set_pwm_duty(int16 val) {
    CCPR1L=val>>2;
    val=(val<<4) & 0x30;
    CCP1CON=(CCP1CON & 0xCF)|val;
}


This is similar to other reported problems with some chips/versions...

Best Wishes
Guest








PostPosted: Thu Dec 09, 2004 1:24 am     Reply with quote

Many, many thank�s for your help !!!

Skipper
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group