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

Pwm with pulsin.c base
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

Pwm with pulsin.c base
PostPosted: Wed Feb 10, 2016 6:42 am     Reply with quote

Hello I need to read pulses in 4 pic entries modulate this signal and put it in other 4 outputs I managed to control the high pulse however not low, the pulses are of servo engine 1 to 2ms.The pulse down this very long over 60ms I need 20ms, the PWM works perfectly without pulsin.c code but it does not work but I need it to measure the pulse of time.


Code:

#include <16F877A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(crystal=20MHz)

#use rs232(BAUD=9600, UART1, ERRORS, BITS=8, PARITY=N) //ensure hardware UART used
//#include <lcd.c>
#include "pulsin.c"


int16 pulse0,pulse1,pulse2,pulse3;
int8 x;
int8 t=80; 

void pwm()
{
for(x=0; x<t;x++){
//x=x+1;
if(x>pulse0)
 {
  output_low(pin_c0);
 }
  if(x<pulse0)
 {
  output_high(pin_c0);
 }
 
 //**********************************
 if(x>pulse0)
 {
  output_low(pin_c0);
 }
  if(x<pulse0)
 {
  output_high(pin_c0);
 }

 //************************************
  if(x>pulse1)
 {
  output_low(pin_c1);
 }
  if(x<pulse1)
 {
  output_high(pin_c1);
 }

 //************************************
  if(x>pulse2)
 {
  output_low(pin_c2);
 }
  if(x<pulse2)
 {
  output_high(pin_c2);
 }

 //************************************
   if(x>pulse3)
 {
  output_low(pin_c3);
 }
  if(x<pulse3)
 {
  output_high(pin_c3);
 }

 //************************************
if(x>=t) // 20ms
{
x=0;//reset  each 20ms
}
}
}

//*******************************************
void main()
{
int16 result0,result1,result2,result3;

//lcd_init();
  // delay_ms(500);


   
   while(TRUE) 
  {
   pwm();

//******************input pulses**************************

   result0 = pulsin(PIN_B0, 1);
   pulse0 = result0*10/300 ; //10 original
   //**********************************************
   
   result1 = pulsin(PIN_B1, 1);
   pulse1 = result1* 10/300; //10 original
   //************************************************
   result2 = pulsin(PIN_B2, 1);
   pulse2 = result2*10/300 ; //10 original
   //************************************************
   result3 = pulsin(PIN_B3, 1);
   pulse3 = result3 * 10/300; //10 original
   //*************************************************

  //printf(lcd_putc,"\f%lu %u\n", pulse0,x);
  //delay_ms(20);
  }


}


Last edited by Laus on Wed Feb 10, 2016 7:58 am; edited 2 times in total
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 7:40 am     Reply with quote

you should post the 'pulsin.c' code or where you got it from. It's not on my version of PCM( 4.xxx).

Jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Feb 10, 2016 7:43 am     Reply with quote

1- format your code with the code button
2- list PULSIN.C as without it your code is NONSENSICAL
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 7:50 am     Reply with quote

Pulsin.c


Obtained here in the forum

http://www.ccsinfo.com/forum/viewtopic.php?t=42353&highlight=pulsin
Code:

//***********************************************************
#ifdef __PCB__
#error  Pulsin is not supported for the PCB compiler.
#endif
#ifdef __PCD__
#error  Pulsin is not supported for the PCD compiler.
#endif

#ifdef __PCM__
#define interrupt_enabled(x)  !!(*make8(x,1) & make8(x,0))
#endif
#ifdef __PCH__
#define interrupt_enabled(x)  !!(*(make8(x,1) | 0xF00) & make8(x,0))
#endif

#define BYTE_PTR(x) &(int8 *)(x)

// ASM definitions
#define W  0
#define F  1

// Status Register Bits
#define Z  2
#define C  0

#ifdef __PCM__
// Register addresses (16F)
#byte INDF   = 0x00
#byte STATUS = 0x03
#byte FSR    = 0x04
#endif

#ifdef __PCH__
// Register addresses (18F)
#byte INDF0  = 0xFEF
#byte STATUS = 0xFD8
#byte FSR0H  = 0xFEA
#byte FSR0L  = 0xFE9
#endif

//---------------------------------------
// #define PULSIN_MAX  60000

