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 support@ccsinfo.com

Single output & pulse steering mode on PIC18F24k20

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



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

Single output & pulse steering mode on PIC18F24k20
PostPosted: Fri Dec 04, 2009 4:07 am     Reply with quote

I'm using the PIC18F24k20 with internal oscillator @ 1mhz

I wanted to use the "Single output: P1A, P1B, P1C and P1D controlled by steering (See Section 16.4.7 “Pulse Steering Mode”)
as listed in 16.0 ENHANCED CAPTURE/COMPARE/PWM (ECCP) MODULE

But I am having trouble enabling multiple outputs.
Actually I am having trouble enabling any other output than P1A.

I have the 4 outputs tied together with binary weighted resistors. Sort-of a crude DAC.
Without a load I would expect to see the combined output at Vdd.
Instead I see a voltage that looks like some of the outputs are low.

Thanks in advance.

Leef_me

Code:

#include <18F24K20.h>
#define P1A PIN_C2
#define P1B PIN_B2
#define P1C PIN_B1
#define P1D PIN_B4

void main()
{
   setup_timer_2(T2_DIV_BY_1,24,1);
   set_pwm1_duty(10);

// I originally tried this line, but I am somewhat confused by 'PWM_H_H'
//   setup_ccp1(CCP_PWM_H_H

   setup_ccp1(CCP_PWM     
                          | CCP_PULSE_STEERING_A
                          | CCP_PULSE_STEERING_B
                          | CCP_PULSE_STEERING_C
                          | CCP_PULSE_STEERING_D
                          );

// the above works, I get a signal on P1A, but if I add any of these code lines
// the combined output appears to be a voltage divider

            output_drive(P1B);

            bit_set(LDR_TRISB,2); //#define P1B PIN_B2

            output_drive(P1C);

            bit_set(LDR_TRISB,1); //#define P1C PIN_B1

            output_drive(P1D);

            bit_set(LDR_TRISB,4); //#define P1D PIN_B4

// at first these seem illogical to use, but I thought the steering bits
would override the data bit and the result would be setting the TRIS bity as output.

            output_low(P1B);

            output_low(P1C);

            output_low(P1D);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 1:10 pm     Reply with quote

1. Post a test program that compiles without errors. Show the #fuses
and #use delay() statements. If you have a while(1) statement at
the end or some other loop (to prevent the PIC from going to sleep
when it falls off the end of main), then post that.

2. Post your compiler version.
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 4:21 pm     Reply with quote

Hi PCM,
Sorry about that, I forgot the drill. Here is an updated listing w/all requested info.
Code:
//Compiler version 4.099


// Comment OUT the following "#define" line to allow STAND-ALONE device operation
#define ICD_EN // this allows the #device ICD=TRUE and #FUSES to be placed in the header file

//==========================================================================
// this section is normally stored in the project's *.h file


#include <18F24K20.h>

#ifdef ICD_EN
   #device ICD=TRUE
   #FUSES NODEBUG                  //No Debug mode for ICD
#endif





#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV18               
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODELAYINTOSC         

#use delay(clock=1000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=CONSOLE)

// the above section is normally stored in the project's *.h file
//==========================================================================


#define P1A PIN_C2
#define P1B PIN_B2
#define P1C PIN_B1
#define P1D PIN_B4
#byte LDR_TRISA = 0xF92

#byte LDR_TRISB = 0xF93

#byte LDR_TRISC = 0xF94

void main()
{
   setup_timer_2(T2_DIV_BY_1,24,1);
   set_pwm1_duty(10);

// I originally tried this line, but I am somewhat confused by 'PWM_H_H'
//   setup_ccp1(CCP_PWM_H_H

   setup_ccp1(CCP_PWM     
                          | CCP_PULSE_STEERING_A
                          | CCP_PULSE_STEERING_B
                          | CCP_PULSE_STEERING_C
                          | CCP_PULSE_STEERING_D
                          );


// the above works, I get a signal on P1A,

while(1);


//but if I add any of these code lines
// the combined output appears to be a voltage divider

            output_drive(P1B);

            bit_set(LDR_TRISB,2); //#define P1B PIN_B2

            output_drive(P1C);

            bit_set(LDR_TRISB,1); //#define P1C PIN_B1

            output_drive(P1D);

            bit_set(LDR_TRISB,4); //#define P1D PIN_B4

while(1);


// at first these seem illogical to use, but I thought the steering bits
//would override the data bit and the result would be setting the TRIS bit as output.

            output_low(P1B);

            output_low(P1C);

            output_low(P1D);
while(1);

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 5:27 pm     Reply with quote

It's a little difficult for me to understand how to fix your problem
because I don't understand exactly what you want.

From my point of view, I would make an absolutely stripped down
program, with minimal fuses, no TRIS settings, or output drive and
all this stuff. I would remove all external circuits, such as your
resistor network.

Then I would try to set it up for PWM single channel, with the same
signal being output to all 4 pins, or to smaller combinations of the pins.

If I did that, then I would pronounce that I had success. I would
understand how to make it do pulse steering.

But I'm not sure that's what you want. So it's difficult for me to proceed.
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 6:04 pm     Reply with quote

I want the code needed to use the "Single output: P1A, P1B, P1C and P1D controlled by steering (See Section 16.4.7 “Pulse Steering Mode”)
as listed in 16.0 ENHANCED CAPTURE/COMPARE/PWM (ECCP) MODULE

As I understand it, it is possible to have a single PWM output and then use steering to send that output to any one of four outputs.

For example Ttelmah's 3rd post, and PCM programmer's 2nd post and PCM's last post in this thread Arrow
http://www.ccsinfo.com/forum/viewtopic.php?p=82431


Question Question Hey! Wait a minute. There seems to be a different number of parameters !?!?! Arrow Or'ing doesn't count as another parameter !

PCM wrote
Code:

setup_ccp1(CCP_PWM, CCP_PWM_H_H |CCP_PULSE_STEERING_B);


Leef_me wrote
Code:

   setup_ccp1(CCP_PWM     
                          | CCP_PULSE_STEERING_A
                          | CCP_PULSE_STEERING_B
                          | CCP_PULSE_STEERING_C
                          | CCP_PULSE_STEERING_D
                          );
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Fri Dec 04, 2009 10:29 pm     Reply with quote

Bump, no improvement Sad
Anyone else have corrections for Pic18F24K20 single PWM steered to multiple outputs ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Dec 05, 2009 12:14 am     Reply with quote

I think there are some bugs in the PWM steering code in vs. 4.099
(and they're also in vs 4.101). The test program shown below should
fix those bugs. I've created a new routine called set_pwm_steering().

Basically, I've separated setting the PWM and setting the steering into
two different functions now. That way I can fix the steering code
problems by writing my own routine to do it. It uses the same PWM
steering constants that are in the 18F24K20.H file, so it's easy to use.

I don't have this PIC so I can't test it in hardware, but I think it should
work.
Code:

#include <18F24K20.h>
#fuses INTRC_IO, NOWDT, PUT, NOLVP, NOPBADEN
#use delay(clock=8000000) 

// These are the PWM output pins for the 18F24K20.
#define P1A PIN_C2
#define P1B PIN_B2
#define P1C PIN_B1
#define P1D PIN_B4
 
#byte PSTRCON = 0xFB9

// Call this routine to set the PWM steering.  You can OR
// together the PWM steering constants from the PIC's
// header file.
void set_pulse_steering(int32 steering)
{
int8 temp;

temp = make8(steering, 3);  // Get high byte only

PSTRCON = temp;   // Setup PWM steering register

// Set the TRIS to outputs for the enabled steering pins.
// Also set the selected pins to a low level.
if(temp & 1)
   output_low(P1A);
if(temp & 2)
   output_low(P1B);
if(temp & 4)
   output_low(P1C);
if(temp & 8)
   output_low(P1D);
}


//===========================================
void main()
{
setup_timer_2(T2_DIV_BY_16, 124, 1);  // Set 1000 Hz PWM freq

set_pwm1_duty(31);  // Set PWM for 25% duty cycle

// Set up PWM so that all four outputs are active high.
setup_ccp1(CCP_PWM_H_H);

// Enable PWM output on all four pins.
set_pulse_steering( CCP_PULSE_STEERING_A |
                    CCP_PULSE_STEERING_B |
                    CCP_PULSE_STEERING_C |
                    CCP_PULSE_STEERING_D);

while(1);
}
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Sat Dec 05, 2009 3:01 am     Reply with quote

Thanks PCM,
I'll have to try out your code.

>>I think there are some bugs in the PWM steering code in vs. 4.099

edit: BTW, how did you know about the above bug ?
What led you to come across this and find out the details ?


Yes, after a few hours I found that "PSTRCON @ 0xFB9" is never mentioned in the LST file.

as a result instead of getting for example:
STRB: Steering Enable bit B
this ---> 1 = P1B pin has the PWM waveform with polarity control from CPxM<1:0>

I was getting
this ---> 0 = P1B pin is assigned to port pin



>>It uses the same PWM steering constants that are in the 18F24K20.H file, so it's easy to use.

great idea!


IMHO as a purist, it might be more "proper" to write
output_drive(P1A);

instead of
output_low(P1A);
Leef_me



Joined: 14 Mar 2006
Posts: 45

View user's profile Send private message

PostPosted: Mon Dec 07, 2009 6:34 pm     Reply with quote

from: CCS Support
>The problem you reported has been fixed and will be in the next compiler release.
(12/07/2009 1:05 PM pacific)

>> Leef_me wrote:
>>
>> There appears to be a problem with 'setup_ccp1' single PWM output pulse steering
>> The steering register is not updated by the instruction.
>> setup_ccp1(CCP_PWM
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 08, 2009 6:19 pm     Reply with quote

Quote:

BTW, how did you know about the above bug ?
What led you to come across this and find out the details ?

I compiled a test program and looked at the .LST file. With vs. 4.099,
I noticed the code looked incorrect at the end of the routine. It should
load a value into the PSTRCON register. Instead, it's doing something
strange with a banked register.

I remembered that the 16F690 also had PWM pulse steering. So I
compiled a test program for it and looked at the code, as shown below.
Notice that they set two bank select bits and write to a register at address
0x19D. So it became clear that CCS had just copied the 16F code into
the 18F compiler for this feature. They didn't change the address of
the PSTRCON register to the correct 18F address.

Also, they are supposed to set the TRIS to be outputs for all the pins
that are set for PWM steering. They don't do that. They only do it
for the first one.

After I saw all of this, then I posted "I think there are some bugs".

18F14K20 With vs. 4.099:
Code:
.................... // Steer the PWM output to all four P1x pins. 
.................... setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_A 
....................                        | CCP_PULSE_STEERING_B 
....................                        | CCP_PULSE_STEERING_C 
....................                        | CCP_PULSE_STEERING_D ); 
0042:  BCF    TRISC.2
0044:  BCF    LATC.2
0046:  MOVLW  0C
0048:  MOVWF  CCP1CON
004A:  CLRF   PWM1CON
004C:  CLRF   ECCP1AS
004E:  MOVLW  0F       // *** Bug
0050:  MOVLB  1        // *** Bug
0052:  MOVWF  x9D      // *** Bug


16F690 with vs. 4.099:
Code:

....................  setup_ccp1(CCP_PWM       | CCP_PULSE_STEERING_A 
....................                           | CCP_PULSE_STEERING_B 
....................                           | CCP_PULSE_STEERING_C 
....................                           | CCP_PULSE_STEERING_D 
....................                           ); 
0026:  BSF    03.5
0027:  BCF    07.5
0028:  BCF    03.5
0029:  BCF    07.5
002A:  BSF    03.5
002B:  BCF    09.6
002C:  MOVLW  0C
002D:  BCF    03.5
002E:  MOVWF  17
002F:  CLRF   1C
0030:  CLRF   1D
0031:  MOVLW  0F

// This is the 16F690 code that writes to its PSTRCON register.
// The address is 0x19D.   
0032:  BSF    03.5
0033:  BSF    03.6
0034:  MOVWF  1D     



18F14K20 with vs. 4.102:
Code:
.................... setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_A 
....................                        | CCP_PULSE_STEERING_B 
....................                        | CCP_PULSE_STEERING_C 
....................                        | CCP_PULSE_STEERING_D ); 
0042:  BCF    TRISC.2
0044:  BCF    LATC.2
0046:  BCF    F96.6  // Set TRISE.6 = 0   *** Possible new bug
0048:  MOVLW  0C
004A:  MOVWF  CCP1CON
004C:  CLRF   PWM1CON
004E:  CLRF   ECCP1AS
0050:  MOVLW  0F           // *** Fixed
0052:  MOVWF  PSTRCON      // *** Fixed

They still don't set the TRIS for all the Pulse Steering pins. You have
to set it manually with your own code.
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