|
|
View previous topic :: View next topic |
Author |
Message |
zachavm
Joined: 23 Mar 2006 Posts: 9
|
Problems Capturing a pulse's frequency. |
Posted: Fri Mar 23, 2007 12:30 pm |
|
|
I'm doing a senior project where that is a DC motor control. Basicly, we are using a speed sensor to read in a speed and then control the input to it to adjust the power accordingly. The speed input is accomplished through reading the frequency of a square wave sent to the pic. Hence, I'm using timer1 in conjunction with CCP1 and it's capture capability.
Currently, I'm trying to get the speed sensor to work and I'm having some problems. In this code, there are a couple of things happening (button inputs, LCD outputs, and use of CCP1 for capturing), but the focus should be on timer1 and CCP1. I've highlighted these sections in the code.
I've spent some time outputting different variables to the LCD and I think I've narrowed the problem down to timer1. Basicly, when I output the value of CCP_1 to the LCD, it always remains the same (65536, the maximum cnt for the timer). I've also been able to determine that the timer1 overflow interrupt is never happening. I don't know what's causing this, but I'm pretty sure that timer1 isn't counting, and I don't know why. I've been using examples, and I can't figure out why this code isn't working? Any suggestions?
Code: | #include <16F876.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>
#include <stdlib.h>
// Global Variables
int i;
int16 speed = 50;
char mystr[10];
int overflow_cnt;
unsigned int32 end_time = 0, start_time = 0;
int32 pulse_ticks;
int32 actual_speed;
int32 cnt = 0;
int b1 = 0;
int b2 = 0;
int screenChanged = 1;
//sends a data byte to the LCD
void send_data(char e)
{
output_bit(PIN_C4, 1); //RS is set high so that the LCD is in Data Mode
output_B(e);
delay_us (20); //Delays for one microsecond
output_bit(PIN_C5, 1);
delay_us (20); //Delays for one microsecond to give the LCD time to read the data
output_bit(PIN_C5, 0); //enable is low. brought high to put on data
delay_us (20);
}
//sends a command to the LCD
void send_command(char f)
{
output_bit(PIN_C4, 0); //RS is set low so that the LCD is in Command Mode
output_B(f); //turns on display and adds cursor, underline, and cursor blink
delay_us (20);
output_bit(PIN_C5, 1); //trows enable low to send command to LCD
delay_us (20); //Delays for one microsecond to give the LCD time to read the data
output_bit(PIN_C5, 0); //enable is brought back to high
delay_us (20);
}
/********************************************
#int_TIMER1
TIMER1_isr() //interupt for timer1 overflow
{
++overflow_cnt; //increments when there is an overflow of timer 1
}
#int_CCP1
CCP1_isr() //interupt for CCP1 activation
{
end_time = CCP_1;
pulse_ticks = (end_time + ((overflow_cnt * 0x10000) - start_time));
actual_speed = (int32)((float)(60 * 50000000) / (float)(pulse_ticks * 1024));
start_time = end_time;
overflow_cnt = 0;
}
******************************************/
void main()
{
//initiates the LCD
delay_ms(500);
output_bit(PIN_C5, 0); //enable is low. brought high to put on data
send_command(0x0C);
send_command(0x38);
send_command(0x01);
//activate and setup LCD
delay_ms (100);
//send to LCD "Hello World"
send_data('W');
send_data('e');
send_data('l');
send_data('c');
send_data('o');
send_data('m');
send_data('e');
delay_ms(2000); //2 second delay
send_command(0x01); //clears the screen
delay_ms(5);
/*****************************************
//initialization of timer1 and CCP1
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_CCP1);
enable_interrupts(global);
******************************************/
while(1)
{
//checks to see if button 1 is pressed (speed up)
if(!input(PIN_C6) && b1 == 1)
{
if (speed <2000> 50)
speed -= 50;
b2 = 0;
screenChanged = 1;
}
if(input(PIN_C7))
b2 = 1;
//makes sure the screen get's refreshed if no button is pushed
cnt++;
if(cnt > 100000)
screenChanged = 1;
//outputs the speed to the LCD
if (screenChanged == 1)
{
send_command(0x01); //clears the display
delay_ms(5);
sprintf(mystr, "%lu", speed); //converts the int to a character string
i = 0; //loop that writes the number to the LCD
while(mystr[i] != NULL)
{
send_data(mystr[i]);
i++;
}
send_data('R');
send_data('P');
send_data('M');
send_command(0xC0); //shift writing position to second line
sprintf(mystr, "%lu", actual_speed); //converts the int to a character string
i = 0; //loop that writes the number to the LCD
while(mystr[i] != NULL)
{
send_data(mystr[i]);
i++;
}
send_data('R');
send_data('P');
send_data('M');
screenChanged = 0;
}
} //end while
} // end main
|
Last edited by zachavm on Fri Mar 23, 2007 12:40 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
zachavm
Joined: 23 Mar 2006 Posts: 9
|
|
Posted: Fri Mar 23, 2007 12:49 pm |
|
|
Well, I've figured out part the big part of the problem almost right after I posted this (I had been working on this for the last day). If you look at my timer1 setup, I've got it using an external timer rather then an internal one (D'oh). Anyway, I'm now working out the bugs on that. |
|
|
zachavm
Joined: 23 Mar 2006 Posts: 9
|
|
Posted: Mon Mar 26, 2007 11:08 pm |
|
|
Thanks guys, this worked like a charm. We've now got it up and running. I appreciate the help. |
|
|
|
|
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
|