• AVR Freaks

AnsweredHot!PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM1

Author
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
2019/04/08 07:14:33 (permalink)
0

PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM1


Hi.
I'm working on a RS485 slave board and I am having problems when trying to write the higher register of PWM3 and CCP1/PWM1 of a PIC18F26K40. Both PWMs are set to 10KHz fixed frequency, duty cycle value is from 0 to 100 (%), and in the test below I'm trying to set the PWMs to 75% duty cycle.
I'm using MPLAB X v3.60 and XC8 v1.42.

I have this multidimensional array on a header file:
uint16_t slave_template [14][13] = 
{
{ ':' , 'S' , 1 , ',' , ON_OFF , PWM3 , ';' , &RA5PPS , 0x07 , &LATA , (1 << 5) , &PWM3DCH , &PWM3DCL },
{ ':' , 'S' , 2 , ',' , ON_OFF , PWM3 , ';' , &RA7PPS , 0x07 , &LATA , (1 << 7) , &PWM3DCH , &PWM3DCL },
{ ':' , 'S' , 3 , ',' , ON_OFF , PWM3 , ';' , &RA6PPS , 0x07 , &LATA , (1 << 6) , &PWM3DCH , &PWM3DCL },
{ ':' , 'S' , 4 , ',' , ON_OFF , PWM1 , ';' , &RC0PPS , 0x05 , &LATC , (1 << 0) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 5 , ',' , ON_OFF , PWM1 , ';' , &RC1PPS , 0x05 , &LATC , (1 << 1) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 6 , ',' , ON_OFF , PWM1 , ';' , &RC2PPS , 0x05 , &LATC , (1 << 2) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 7 , ',' , ON_OFF , PWM1 , ';' , &RC3PPS , 0x05 , &LATC , (1 << 3) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 8 , ',' , ON_OFF , PWM1 , ';' , &RC7PPS , 0x05 , &LATC , (1 << 7) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 9 , ',' , ON_OFF , PWM1 , ';' , &RB5PPS , 0x05 , &LATB , (1 << 5) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 10 , ',' , ON_OFF , PWM1 , ';' , &RB4PPS , 0x05 , &LATB , (1 << 4) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 11 , ',' , ON_OFF , PWM1 , ';' , &RB3PPS , 0x05 , &LATB , (1 << 3) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 12 , ',' , ON_OFF , PWM1 , ';' , &RB2PPS , 0x05 , &LATB , (1 << 2) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 13 , ',' , ON_OFF , PWM1 , ';' , &RB1PPS , 0x05 , &LATB , (1 << 1) , &CCPR1H , &CCPR1L },
{ ':' , 'S' , 14 , ',' , ON_OFF , PWM1 , ';' , &RB0PPS , 0x05 , &LATB , (1 << 0) , &CCPR1H , &CCPR1L }
};

 
'S' = output
 
Dividing my function in 3 parts, I have an example of the problem:
 
uint16_t *PPS_address;
uint16_t *DUTY_HIGH_address;
uint16_t *DUTY_LOW_address;

//1 AND 2...THESE WORK:
//SETTING PWM3 OUTPUT ON PIN RA5 AND WRITING TO PWM3DCL REGISTER VIA POINTER
PPS_address = (uint16_t*) slave_template[0][7]; //slave_template[0][7] = &RA5PPS
*PPS_address = slave_template[0][8]; //RA5PPS = 0x07 via pointer

DUTY_LOW_address = (uint16_t*) slave_template[0][12]; //slave_template[0][12] = &PWM3DCL
*DUTY_LOW_address = 0xC0; //PWM3DCL = 0xC0 via pointer

//I USE, OR 3A ALONE, OR 3B ALONE, AT THIS POINT...
//3A...THIS DOESN'T WORK:
//WRITING TO PWM3DCH VIA POINTER
DUTY_HIGH_address = (uint16_t*) slave_template[0][11]; //slave_template[0][11] = &PWM3DCH
*DUTY_HIGH_address = 0x12; //PWM3DCH = 0x12 via pointer

//3B...THIS WORK:
PWM3DCH = 0x12; //PWM3DCH = 0x12 writing the register directly


