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

using internal osc and outputting osc/4

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



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

using internal osc and outputting osc/4
PostPosted: Wed Apr 04, 2007 8:06 pm     Reply with quote

I'm using a 16f88 and the internal osc. My serial comms are very intermittent so I'm thinking the internal osc may be off a little. The data sheet says you can set it up so that the internal osc/4 is output on one of the osc pins. How do you set that up? I've tried
#include <16f88.h>
#fuses intrc_io,NOWDT,nolvp
#use delay(clock=8000000)

#include <16f88.h>
#fuses intrc,NOWDT,nolvp
#use delay(clock=8000000)

but I never get anything out of pins a6 or a7. is there something else I need to do?
Thanks
Ringo
_________________
Ringo Davis
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

PostPosted: Thu Apr 05, 2007 1:06 am     Reply with quote

INTRC allows Fosc/4 output on RA6. I tried it but is quite unstable even with good bypass caps on the 16F88 - on oscilloscope looks to be about 2% jitter. Measured frequency about 1.98MHz. This makes it marginal for RS232 I think, although I got consistent output at 9600 baud, even just sending A's.

See PCM Programmer's post on this problem:
http://www.ccsinfo.com/forum/viewtopic.php?t=28707&highlight=16f88+intrc
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Thu Apr 05, 2007 7:54 am     Reply with quote

The 628A is in the same package and it's spec says the internal osc is good to <1%. Is this believable? If so then that should fix my problem, I'll just drop in a different pic. Otherwise I'll need to add a crystal. I'm trying to avoid the crystal since it is about as big as the pic and makes the pcb bigger. I'm going for small on this one.
_________________
Ringo Davis
Rocket



Joined: 29 Aug 2005
Posts: 27

View user's profile Send private message

PostPosted: Thu Apr 05, 2007 2:39 pm     Reply with quote

Serial coms aka RS232 needs to be within 5%, and the 1.98Mhz is a 1% error, which is 'OK'. The problem might be on the other end, it would not be the first time the PC is at fault.

SHALOM!
_________________
J.I.L.
Kenny



Joined: 07 Sep 2003
Posts: 173
Location: Australia

View user's profile Send private message

PostPosted: Thu Apr 05, 2007 11:11 pm     Reply with quote

The internal precision 4MHz oscillator of the 16F628A does look to be more than accurate enough over the industrial temperature range.

My concern with the 16F88 was the instability of the 8MHz clock and the problems that several people have experienced with RS232.

Edited: found temperature spec., it was just above where I was looking!
Minimum -10%, maximum +10% for -40°C to +85°C range.
I measured the mean frequency at close to the 25°C used to set the calibration at the factory.

At least the error in the baud rate generator with 8MHz is only 0.16% at 9600 baud. Also the jitter in the 8MHz clock would be integrated to some extent by the baud rate generator frequency divider.

It's a combination of all these errors though that can make things marginal.

Good luck with the 16F628A!
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 7:36 pm     Reply with quote

I went to a 16f628a and the internal osc was still not good enough. The baud rate would go in and out. Sometimes it would print good stuff then garbage later, so I made a new board with a 20mhz crystal.
I'm using 3.249.

Here is the latest problem. This board takes 4 bytes pan,tilt,fire,and carriage return.

Pan and tilt are used to control servos and fire is a pwm value.

I can send 4 or 5 commands then the board just stops responding. I have an led lighting up when a cr is seen, and it goes off when any other char is seen. so if I send 3 number and a cr it goes off briefly then back on. When it stops working the led is off so it saw a char or 2 then quit seeing them. I also print out haw many chars it has seen since the last cr and that is getting printed in a timer 2 int, that keeps printing after the board stops responding. It acts like the serial int got turned off or something.

in my timer 2 int I set CTS low, turn off the serial ints, do my servo stuff and then turn the ints back on. I have tried commenting out the turning the serial ints off, but that did not help. I also commented out the servo stuff and it still did not help. Any ideas what could be going on?

Here is the entire code.




Code:


#include "16f628a.h"
#fuses hs,NOWDT,nolvp
#use delay(clock=20000000)
#define SERIAL_BUFFER_SIZE 5
int SERIAL_BUFFER[SERIAL_BUFFER_SIZE];
int *curPos;  // Current Serial Buffer Ptr Position
int curCnt=0;
unsigned int pan_value=127;
unsigned int tilt_value=127;
unsigned int fire_value=0;
int32 commandnum=0;

