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

Timer0 Problem

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



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

Timer0 Problem
PostPosted: Sun Nov 23, 2014 2:29 am     Reply with quote

Hi. Can someone please tell me what is the wrong with the code???
Code:
#include <16f877a.h>
#include <stdlib.h> // atoi

#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)

char data[2]={0,0};
unsigned int i=0,a=0,P_W=20;



#int_TIMER0             
void  hundred_micro() // 0.1 mili
{
   if (i<P_W)    output_high(Pin_D1);
   if (i>P_W)    output_low(Pin_D1);
   i++;
   if (i>=201)          i=0; 
   set_timer0(6);
}

void main ()
{
set_tris_d(0x00);    // Port D output
output_d(0x00);      // Clear Port D

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
set_timer0(6);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);

printf("\fReady\n\r");

while (TRUE)
{
      if (kbhit())
      { 
          for (a=0;a<2;a++)          data[a]=getc();
          P_W=atoi(data);
          if (P_W>20) P_W=20;
          if (P_W<1) P_W=0;
          printf("\PULSE TIME=%f ms   i=%u \n\r",P_W*0.1,i);
                       
      }
           
}
}


Timer is not working cause "i" stays in 0. I change the pic the same... i loaded a simple blinking led file , working good.
So what is the problem!!!! Mad
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sun Nov 23, 2014 7:09 am     Reply with quote

what causes a change in the value of "data" ?

if you are going to use set_tris() then use FASTIO first.



Code:

if (i<P_W)    output_high(Pin_D1);
else    output_low(Pin_D1);


lastly this :
since P_W is set to zero on every pass ,before the following is evaluated
what does THIS really do ??

Code:

 if (P_W>20) P_W=20;
          if (P_W<1) P_W=0;


as far as i can see, i would EXPECT the performance you are seeing
as this is JUST what your program commands.
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Sun Nov 23, 2014 7:35 am     Reply with quote

Thanks for replay.
P_w is the data I am sending from pc in ascii. By atoi I am converting it to int. It has to be between 0 and 20.
I is set zero every 200.
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sun Nov 23, 2014 9:07 am     Reply with quote

Code:

data I am sending from pc


NOT in the code you posted though
it is a STATIC value AS shown.

show me the line of code where you think you are receiving the new value .....
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Sun Nov 23, 2014 9:31 am     Reply with quote

 I didn't understand you...
By getc () I am getting the new data. There is no static value.
Code:

if (kbhit())       {            for (a=0;a<2;a++)          data[a]=getc();           P_W=atoi(data);           if (P_W>20) P_W=20;           if (P_W<1) P_W=0;           printf("\PULSE TIME=%f ms   i=%u \n\r",P_W*0.1,i);                               } 
asmboy



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

View user's profile Send private message AIM Address

PostPosted: Sun Nov 23, 2014 9:41 am     Reply with quote

from the ccs manual re ATOI()
Quote:

Syntax:
ivalue = atoi(string)
or
lvalue = atol(string)
or
i32value = atoi32(string)
Parameters: string is a pointer to a null terminated string of characters.


after reading the above - think about the implications to data[2]
BADCODE #1:
you enter your handler when the FIRST character is received but then try to get TWO characters before another char can arrive ....

you logic is very faulty in the time domain, and i have no idea what you send from the PC
BAD CODE #2 - format of received data

for instance suppose you want to set
P_W="15"
what do you send ??"15"<cr>
how many chars is that?

how about for "7"

where is your nul char terminator?
how do you differentiate between one and two digits?

is the light coming on for you yet ??

your thoughts?


Last edited by asmboy on Sun Nov 23, 2014 9:46 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Sun Nov 23, 2014 9:46 am     Reply with quote

Are two incoming text characters a string?. A string _needs_ a null terminator. atol, won't work properly without this.
kbhit means _one_ character is waiting. You then read two. This will mean this part of the code will hang.
How will the code handle anything but numbers?. Error handling may be needed....

Your array needs to be larger. Then you should add characters to this, till a line feed is seen, and then add the null terminator instead of this. Then call atol.

As some more comments, when you set timer0 to 6, it has already counted to probably about 12.... Get rid of this and just let the timer free run. You are not going to get 0.1mSec by updating it. Instead you make the time less accurate. If you want 0.1mSec, then use timer2.

There is a big problem in trying to print 'i' it is updating 10000* per second. It is liable to change during the actual printout. Result 'garbage'. Take a copy and print this. If it was larger than an int8, then you'd have to either disable interrupts while doing the copy, or perform a loop till the copy was correct. The value will mean nothing though.

Do you realise how much time is involved in this interrupt?. You are executing it every 500 instructions. The save/restore, and maths, probably adds to about 90 instructions. Result nearly 20% of the entire processor time is being spent just handling this. Why not just use the hardware PWM - that is what it is for.....

Code:

#include <16f877a.h>

#fuses hs,nowrt,nowdt,nodebug,brownout,nolvp,nocpd,put,noprotect
#use delay (clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8, parity=N, errors)

#include <stdlib.h> // atoi - only include things _after_ the processor is
//setup - otherwise functions using I/O and delays won't work....

unsigned int i=0,P_W=20;

#INT_TIMER2             
void  hundred_micro() // 0.1 mili
{
   if (i<P_W)   
      output_high(Pin_D1);
   else   
      output_low(Pin_D1);
   if (++i > 200)
      i=0;
}

void main ()
{
    int8 chr;
    int8 ctr=0;
    int8 local_i;
    char data[8]; //Keep variables _local_ unless they need to be global.
    //set_tris_d(0x00);    // pointless - doing the output below sets TRIS
    output_d(0x00);      // Clear Port D

    setup_timer_2(T2_DIV_BY_4, 124,1); //Gives OSC/(4*4*125) = 10000
    enable_interrupts(int_timer2);
    enable_interrupts(GLOBAL);

    printf("\fReady\n\r");

    while (TRUE)
    {
      if (kbhit())
      {
          chr=getc();
          if (chr=='\n') //line feed
          {
              //Only do this when line feed is seen
              data[ctr]='\0'; //null terminate string
              ctr=0;
              P_W=atoi(data); //Now atoi can work
              if (P_W>20)
                  P_W=20;
              //if (P_W<1) P_W=0; //pointless P_W is unsigned
              //If it is <1, it _is_ 0....
              local_i=i;
              printf("\PULSE TIME=%3.1w ms i=%u\n\r",P_W,local_i);
          }
          else
          {
              if (isdigit(chr))
              { //Ignore characters that are not numbers
                 data[ctr++]=chr;     
                 if (ctr>7)
                     ctr=7; //ensure text cannot go beyond storage area. 
              }
          }   
      }
   }
}
Ruby



Joined: 04 Jul 2014
Posts: 44

View user's profile Send private message

PostPosted: Sun Nov 23, 2014 10:04 pm     Reply with quote

Thank you very much you all specially Ttelmah.
I am sending the data through docklight program for now so I know how many characters I am sending. Although I am sending the data through docklight , do I still need to send a null terminator?
The reason I wanted to read "i" was to see if timer was working.
And finally I didn't use pwm cause I need to control 4 escs with pulses in 50hz or 400hz as I posted before in another forum.
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