Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

how to display meesage to LCD using phone

Status
Not open for further replies.

crocklip

Junior Member level 1
Joined
Nov 23, 2005
Messages
18
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,568
16f877a mplab timer time

hi,

I am using a PIC 16f877a-
I am trying to find the period of a signal being input to an input pin. To do it I start the timer (TMR0) when the the input pin goes high for the first time. after 20 periods of the input signal I stop the timer. by doing this I can divide the value of the timer at this point by 20 and then multiply the result by the period of the timer. This should give me the period of the input signal... So my question is can the PIC handle the following code:

timer_time = (((0xFF)*(overflow_acc) + TMR0)*(1/0.000064));


signal_period = (timer_time/20);

where 0.000064 is the period of the timer(TMR0)

I'm using the HI-TECH C compiler.

Any help would be great,

Thanks
 

Re: Can a 16f877a do this?

Hi!
I think yes. But the best way to check this is to simulate the code in MPLAB. By the way why don't you use the capture compare module of the contrller. Simply save the values of the 20 pulses and add them to get the total time.
Regards.
 

Re: Can a 16f877a do this?

Hai,

Just check out the CCP option in PIC. This is the easiest way to find the time period between two signals. Try it

Regards
Gopi
 

Re: Can a 16f877a do this?

Hey,
I checked out the CCP module which supports what I want to do but theres something which doesnt let me use it:
there will be 6 different input signals in portB that I need to sample one after another but there are only two compare/capture pins on the PIC (CCP1, CCP2).

Anyway I tried to simulate the program using the above method but it doesnt seem to be able to manage that particular line.

Thanks for the help
 

Re: Can a 16f877a do this?

Hi!
I want to tell you something that will help you. If MPLAB is not simulating it, then there is a great chance that it will not work as it has already happened with me. Try breaking the equation into smaller equations and then add the results to get the result for the complete equation. Anyway try your luck.
Regards.
 

Can a 16f877a do this?

A few things I notice about your code. First, do you mean to use:

timer_time = (0x100 * overflow_acc + TMR0) * 0.000064;

Next, it appears that you are using a prescaler of 64 at 4 MHz clock. You'd be more accurate if you use a prescaler of 1 (because you don't know the value in the prescaler). Of course, you'll have to handle the overflow_acc 64 times more often.

Also, if timer_time is an integer and you multiply by 0.000064, as I suggest, you'll loose almost all of your precision. Ever thought of expressing the period in uS? If timer_time is a floating point value, this is not a problem.
 

Re: Can a 16f877a do this?

well, I used 0xFF because when this is multiplied by the overflow accumulator the result will be the actual amount of times the timer cycled. 0xFF being the maximum value the 8-bit timer can increment to before overflowing.
I would be more than happy to post/email the short program if it would help you help me!
Thanks so far
 

Can a 16f877a do this?

I guess I'm not understanding nature of your problem.

I'm assuming the following:

1. Your code compiles, but you get a strange result when you simulate.
2. When you are timing, everytime TMR0 overflows you increment overflow_acc through an interrupt or by polling TOIF or whatever.
3. The time it takes for TMR0 to increment by one is 0.000064 seconds (64 uS).

If this is the case then the period is

time (in timer increments) = overflow_acc*256 + TMR0
time (in seconds) = time (in timer increments) * 0.000064 seconds per increment
period = time (in seconds) / 20

You can do this in one line:

signal_period = (overflow_acc * 256 + TMR0) * 0.000064 / 20;

If signal_period is an integer, I am suggesting you keep signal_period in uS so you would use:

signal_period = (overflow_acc * 256 + TMR0) * 64 / 20;

Now, about 255 (0xFF) vs. 256 (0x100). TMR0 ranges from 0x00 to 0xFF. If you count the cycles it takes to overflow you get 0x100 (0xFF - 0x00 + 0x01). Suppose, for a second you have overflow_acc = 2 and TMR0 = 255. Using 255*overflow_acc + TMR0 you get 765. Now, lets increment one more time so that TMR0 overflows and we increment overflow_acc. Now we have overflow_acc = 3 and TMR0 = 0. Using 255*overflow_acc + TMR0 you get 765. Do you see a problem here?

Let me know if my assumptions are wrong.
 

Re: Can a 16f877a do this?

Jon,