#ifdef PULSIN_MAX
  #if(PULSIN_MAX > 65535)
      #error PULSIN MAX is too High. Maximum value is 65535. 
  #endif
#endif

//---------------------------------------

#ifdef __PCM__
int16 pulsin(int8 ccs_pin, int8 state)
{
int8 io_port;
#endif

#ifdef __PCH__
int16 pulsin(int16 ccs_pin, int8 state)
{
int16 io_port;
#endif

int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int8 gie_enabled = FALSE;

int8 bitmask;
int8 flip;
int16 count;

// These variables are used in the ASM code
// and must be located in the same RAM bank.
#locate io_port = 0x30  // Can be 8 or 16 bits
#locate count   = 0x32  // 16 bits
#locate state   = 0x34
#locate bitmask = 0x35
#locate flip    = 0x36


if(interrupt_enabled(GLOBAL))
  {
   disable_interrupts(GLOBAL);
   gie_enabled = TRUE;
  }

// Get the I/O Port address and the bitmask from
// the CCS pin number value.
io_port = ccs_pin >> 3;

bitmask = bitmask_table[ccs_pin & 7];

// Set TRIS = input.
#ifdef __PCM__
*(io_port | 0x80) |= bitmask;  // For 16F PICs
#endif
#ifdef __PCH__
*(io_port + 0x12) |= bitmask; // For 18F PICs
#endif


#asm   
PULSINT:
#ifdef __PCM__
         movf    io_port, W      ; Get port
         movwf   FSR
#endif

#ifdef __PCH__
         movf    io_port, W      ; Get port lsb
         movwf   FSR0L
         movf    BYTE_PTR(io_port) +1, W   ; Get port msb
         movwf   FSR0H
#endif
         movf    bitmask,w

         clrf    flip            ; Preset state tracking
         btfss   state, 0        ; State tracking preset for flip
         movwf   flip            ; Set state to bit mask
   
         call    statecnt        ; Wait for idle state
         btfsc   STATUS, Z       ; If timeout then it's over
         goto    done

         call    statecnt        ; Wait for starting edge
         btfsc   STATUS, Z       ; If timeout then it's over
         goto    done
   
         call    statecnt        ; Do the count
         goto    done

//--------------------------------------------------
statecnt:
         movf    bitmask, W      ; Flip state each time through here
         xorwf   flip, F
#ifdef PULSIN_MAX
         movlw   ((-(PULSIN_MAX)) + 1)       ; Start counter -PULSIN_MAX + 1
         movwf   count
         movlw   (((-(PULSIN_MAX)) + 1) >> 8)
         movwf   BYTE_PTR(count) + 1
#else
         movlw    1
         movwf    count
         clrf     BYTE_PTR(count) + 1
#endif

statecntloop:                    ; Takes 10 usec
#ifdef __PCM__
         movf    INDF, W         ; 1 Read Port with INDF
#endif
#ifdef __PCH__
         movf    INDF0, W        ; 1 Read Port with INDF0
#endif
         andwf   bitmask, W      ; 1 Mask it with bitmask
         xorwf   flip, W         ; 1 Mix with desired state
         btfss   STATUS, Z       ; 2 / 1
#ifdef PULSIN_MAX
         goto    statecntexit    ; 0 / 2 No longer in state
#else
         return                  ; 0 / 2 No longer in state
#endif
         incf    count, F        ; 1 Increment counter
         btfsc   STATUS, Z       ; 1 / 2
         incfsz  BYTE_PTR(count) + 1, F   ; 1 / 2
         goto    statecntloop    ; 2 / 0
         return                  ; 0 / 2 Counter overflow
#ifdef PULSIN_MAX
statecntexit:
         movlw   PULSIN_MAX      ; Normalize count
         addwf   count, F
         movlw   PULSIN_MAX >> 8
         btfsc   STATUS, C
         addlw   1
         addwf   BYTE_PTR(count) + 1, F
         bcf     STATUS, Z       ; Indicate no overflow
         return
#endif
done:

#endasm

if(gie_enabled)
  {
   enable_interrupts(GLOBAL);
  }

return(count);
}
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 8:07 am     Reply with quote

Perfect ! Now we can help....

Knowing PCM created it is has to work.....

first start off with ONE servo,get it working..then 2,3,4
It's a LOT easier and 'proper technique' to start small, build on working code.

Jay
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Wed Feb 10, 2016 8:21 am     Reply with quote

by "servo engine" i believe you mean hobby style pulse width controlled servo right ?

PCM's program was created for impaired PICS that have no CCP capability
but the 877 DOES have the hardware.

have you read the CCP section of the
16f877 datasheet to see how it could help you?

what IS your project and what are you trying to control?
Your post is very hard to make sense of unless you explain what your project IS and what you are controlling..
add some DIMENSION please
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 8:46 am     Reply with quote

I _think_ he's trying to read 4 input signals ( 1-2ms) and then control 4 RC servos with the data..

It looks like he's bodged code from several sources....
I understand English isn't everyone's 1st language but we really need a better description of the project.

He should start with one input-> PIC-->one output

Jay
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 9:02 am     Reply with quote

ok I'll work the signal 1 radio control RC receiver, PPM signal and the pic increase or decrease the duration of the positive pulse, the only problem and that I'm not able to control the negative part of the pulse with the above code, not to use the CCP as are 4 different signals
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 9:09 am     Reply with quote

This part controls the negative pulse time should be in 20ms but this around 60ms.
If you use this code in alone I have a PPM signal 1 and 2ms 50Hz.

Code:
{
for(x=0; x<t;x++){
//x=x+1;
if(x>pulse0)
 {
  output_low(pin_c0);
 }
  if(x<pulse0)
 {
  output_high(pin_c0);
 }
 //************************************
if(x>=t) // 20ms 
{
x=0;//reset  each 20ms
}
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 9:36 am     Reply with quote

Take a deep breath, and step back.

What you currently have is never properly going to work.
Bits of code from various locations assembled without any understanding of what they do, and more importantly of how they will interact.
Big problem is that every single direction through a loop like this will differ slightly in time. So if you tweak everything to get your 20mSec, then you just change one thing (one of the time values), the timing will then be wrong....
The delay while the values are read, will also change according to the incoming pulses. and result in even more variation. This is why you are seeing the timing error for your 60mSec.

You need to be switching to actually using a hardware clock, and effectively multi-tasking. Use the hardware CCP's to generate the output pulses. I posted single pulse CCP code to generate a servo pulse only a few weeks ago, and for what you want (with the pulses sequential), this can very easily be modified to handle four pulses rather than one.
Then realise that 'pulsein', was published as a 'bodge' to allow a pulse width to be measured on a chip that did not have a CCP. To do the measurement without affecting the output pulse, I'd be suggesting you need to look at using the interrupt on change, on the four input bits (so feeding them to B4 to B7), and then recording the value from a single timer to measure the widths. The main loop can then sit and when these values have updated, calculate the new times, and feed these into the code for the outputs.
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 10:05 am     Reply with quote

The operation of the code was understood I use this PWM in several other codes, the part that is not mine and the pulsin.c .The intention was to replace a reading done by a adc, and a pot for the values returned by pulsin code and thus controlling the PWM. I posted here because after several attempts with other PWM until even with Timer use not got success the pulse of negative time ever and larger than expected with any implemented PWM
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 10:10 am     Reply with quote

And how sometimes the solution is simple and this is our view but we could not see by some oversight, asked for help here. But I see the PWM is really incompatible with the control made through the code pulsin.
Ttelmah



Joined: 11 Mar 2010
Posts: 19245

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 10:15 am     Reply with quote

No.

The point is that pulsin takes _time_, and this varies according to the pulse widths involved, and the phase relationship between the pulses being tested (given that you test multiple pulses in sequence).
Your PWM code won't maintain accurate gaps, if anything in the loop involved changes in time.
You need to generate the timing between the pulses here using a timer, so that it becomes independant of the other things happening.
Laus



Joined: 16 Jan 2016
Posts: 17
Location: Brazil

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 10:30 am     Reply with quote

The problem is that the pulsin disable the timer sometimes and this causes more errors in the PWM.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Wed Feb 10, 2016 11:21 am     Reply with quote

I'm just plain lost.

Maybe some pictures/diagrams/ASCIIart showing us what you are trying to achieve will help.
Then we can come up with alternative ways of doing the job in hand.

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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