I am monitoring RA5PPS, PWM3DCH and PWM3DCL registers by sending them via serial (and checking on screen) their values after my function is called. Step 1 and 2 are working correctly, and when I use or 3A alone, or 3B alone, in both cases the values observed are RA5PPS = 0x07, PWM3DCH = 0x12 and PWM3DCL = 0xC0. The difference is that if I use 3B the output gives me a 75% PWM at RA5, and if I use 3A the RA5 pin remain constamtly in '0'.
PutByte485(RA5PPS);
PutByte485(PWM3DCH);
PutByte485(PWM3DCL);


The same behavior occurs to CCP1/PWM1, writing CCPR1L via pointer works, but if I write CCPR1H via pointer the same constant '0' output occurs, and if I write CCPR1H directly via its register the output gives me a 75% PWM at 10KHz.

Also, I'm using a file called powerup.as in my project. Without this file included as source file, the initialization of the multidimensional array does not work, all indexes are read as 0 if I do not include it in the project. I got this file on this post: https://www.microchip.com/forums/m969418.aspx

I'm not figuring out what I'm doing wrong or how to solve this, could somebody help me?
Thanks in advance.
Regards.
#1
davekw7x
Entropy++
  • Total Posts : 1716
  • Reward points : 0
  • Joined: 2012/01/16 12:01:07
  • Location: Left Coast, USA
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 07:30:46 (permalink) ☼ Best Answerby seccoxiru 2019/04/08 09:20:26
+2 (2)
seccoxiru

DUTY_HIGH_address = (uint16_t*) slave_template[0][11]; //slave_template[0][11] = &PWM3DCH




 But, from pic18f26k40.h in your compilers include directory:
extern volatile unsigned char           PWM3DCH             @ 0xFA4;

 
Bottom line.  Look at all of the variables that hold your SFR addresses.  Declare them as (unsigned char *) or (uint8_t *) and use thye proper cast in the assignments.
 
[Edit]
Even though this can work (tested with a little toy project on my PIC18F27K40), it is, in general, not a Good Idea to cast a 16 bit integer as a pointer (and vice versa).  If your application actually requires a 2-D array to parse something, maybe it's time to re-think.  Using an array of structs (with each member having appropriate type), as suggested by pcbbc in the next post would be vastly preferable. And predictable. And portable.
[/Edit]
 
Regards,

Dave
post edited by davekw7x - 2019/04/08 09:11:05

Sometimes I just can't help myself...
#2
pcbbc
Super Member
  • Total Posts : 900
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 07:37:36 (permalink) ☄ Helpfulby seccoxiru 2019/04/08 10:25:47
+4 (4)
For heavens sake man, define a structure!
And declare it const so it can be kept in ROM (unless your code is modifing it somewhere).
#3
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 09:27:57 (permalink)
+1 (1)
davekw7x
seccoxiru

DUTY_HIGH_address = (uint16_t*) slave_template[0][11]; //slave_template[0][11] = &PWM3DCH




 But, from pic18f26k40.h in your compilers include directory:
extern volatile unsigned char           PWM3DCH             @ 0xFA4;

 
Bottom line.  Look at all of the variables that hold your SFR addresses.  Declare them as (unsigned char *) or (uint8_t *) and use thye proper cast in the assignments.
 
[Edit]
Even though this can work (tested with a little toy project on my PIC18F27K40), it is, in general, not a Good Idea to cast a 16 bit integer as a pointer (and vice versa).  If your application actually requires a 2-D array to parse something, maybe it's time to re-think.  Using an array of structs (with each member having appropriate type), as suggested by pcbbc in the next post would be vastly preferable. And predictable. And portable.
[/Edit]
 
Regards,

Dave


Yes, that solved. Thanks very much. Just changed pointers and casts to uint8 and it worked... I think I confused the size of the register with the address size of the register.
Another Question: if I was using a PIC32 the pointers and casts would be uint32_t type? Is there any way I can use exactly the same code for 8-bit and 32-bit PICs? 
#4
davekw7x
Entropy++
  • Total Posts : 1716
  • Reward points : 0
  • Joined: 2012/01/16 12:01:07
  • Location: Left Coast, USA
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 09:39:42 (permalink)
+2 (2)
seccoxiru
davekw7x
[Edit]
Even though this can work (tested with a little toy project on my PIC18F27K40), it is, in general, not a Good Idea to cast a 16 bit integer as a pointer (and vice versa).  If your application actually requires a 2-D array to parse something, maybe it's time to re-think.  Using an array of structs (with each member having appropriate type), as suggested by pcbbc in the next post would be vastly preferable. And predictable. And portable.
[/Edit]
 