//make CTS high to receive commands
//make CTS low to inhibit commands
#define tilt        PIN_A0
#define pan         PIN_A1
#define rts         PIN_B0
#define Rx          PIN_B1
#define Tx          PIN_B2
#define fire_pin    PIN_B3
#define CTS         PIN_B4

#use rs232(baud=19200,xmit=TX,rcv=RX,bits=8,parity=N)

void ProcessCommands();
void UpdateServos();


void main(void)
{
    int i,temp;
    curPos = SERIAL_BUFFER;
    port_b_pullups(true);
    setup_ccp1(CCP_PWM);
    setup_timer_2(T2_DIV_BY_1,255,16);// every 4 ms
 
    enable_interrupts(INT_RDA);    // Serial Data Available IRQ
    enable_interrupts(INT_TIMER2); // Timer 2 Overflow
    enable_interrupts(GLOBAL); //
    output_low(pan);
    output_low(tilt);
    set_pwm1_duty(10);
    printf("Pan Tilt Fire Version 1.0\r\n");
    output_high(CTS);// enable commands to be sent

    for(i=0;i<5>5000)
        {
         print_counter=0;
            printf("Pan Tilt Fire curCnt= %d  commandnum=%ld\r\n",curCnt,commandnum);   
        }
   
   
}
//////////////////////////////////////////////////////////////////////////////
void UpdateServos()
{
    int x;
    if(pan_value>0)// value of 1-255 results in a pulse from .5 to 2.5ms
    {
        output_high(pan);
        delay_us(600);
        for(x=0;x<pan_value>0)
    {
        output_high(tilt);
        delay_us(600);
        for(x=0;x<tilt_value;x++)
        delay_us(6);
        output_low(tilt);
    }
    else
        output_low(tilt);

}


//////////////////////////////////////////////////////////////////////////////
void ProcessCommands()
{
    pan_value=Serial_buffer[0];
    tilt_value=Serial_buffer[1];
    fire_value=Serial_buffer[2];
    set_pwm1_duty(fire_value);
    printf("setting P=%u T=%u F=%u\r\n",pan_value,tilt_value,fire_value);
}




any help will be greatly appreciated.
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 7:44 pm     Reply with quote

You're enabling interrupts but I don't see any isr's.

Also, you should have ERRORS in your #use rs232() statement for
the hardware UART (You should do this in every program).
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 7:48 pm     Reply with quote

That is weird, it did not post all of my code.
lets try this again
Code:

#include "16f628a.h"
#fuses hs,NOWDT,nolvp
#use delay(clock=20000000)
#define SERIAL_BUFFER_SIZE 5
int SERIAL_BUFFER[SERIAL_BUFFER_SIZE];
int *curPos;  // Current Serial Buffer Ptr Position
int curCnt=0;
unsigned int pan_value=127;
unsigned int tilt_value=127;
unsigned int fire_value=0;
int32 commandnum=0;

//make CTS high to receive commands
//make CTS low to inhibit commands
#define tilt        PIN_A0
#define pan         PIN_A1
#define rts         PIN_B0
#define Rx          PIN_B1
#define Tx          PIN_B2
#define fire_pin    PIN_B3
#define CTS         PIN_B4

#use rs232(baud=115200,xmit=TX,rcv=RX,bits=8,parity=N)

void ProcessCommands();
void UpdateServos();


void main(void)
{
    int i,temp;
    curPos = SERIAL_BUFFER;
    port_b_pullups(true);
    setup_ccp1(CCP_PWM);
    setup_timer_2(T2_DIV_BY_1,255,16);// every 4 ms
 
    enable_interrupts(INT_RDA);    // Serial Data Available IRQ
    enable_interrupts(INT_TIMER2); // Timer 2 Overflow
    enable_interrupts(GLOBAL); //
    output_low(pan);
    output_low(tilt);
    set_pwm1_duty(10);
    printf("Pan Tilt Fire Version 1.0\r\n");
    output_high(CTS);// enable commands to be sent

    for(i=0;i<5;i++)
    {
    output_high(PIN_B6);
    delay_ms(500);
    output_low(PIN_B6);
    delay_ms(500);
    }
     output_high(Pin_b6);//turn on led
 
    while(1)
    {
    }
}


//////////////////////////////////////////////////////////////////////////////
#int_rda
void serial_int_routine()
{
    int temp;
    output_low(Pin_b6);//turn off led when a char comes in
    *curPos = getc();

    // Make sure we don't overrun the buffer:
    if (curCnt < SERIAL_BUFFER_SIZE)
    {
       // End of command, set flag to process the command:
       if (*curPos =='\r')
       {
          ProcessCommands();
            output_high(Pin_b6);//turn led back on when a complete packet is seen
          // Reset pointer to beginning of buffer:
          curPos = SERIAL_BUFFER;
          curCnt = 0;
          commandnum++;
       }
       else
       {
            // Increment buffer position:
            curPos++;
            curCnt++;
       }
     }
     else
     {
         curCnt = 0;
         curPos = SERIAL_BUFFER;
         printf("overrun\r\n");
     }
}

//////////////////////////////////////////////////////////////////////////////
#int_TIMER2
void TIMER2_isr() // every 4 ms
{
    static int32 servo_counter=0;
    static int32 print_counter=0;
    servo_counter++;
    print_counter++;
    //period is 4ms
    //should update servo every 20 ms
    if (servo_counter >=20)
    {
        output_low(CTS);// disable commands to be sent
        delay_ms(5);// just to make sure someone doesn't send a late command
        disable_interrupts(INT_RDA);
        UpdateServos();
        enable_interrupts(INT_RDA);
        output_high(CTS);// enable commands to be sent
        servo_counter = 0;
    }
    if(print_counter>5000)
        {
         print_counter=0;
            printf("Pan Tilt Fire curCnt= %d  commandnum=%ld\r\n",curCnt,commandnum);   
        }
   
   
}
//////////////////////////////////////////////////////////////////////////////
void UpdateServos()
{
    int x;
    if(pan_value>0)// value of 1-255 results in a pulse from .5 to 2.5ms
    {
        output_high(pan);
        delay_us(600);
        for(x=0;x<pan_value;x++)
        delay_us(6);
        output_low(pan);
    }
    else
        output_low(pan);


    if(tilt_value>0)
    {
        output_high(tilt);
        delay_us(600);
        for(x=0;x<tilt_value;x++)
        delay_us(6);
        output_low(tilt);
    }
    else
        output_low(tilt);

}


//////////////////////////////////////////////////////////////////////////////
void ProcessCommands()
{
    pan_value=Serial_buffer[0];
    tilt_value=Serial_buffer[1];
    fire_value=Serial_buffer[2];
    set_pwm1_duty(fire_value);
    printf("setting P=%u T=%u F=%u\r\n",pan_value,tilt_value,fire_value);
}





This is the last thing it printed, It jsut keeps printing the same thing after the lockup.
Pan Tilt Fire curCnt= 2 commandnum=10
_________________
Ringo Davis
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 7:58 pm     Reply with quote

Is there an example of how to use the ERRORS in the use232 statement? The manual is sparse in the description.
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 8:04 pm     Reply with quote

Add it, as shown in bold below:
Quote:
#use rs232(baud=19200,xmit=TX,rcv=RX,bits=8,parity=N, ERRORS)
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 8:13 pm     Reply with quote

I got that much, but then what do you do? How do you know if an error occurred?
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 8:15 pm     Reply with quote

If your program locked up before you added ERRORS and then after
you added it, it stopped locking up, then overrun errors were occuring.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 8:30 pm     Reply with quote

That definitely looks like it did it. What exactly do you mean by overrun errors and how do I avoid them? I was getting the problem while typing chars into hyper term, so nothing real fast. When It works I'll be sending data at a much faster rate from a c# program. I would have thought the CTS line would help with stuff like this. I'm using hw handshaking in both hyper term, and c#.
Ringo
_________________
Ringo Davis
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 16, 2007 8:43 pm     Reply with quote

You will get an overrun error if the 2-deep hardware receive fifo in
the PIC's UART fills up, and then a 3rd character is received, for which
there is no room left in the fifo.

This can happen if #int_rda interrupts are disabled for too long. This is
in fact happening in your program. You need to change the design of
the program so that you don't have to do this.
Ringo42



Joined: 07 May 2004
Posts: 263

View user's profile Send private message

PostPosted: Tue Apr 17, 2007 6:42 am     Reply with quote

The strange part is I was having the problem with the servo stuff and the int disabling stuff commented out, so the serial int was never getting turned off.
Kinda weird but now I know what to work on, Thanks.
Ringo
_________________
Ringo Davis
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