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

syncronization problem

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



Joined: 22 Nov 2003
Posts: 32

View user's profile Send private message

syncronization problem
PostPosted: Tue Aug 02, 2005 8:49 pm     Reply with quote

I have a circuit that uses a PIC1F688 using the internal 8Mhz oscillator. It has two 5Khz PWM inputs (RA4 and RA5). These inputs are independent and are either off or driven with a 25-75% duty cycle. The input PWM is to be mirrored out (RA2 and RC0) when no error condition is present. Two ADC inputs (RC2 and RC1) are are used to monitor current flow. There are two current SENSE signal outputs (RC4 and RC5) that are to be set when current is present on the ADC inputs. Also there is an ERROR signal output (RC3) that is to be set when an overcurrent condition has occurred.

I'm having trouble syncronizing everything that needs to be done. The ADC inputs need to read and tested at regular intervals syncronized with the PWM (or a timer when the PWM is not present) and the PWM needs to be mirrored. The only consistent time available is at the beginning and end of the PWM cycle when the output is either high (1-25%) or low (76-100%). Each about 50us or 100 clock cycles.

The code below my latest attempt at it. It only works in bursts suggesting that there is a timing problem.

Thanks in advance.

Bob

Code:

#CASE                                    // compiler is case sensitive
#include <16F688.h>                           // using the PIC16F688
#DEVICE ADC=8                              // using 8 bit ADC
#FUSES NOWDT, INTRC_IO, BROWNOUT, MCLR, NOCPD, NOPUT, NOIESO, NOFCMEN

#USE delay(clock=8000000)                     // internal clock at 8Mhz
#USE FAST_IO( A )                           // ports won't change
#USE FAST_IO( C )                           // so use fast access

#BYTE PORTA    = 0x105                        // direct port A access
#BYTE PORTC    = 0x107                        // direct port C access
#BIT  ERROR    = PORTC.3                     // direct crowbar error output
#BIT  SENSE_1    = PORTC.4                     // direct #1 sense output
#BIT  SENSE_2    = PORTC.5                     // direct #2 sense output
#BIT  IN_1       = PORTA.5                     // direct #1 pwm input
#BIT  IN_2       = PORTA.4                     // direct #2 pwm input
#BIT  OUT_1    = PORTA.2                     // direct #1 pwm output
#BIT  OUT_2    = PORTC.0                     // direct #2 pwm output

#define SENSE    2
#define CROWBAR 20