Another Question: if I was using a PIC32 the pointers and casts would be uint32_t type? Is there any way I can use exactly the same code for 8-bit and 32-bit PICs? 

Well, you could test it.
 
I still don't think it's a Good Idea, in general, to convert integers (of any size) to pointers to anything (and vice versa), even if it seems to work when you test it.  But that's just me;  I'm funny that way
 
Regards,

Dave
 
post edited by davekw7x - 2019/04/08 09:47:14

Sometimes I just can't help myself...
#5
pcbbc
Super Member
  • Total Posts : 900
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 09:51:27 (permalink) ☄ Helpfulby seccoxiru 2019/04/08 10:09:18
+2 (2)
Not exactly the same, no.  Or at least not without being even more wasteful of memory that you are currently.
Possibly with some #if / #ifdef conditional compilation.  I expect lots of the registers have different names as well (I'm not at all familiar with PIC32).
 
But start by defining a structure for your existing data.  A lot of your casting issues will go away.
 
THis should get you started:
typedef struct {
    char c1;
    char c2;
    uint8_t index;
    char c3;
    uint8_t onoff;
    uint8_t pwm;
    char c4;
    volatile uint8_t* p_pps_reg;
    uint8_t pps_val;
    volatile uint8_t* p_lat_reg;
    uint8_t lat_bit;
    volatile uint8_t* p_pwmhi_reg;
    volatile uint8_t* p_pwmlo_reg;
} TEMPLATE;

const TEMPLATE slave_template[] = {
    { ':' , 'S' , 1 , ',' , ON_OFF , PWM3 , ';' , &RA5PPS , 0x07 , &LATA , (1 << 5) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 2 , ',' , ON_OFF , PWM3 , ';' , &RA7PPS , 0x07 , &LATA , (1 << 7) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 3 , ',' , ON_OFF , PWM3 , ';' , &RA6PPS , 0x07 , &LATA , (1 << 6) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 4 , ',' , ON_OFF , PWM1 , ';' , &RC0PPS , 0x05 , &LATC , (1 << 0) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 5 , ',' , ON_OFF , PWM1 , ';' , &RC1PPS , 0x05 , &LATC , (1 << 1) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 6 , ',' , ON_OFF , PWM1 , ';' , &RC2PPS , 0x05 , &LATC , (1 << 2) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 7 , ',' , ON_OFF , PWM1 , ';' , &RC3PPS , 0x05 , &LATC , (1 << 3) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 8 , ',' , ON_OFF , PWM1 , ';' , &RC7PPS , 0x05 , &LATC , (1 << 7) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 9 , ',' , ON_OFF , PWM1 , ';' , &RB5PPS , 0x05 , &LATB , (1 << 5) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 10 , ',' , ON_OFF , PWM1 , ';' , &RB4PPS , 0x05 , &LATB , (1 << 4) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 11 , ',' , ON_OFF , PWM1 , ';' , &RB3PPS , 0x05 , &LATB , (1 << 3) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 12 , ',' , ON_OFF , PWM1 , ';' , &RB2PPS , 0x05 , &LATB , (1 << 2) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 13 , ',' , ON_OFF , PWM1 , ';' , &RB1PPS , 0x05 , &LATB , (1 << 1) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 14 , ',' , ON_OFF , PWM1 , ';' , &RB0PPS , 0x05 , &LATB , (1 << 0) , &CCPR1H , &CCPR1L }    
};

#6
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 10:25:15 (permalink)
0
pcbbc
Not exactly the same, no.  Or at least not without being even more wasteful of memory that you are currently.
Possibly with some #if / #ifdef conditional compilation.  I expect lots of the registers have different names as well (I'm not at all familiar with PIC32).
 
But start by defining a structure for your existing data.  A lot of your casting issues will go away.
 
THis should get you started:
typedef struct {
    char c1;
    char c2;
    uint8_t index;
    char c3;
    uint8_t onoff;
    uint8_t pwm;
    char c4;
    volatile uint8_t* p_pps_reg;
    uint8_t pps_val;
    volatile uint8_t* p_lat_reg;
    uint8_t lat_bit;
    volatile uint8_t* p_pwmhi_reg;
    volatile uint8_t* p_pwmlo_reg;
} TEMPLATE;