You are spot on with your assumptions. I really see no reason why the program shouldn't simulate properly and its being frustrating me for too long. the program is to sample the frequency of a guitar string and to set one pin if its too high and another if its too low and both if its equal. I think I should just include the code in this post to make it easier for you. At some points I have commented out previous code that I was using prior to your suggestions so just ignore that stuff.
Hope this can help,
thanks

//Code to sample the input of a guitar string (E)
//whose signal is input to pin RB1
//if the frequency of the signal is too high then
//RB0 goes high. If to low the RB2 goes high.

#include <pic.h>
#include <htc.h>
#include <math.h>




#define TIMER_PERIOD 0.000064


#define E_STRING 110//frequency of E string

#define CENTER_COUNT 1/E_STRING


volatile unsigned int overflow_acc;


// The guitar note span
// # # # # # # # # # #
//EF G A BC D EF G A BC D E
//1 2 3 4 * 5 6
//
near char reload = 0;
/////////////// service routine for timer 0 interrupt ////////////////////////
void interrupt
timer0_isr(void)
{
if(reload == 0){
// effect a change on PORTB whenever our desired period is reached.
// Note this timing will contain a margin of error.
overflow_acc++;
// effect a change on PORTB
}
reload--;
T0IF = 0;
}
///////////////////////////////////////////////////////////////////////////////






//----------------------------------------------------------------------------
// Main Loop
//----------------------------------------------------------------------------

int main(void)

{
//------------------------------
// Initialize
//------------------------------
double timer_time;
int signal_period;
int all_timer;
int overflow;
unsigned int i;




TRISB = 2; // RB1 is input
// RB0 is ouput, High LED
// RB2 is ouput, Low LED
RB1 = 0; // no pullups active

T0CS = 0;
//PS2 = 1; // set prescaler to 1:64
//PS1 = 0; // ' ' ' ' ' ' ' ' ' ' '
//PS0 = 1; // ' ' ' ' ' ' ' ' ' ' '
//PSA = 0; //SET PRESCALER TO TMR0

TMR0IE = 1; // enable interrupt on timer overflow
GIE = 1; // global interrupt enable

while(1)
if(RB1)
{break;}


while(1)
{
overflow_acc = 0;
TMR0 = 0X00;
for (i=0;i<20;i++)//cycle through 20 periods
{ while(1)
if(!RB1)
{break;}
while(1)
if(RB1)
{break;}
}



signal_period = (overflow_acc * 256 + TMR0) * 64 / 20;
//timer_time = (((0xFF)*(overflow_acc) + TMR0)*(TIMER_PERIOD));
//
//
//overflow = ((0xFF)*(overflow_acc));
//all_timer = (overflow + TMR0);
//timer_time = ((all_timer)*(TIMER_PERIOD));

//signal_period = (timer_time/20);

if(signal_period <= CENTER_COUNT)
RB0 = 1;
if(signal_period >= CENTER_COUNT)
RB2 = 1;

}

}
 

Can a 16f877a do this?

Change

#define CENTER_COUNT 1/E_STRING

to

#define CENTER_COUNT 1000000/E_STRING

Then try it. Also, to help with accuracy, replace the

signal_period = ****

with

time_stop = TMR0;
signal_period = (overflow_acc * 256 + time_stop) * 64/20;

time_stop can be an unsigned byte.

For your application, you don't really need as much precision as signal_period will get you, but it'll probably work nonetheless.

Perhaps that will work
 

Re: Can a 16f877a do this?

originally I was getting the simulation output of RB2 to be high no matter what the input frequency. Now I am getting RB0 to be high no matter what. BTW should the 64us not be 1us for the timer period? (timer freq = 1MHZ).
anyway I am using PIC simulator IDE and maybe the problem lies with the simulator. I will go ahead and program the chip with what I have and see what happens. Thanks for all the help.
 

Can a 16f877a do this?

You can either use 1us or a prescaler of 64. The two are mutually exclusive so whatever you do, be consistent throughout the program.

I like your original code where you named the constants (TIMER_PERIOD) etc.

Step through (or break within) your simulation and try to make sense of what's going on here.

Good luck
 

Re: Can a 16f877a do this?

Hi,

I tried the code with the chip and hooked it up. This time however unlike the simulator, I got no output at all. If anyone can see any problem with the code I would be delighted to hear it.
Who was it who said "if the experiment works, then something went wrong"?!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top