void main()
{
   static int index, reading, timer;
      
   set_tris_a( 0b00111000 );                  // setup port a
   set_tris_c( 0b00000110 );                  // setup port c
   OUT_1 = OUT_2 = FALSE;                     // no drive to start
   SENSE_1 = SENSE_2 = 0;                     // no current to start
   ERROR = 0;                              // no error to start
   setup_oscillator( OSC_8MHZ );               // use internal 8Mhz clock
   setup_adc_ports( sAN5 | sAN6 | VSS_VDD );      // setup ADC
   setup_adc( ADC_CLOCK_INTERNAL );            // using internal clock
   setup_comparator(NC_NC_NC_NC);               // no comparators
   setup_counters( RTCC_INTERNAL, RTCC_DIV_2 );   // 256us overflow
   setup_timer_1( T1_DISABLED );               // timer 1 not used
   set_adc_channel( 5 );                     // set initial channel
   delay_ms( 1000 );                        // wait for driver
   set_rtcc( 0 );                           // sync timer
   
   while( TRUE )
   {
      while( get_rtcc() < 200 )               // syncronize on timer
      {
         if( IN_1 == TRUE || IN_2 == TRUE )      // test PWM input   
         {
            break;                        // syncronize on PWM
         }
      }
      set_rtcc( 0 );                        // reset timer
      if( ERROR == FALSE )                  // start if no errors
      {
         if( IN_1 == TRUE ) OUT_1 = TRUE;      // turn on pwm outputs      
         if( IN_2 == TRUE ) OUT_2 = TRUE;
      }
      read_adc( ADC_START_ONLY );               // start adc reading
      while( get_rtcc() < 50 );               // wait for 25% duty
      reading = read_adc( ADC_READ_ONLY );      // finish adc reading
      while( get_rtcc() < 150 )               // watch pwm to 75%
      {
         if( ERROR == FALSE )               // stop when no errors            
         {
            if( OUT_1 != IN_1 ) OUT_1 = FALSE;   // turn off pwm outputs
            if( OUT_2 != IN_2 ) OUT_2 = FALSE;
         }
      }
      if( ERROR == FALSE )                  // stop when no errors               
      {
         if( OUT_1 == TRUE ) OUT_1 = FALSE;      // turn off pwm outputs
         if( OUT_2 == TRUE ) OUT_2 = FALSE;
      }      
      ERROR = (reading > CROWBAR);            // test reading for error
      if( index == 1 )                         // which index?
      {
         SENSE_1 = (reading > SENSE);         // set sense output
         set_adc_channel( 6 );               // set adc channel
         index = 0;                        // set index
      }
      else
      {
         SENSE_2 = (reading > SENSE);         // set sense output
         set_adc_channel( 5 );               // set adc channel
         index = 1;                        // set index
      }
   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 02, 2005 11:38 pm     Reply with quote

I didn't try to solve your overall problem. I just looked at things that seemed strange to me.

Here you're defining the port registers in RAM Bank 2:
Quote:
#BYTE PORTA = 0x105 // direct port A access
#BYTE PORTC = 0x107 // direct port C access

They are also available in Bank 0, and it would save a lot of
bank switching code if you put them there. Like this:
Code:
#BYTE PORTA    = 0x5                       
#BYTE PORTC    = 0x7 

I made that change and re-compiled your code. The ROM usage
went from 271 words down to 231. That's with PCM vs. 3.230.


There are three places where you've got code similar to this:
Quote:
ERROR = (reading > CROWBAR);

If you change it to look like this (in all three places) your ROM usage
goes down to 213 words.
Code:

if(reading > CROWBAR)
   ERROR = TRUE;
else
   ERROR = FALSE;   

So if part of your problem is caused by slow speed of execution,
doing these changes will help.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Wed Aug 03, 2005 10:17 am     Reply with quote

I was surprised when you said these compile differently.
Code:
ERROR = (reading > CROWBAR); 

Code:

if(reading > CROWBAR)
   ERROR = TRUE;
else
   ERROR = FALSE;   

In an older versions of the compiler (3.184) they compile the same. In 3.221 the if statement is optimized but the logical assignment is not. For the PIC18 series they are the same in both compilers versions.


Last edited by Neutone on Wed Aug 03, 2005 2:45 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 03, 2005 11:51 am     Reply with quote

This was compiled with PCM vs. 3.230. In the first method,
the compiler is putting the result of the expression into an
intermediate variable. This takes several extra lines of code.
The default optimization level was used. Changing it to #opt 11
or 9, or 5 has no effect.

Code:
0000 00482.. ERROR = (reading > CROWBAR); // test reading for error   
00AC 0823       00483 MOVF   23,W
00AD 3C14       00484 SUBLW  14
00AE 1C03       00485 BTFSS  03.0
00AF 28B2       00486 GOTO   0B2
00B0 3000       00487 MOVLW  00
00B1 28B3       00488 GOTO   0B3
00B2 3001       00489 MOVLW  01
00B3 00A1       00490 MOVWF  21
00B4 1821       00491 BTFSC  21.0
00B5 28B8       00492 GOTO   0B8
00B6 1187       00493 BCF    07.3
00B7 28B9       00494 GOTO   0B9
00B8 1587       00495 BSF    07.3


Code:
0000                00484 .................... if(reading > CROWBAR)   
00AC 0823       00485 MOVF   23,W
00AD 3C14       00486 SUBLW  14
00AE 1803       00487 BTFSC  03.0
00AF 28B2       00488 GOTO   0B2
0000                00489 ....................    ERROR = TRUE;   
00B0 1587       00490 BSF    07.3
0000                00491 .................... else   
00B1 28B3       00492 GOTO   0B3
0000                00493 ....................    ERROR = FALSE;     
00B2 1187       00494 BCF    07.3


Here is the same code compiled with PCM vs. 3.188.
It's much smaller.
Code:

0000 00506...ERROR = (reading > CROWBAR); // test reading for error   
00C8 0823       00507 MOVF   23,W
00C9 3C14       00508 SUBLW  14
00CA 1C03       00509 BTFSS  03.0
00CB 28CE       00510 GOTO   0CE
00CC 1187       00511 BCF    07.3
00CD 28CF       00512 GOTO   0CF
00CE 1587       00513 BSF    07.3
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