const TEMPLATE slave_template[] = {
    { ':' , 'S' , 1 , ',' , ON_OFF , PWM3 , ';' , &RA5PPS , 0x07 , &LATA , (1 << 5) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 2 , ',' , ON_OFF , PWM3 , ';' , &RA7PPS , 0x07 , &LATA , (1 << 7) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 3 , ',' , ON_OFF , PWM3 , ';' , &RA6PPS , 0x07 , &LATA , (1 << 6) , &PWM3DCH , &PWM3DCL },
    { ':' , 'S' , 4 , ',' , ON_OFF , PWM1 , ';' , &RC0PPS , 0x05 , &LATC , (1 << 0) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 5 , ',' , ON_OFF , PWM1 , ';' , &RC1PPS , 0x05 , &LATC , (1 << 1) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 6 , ',' , ON_OFF , PWM1 , ';' , &RC2PPS , 0x05 , &LATC , (1 << 2) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 7 , ',' , ON_OFF , PWM1 , ';' , &RC3PPS , 0x05 , &LATC , (1 << 3) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 8 , ',' , ON_OFF , PWM1 , ';' , &RC7PPS , 0x05 , &LATC , (1 << 7) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 9 , ',' , ON_OFF , PWM1 , ';' , &RB5PPS , 0x05 , &LATB , (1 << 5) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 10 , ',' , ON_OFF , PWM1 , ';' , &RB4PPS , 0x05 , &LATB , (1 << 4) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 11 , ',' , ON_OFF , PWM1 , ';' , &RB3PPS , 0x05 , &LATB , (1 << 3) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 12 , ',' , ON_OFF , PWM1 , ';' , &RB2PPS , 0x05 , &LATB , (1 << 2) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 13 , ',' , ON_OFF , PWM1 , ';' , &RB1PPS , 0x05 , &LATB , (1 << 1) , &CCPR1H , &CCPR1L },
    { ':' , 'S' , 14 , ',' , ON_OFF , PWM1 , ';' , &RB0PPS , 0x05 , &LATB , (1 << 0) , &CCPR1H , &CCPR1L }    
};





I think this will be very helpful for me, but I'm not so familiar with pointers, your example is a new for me.
Considering your example, how do I set a value to a pps's and to pwm's hi and lo in code?
 
EDIT:
Ok, I made it work with your example, thanks again.
 
post edited by seccoxiru - 2019/04/08 10:46:16
#7
pcbbc
Super Member
  • Total Posts : 900
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 10:42:42 (permalink) ☄ Helpfulby seccoxiru 2019/04/08 10:46:40
+1 (1)
Much like you are currently.
But you can just use the pointers in the structure directly rather than having to cast back from uint16_t all the time:
*slave_template[n].p_pwmlo_reg = 0xC0; //PWM3DCL = 0xC0 via pointer
*slave_template[n].p_pwmhi_reg = 0x12; //PWM3DCH = 0x12 via pointer
#8
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 10:47:46 (permalink)
0
pcbbc
Much like you are currently.
But you can just use the pointers in the structure directly rather than having to cast back from uint16_t all the time:
*slave_template[n].p_pwmlo_reg = 0xC0; //PWM3DCL = 0xC0 via pointer
*slave_template[n].p_pwmhi_reg = 0x12; //PWM3DCH = 0x12 via pointer


Ok. Thanks again pcbbc.
The problem was solved and the code was optimized.
#9
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 10:54:58 (permalink)
0
pcbbc
Much like you are currently.
But you can just use the pointers in the structure directly rather than having to cast back from uint16_t all the time:
*slave_template[n].p_pwmlo_reg = 0xC0; //PWM3DCL = 0xC0 via pointer
*slave_template[n].p_pwmhi_reg = 0x12; //PWM3DCH = 0x12 via pointer


Another question to finish:
 
I would like to ask if I can use the same code as I'm currently using, shown below, for 8 and 32 bit PICs:
*slave_template[i].p_pps_reg = template_escrava[i].pps_val;
 
*slave_template[i].p_pwm_hi_reg = duty << 6;
*slave_template[i].p_pwm_lo_reg = duty >> 2;

 
On the typedef I would use volatile uint8_t* reg; for 8-bit PICs, and I would use volatile uint32_t* reg; for 32-bit PICs (I use PIC32MX in some projects). Would that work?
 
[EDIT] The problem is that on 8 bit PICs we use 2 registers, and on PIC32 we have a single register to set PWM duty cycle, correct?
 
Regards
post edited by seccoxiru - 2019/04/08 10:56:22
#10
pcbbc
Super Member
  • Total Posts : 900
  • Reward points : 0
  • Joined: 2014/03/27 07:04:41
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 11:34:46 (permalink) ☄ Helpfulby seccoxiru 2019/04/08 11:47:34
+1 (1)
Something like that, but how big is the duty cycle reg on PIC32? If it is 32 bits then correct.
Which means it is not so easy. You will need some conditional compilation to have different pointer types.

Another option is, for PWM3DCL/H at least, these are at consecutive memory locations on PIC18. So you could code a single pointer and then access that byte and the byte immediately after:
typedef struct {
....
volatile uint8_t* p_pwm_reg;
} TEMPLATE;

slave_template[n].p_pwm_reg[0] = duty << 6;
slave_template[n].p_pwm_reg[1] = duty >> 2;


Or even, if write order of the bytes is not important, leave it up to the compiler to write both bytes:
typedef struct {
....
volatile uint16_t* p_pwm_reg;
} TEMPLATE;

*slave_template[n].p_pwm_reg = duty << 6;


But as I said, I am not an expert on PIC32. And I think you are just touching on the problems of making a single library/project that will compile for both platforms. It is hard enough for two 8 bit devices from the same or similar families.
#11
seccoxiru
Starting Member
  • Total Posts : 80
  • Reward points : 0
  • Joined: 2011/10/27 13:42:59
  • Location: 0
  • Status: offline
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 11:54:43 (permalink)
0
pcbbc
Something like that, but how big is the duty cycle reg on PIC32? If it is 32 bits then correct.
Which means it is not so easy. You will need some conditional compilation to have different pointer types.

Another option is, for PWM3DCL/H at least, these are at consecutive memory locations on PIC18. So you could code a single pointer and then access that byte and the byte immediately after:
typedef struct {
....
volatile uint8_t* p_pwm_reg;
} TEMPLATE;

slave_template[n].p_pwm_reg[0] = duty << 6;
slave_template[n].p_pwm_reg[1] = duty >> 2;


Or even, if write order of the bytes is not important, leave it up to the compiler to write both bytes:
typedef struct {
....
volatile uint16_t* p_pwm_reg;
} TEMPLATE;

*slave_template[n].p_pwm_reg = duty << 6;


But as I said, I am not an expert on PIC32. And I think you are just touching on the problems of making a single library/project that will compile for both platforms. It is hard enough for two 8 bit devices from the same or similar families.

PIC32MX PWM function of Output Control (OC module) uses a 32-bit register, like the datasheets shows.
And yes, I will use pre-processor #ifdef, that's a good ideia, something like:
#ifdef PIC_8_BITS
 
    *slave_template[i].p_pps_reg = slave_template[i].pps_val;
    *slave_template[i].p_pwm_hi_reg = duty << 6;
    *slave_template[i].p_pwm_lo_reg = duty >> 2;
#endif

#ifdef PIC_32_BITS
    //code
#endif

 
Do you suggest any more optimization? 
Regards
 
 
post edited by seccoxiru - 2019/04/08 11:55:45

Attached Image(s)

#12
qhb
Superb Member
  • Total Posts : 9954
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: online
Re: PIC18F26K40 - Fail when using pointer to write the higher register of PWM3 or CCP1/PWM 2019/04/08 13:50:11 (permalink)
0
seccoxiru
...
[EDIT] The problem is that on 8 bit PICs we use 2 registers, and on PIC32 we have a single register to set PWM duty cycle, correct?
 

Of course, you could just let the compiler do all the work for you.
On most PIC18F chips, and recent PIC16F1xxx and PIC16F1xxxx chips, 16 bit registers like this are stored at adjacent addresses, and the PIC header file declares a 16 bit version of the register.
From pic18f26k40.h
// Register: PWM3DC
#define PWM3DC PWM3DC
extern volatile unsigned short          PWM3DC              __at(0xFA3);
#ifndef _LIB_BUILD
asm("PWM3DC equ 0FA3h");
#endif

So, your C code can just write it as a single value in both PIC18 and PIC32.
That will make your 8 bit code a lot more readable too.
 
post edited by qhb - 2019/04/08 13:51:33
#13
Jump to:
© 2019 APG vNext Commercial Version 4.5