View previous topic :: View next topic |
Author |
Message |
wind88
Joined: 29 Dec 2010 Posts: 37
|
PIC16f877A and timer0 |
Posted: Wed Dec 29, 2010 9:07 am |
|
|
I am using pic16f877a and timer0 to control the output to servo motor from ldr.
Code: | #include <16F877A.h>
#device adc=8
#include <math.h>
#include <stdlib.h>
#use delay(clock=4000000)
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOCPD //No EE protection
#FUSES NOPUT //No Power Up Timer
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit ADFM_BIT = 0x9F.7
#define A0 PIN_a0
#define A1 PIN_a2
#define C1 PIN_C2
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
void isr(VOID)
{
if(INT_TIMER0) { // TIMER0 Interrupt Flag
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(C1); // Turn off RC1
}
if (pulse_top == top_value) {
output_high(C1); // Turn On RC2
}
set_timer0(48) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main(void)
{
unsigned char ldr_left;
unsigned char ldr_right;
int ldr_diff;
/* Initial Port Used */
setup_adc_ports(ALL_ANALOG); // SETTING ADC CHANNEL // A0 A1 A2 A3 A5 E0 E1 E2 Ref=Vdd
setup_adc(ADC_CLOCK_DIV_2);
output_C (0x00);
/* Init Servo Pulse */
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
/* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
set_timer0(0) ;
while(1)
/* Read the ADC here */
set_adc_channel(0);
while ( input(A0) ) {
delay_ms( 400 );
ldr_left=read_adc();
set_adc_channel(1);
while ( input(A1) ) {
delay_ms( 400 );
ldr_right=read_adc();
/* Get the different */
ldr_diff=ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
top_value = MAX_VALUE; // Stop the Servo Motor
} else {
if (ldr_diff > THRESHOLD_VALUE) {
top_value = CCW_ROTATION; // Counterclockwise Rotation
} else {
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}
}
|
This is the code that I have. I already try to search the code in this forum and correct the mistake that I made before. But the code is not functioning in my circuit.
Port AN0 and AN1 is the input for the ldr.
Port RC1 is the output to the servo motor. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Wed Dec 29, 2010 10:52 am |
|
|
Without looking very hard:
Nowhere are you enabling the timer0 interrupt.
Nowhere are you telling the compiler that you 'isr' is for the timer0 interrupt.
If input(PIN_A0), and input(PIN_A2) both are false, the code will drop off the end.
Nowhere are you specifying the oscillator for your clock (XT? if you are using a crystal).
Your first 'while' statement will continuously execute the next line, selecting the adc channel, and never proceed to the latter code....
It is not going to work...
Learn to make your code 'tidy' - indent, and some of these faults will become 'self showing'...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Thu Dec 30, 2010 1:31 pm |
|
|
thanx you
I manage to change the code and the error that you told me.
Code: |
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit ADFM_BIT = 0x9F.7
#define A0 PIN_a0
#define A1 PIN_a2
#define C1 PIN_C2
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;
#int_TIMER0
void TIMER0_isr(void)
{
if(INT_TIMER0) { // TIMER0 Interrupt Flag
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(C1); // Turn off RC1
}
if (pulse_top == top_value) {
output_high(C1); // Turn On RC2
}
set_timer0(48) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main()
{
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
/* Init Servo Pulse */
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
/* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
set_timer0(206) ;
while(1)
/* Read the ADC here */
set_adc_channel(0);
if ( input(A0) ) {
delay_ms( 400 );
ldr_left=read_adc();
set_adc_channel(1);
if ( input(A1) ) {
delay_ms( 400 );
ldr_right=read_adc();
{
/* Get the different */
ldr_diff=ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
top_value = MAX_VALUE; // Stop the Servo Motor
} else {
if (ldr_diff > THRESHOLD_VALUE) {
top_value = CCW_ROTATION; // Counterclockwise Rotation
} else {
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19368
|
|
Posted: Thu Dec 30, 2010 4:34 pm |
|
|
So, you have a 4MHz crystal attached?.
Is 'HS' the right oscillator for this?.
You have not corrected the while statement.
Code: |
while(1)
statement()
code
|
executes 'statement' continuously, and will _never_ get to 'code'....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Thu Dec 30, 2010 10:36 pm |
|
|
Code: |
#include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit ADFM_BIT = 0x9F.7
#define A0 PIN_a0
#define A1 PIN_a2
#define B1 PIN_B1
#define ADFM = 0; //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;
#int_TIMER0
void TIMER0_isr(void)
{
if(INT_TIMER0) { // TIMER0 Interrupt Flag
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RC1
}
if (pulse_top == top_value) {
output_high(B1); // Turn On RC2
}
set_timer0(206) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
/* Init Servo Pulse */
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
/* Init TIMER0: Period: Fosc/4 x Prescaler x TMR0*/
set_timer0(206) ; //interrupt every 0.1ms
while(1){
/* Read the ADC here */
if ( input(A0) ) {
set_adc_channel(0);
delay_ms( 400 );
ldr_left=read_adc();
if ( input(A1) ) {
set_adc_channel(1);
delay_ms( 400 );
ldr_right=read_adc();
{
/* Get the different */
ldr_diff=ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE)) {
top_value = MAX_VALUE; // Stop the Servo Motor
} else {
if (ldr_diff > THRESHOLD_VALUE) {
top_value = CCW_ROTATION; // Counterclockwise Rotation
} else {
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}
}
}
}
|
This is the code with a { after the while, is this correct? |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Fri Dec 31, 2010 2:35 am |
|
|
Btw, do I need to initialize port A and C first?
How do I initialize to the value that I want? Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Fri Dec 31, 2010 9:47 am |
|
|
Ttelmah wrote: | So, you have a 4MHz crystal attached?.
Is 'HS' the right oscillator for this?.
You have not corrected the while statement.
Code: |
while(1)
statement()
code
|
executes 'statement' continuously, and will _never_ get to 'code'....
Best Wishes |
regarding the amendment of the code.is it still ok?as i stil get condition is always true in the warning bar.
i really in this help urgently :(
thanx a lot |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Dec 31, 2010 10:27 am |
|
|
Here is a quick look at an attempt to 'clean up' your code. It makes it easier to read and easier to see problems.
Code: | void main()
{
setup_adc_ports(NO_ANALOGS); // Why would you setup NO analogs if you're going to be reading analogs?
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// Init Servo Pulse
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
// Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
set_timer0(206) ; //interrupt every 0.1ms
// No ADC Clock?
while(true)
{
// Read the ADC here
if ( input(A0) )
{
set_adc_channel(0);
delay_ms( 400 ); // I forget what the delay time required is, but 400mS sounds too long.
ldr_left=read_adc();
}
if ( input(A1) )
{
set_adc_channel(1);
delay_ms( 400 );
ldr_right=read_adc();
}
// Get the different
ldr_diff = ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
{
top_value = MAX_VALUE; // Stop the Servo Motor
}
else
{
if (ldr_diff > THRESHOLD_VALUE)
{
top_value = CCW_ROTATION; // Counterclockwise Rotation
}
else
{
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}
|
Read up on how to configure and read ADC values. There's got to be plenty of threads with the details.
You change back and forth on pins and clock fuse settings between your posted code.
What specific problems are you having? Won't compile? Run time results not what expected? |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Fri Dec 31, 2010 11:40 am |
|
|
Quote: | #include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#bit ADFM_BIT = 0x9F.7
#define A0 PIN_a0
#define A1 PIN_a2
#define B1 PIN_B1
#define ADFM = 0; //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned int8 ldr_left;
unsigned int8 ldr_right;
unsigned int ldr_diff;
#int_TIMER0
static void TIMER0_isr(void)
{
if(INT_TIMER0)// TIMER0 Interrupt Flag
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RB1
}
else if (pulse_top == top_value) {
output_high(B1); // Turn On RB1
}
set_timer0(206) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main()
{
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// Init Servo Pulse
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
// Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
set_timer0(206) ; //interrupt every 0.1ms
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
while(true)
{
// Read the ADC here
if ( input(A0) )
{
set_adc_channel(0);
delay_us( 0.5 );
ldr_left=read_adc();
}
if ( input(A1) )
{
set_adc_channel(1);
delay_us( 0.5 );
ldr_right=read_adc();
}
// Get the different
ldr_diff = ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
{
top_value = MAX_VALUE; // Stop the Servo Motor
}
else
{
if (ldr_diff > THRESHOLD_VALUE)
{
top_value = CCW_ROTATION; // Counterclockwise Rotation
}
else
{
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
}
|
thanx for replying,
my problems
one of the line in red have a warning that say the condition is always true :(
besides this,the code is not functioning.i m not sure if there is anything wrong from the code
for the TOSC herehttp://pic-c.ccsinfo.com/forum/viewtopic.php?t=44181&highlight=adc
the delay should be 500ns |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Dec 31, 2010 12:15 pm |
|
|
You don't need to check for the interrupt bit in the ISR. That bit is what triggers the ISR in the first place. So, of course, it will always be true.
You don't need to clear the interrupt flag in the ISR, the compiler handles that with the ISR call.
Code: | #int_TIMER0
void TIMER0_isr(void)
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
// MAX_VALUE=200 turn off the pulse
if (pulse_max >= MAX_VALUE)
{
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RC1
}
if (pulse_top == top_value)
{
output_high(B1); // Turn On RC2
}
set_timer0(206) ; // Initial Value for 0.1ms Interrupt
} |
I would suggest getting parts of your code working and then combine the working parts. Do you have any output you could use for debugging, like an LCD or an LED? |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Fri Dec 31, 2010 12:38 pm |
|
|
Yup. I do have.
A servo so that it could rotate left or right. |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Dec 31, 2010 1:17 pm |
|
|
I would start from the very beginning with a new set of code. The goal is to build up the code piece by piece, checking each addition along the way. And you can use the servos to verify your code is working along the way.
So, the first step would be to write two functions, one to pulse left and one to pulse right. Make them pulse different distances or times, so you can ensure that right is actually right and left is actually left.
Write those functions and put them in the main() while(true) loop like this:
Code: |
while(true)
{
pulse_left();
delay_ms(500);
pulse_right();
delay_ms(500);
}
|
Once that is done and you've confirmed that everything is working you can build and test the next section of code, maybe the ISR. |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Fri Dec 31, 2010 9:58 pm |
|
|
Code: |
#include <pic.h> // this sample code is using 16F877A !!
// configuration
//==========================================================================
__CONFIG ( 0x3F32 ); //configuration for the microcontroller
// define
//==========================================================================
#define servo RB1
#define MHZ *1000L /* number of kHz in a MHz */
#define KHZ *1 /* number of kHz in a kHz */
// Value x must not more that 255
#define DelayUs(x) { unsigned char _dcnt; \
_dcnt = (((x)*(20MHZ))/(24MHZ))|1; \
while(--_dcnt != 0) \
continue; \
_dcnt = (((x)* (20MHZ))/(24MHZ))|1; \
while(--_dcnt != 0) \
continue; }
// function (every function must have a function prototype)
//==========================================================================
void DelayMs(unsigned char y); // Value y must not more that 255
// delay ms
// main function (main fucntion of the program)
//==========================================================================
void main(void)
{
unsigned int i,a;
//set IO port for servo pin
TRISB = 0b00000001; //servo motor is RB1
PORTB = 0b00000000; //clear port B
//servo will loop infinity
while(1) //from one position to another position
{
//*******************************************************
//
//Delay determine the servo motors position
//Try change the value for different position
//
//Value in DelayUs and DelayMs function must not more than 255
//Otherwise the timing will not accurate!!
//
//******************************************************
for(i=0;i<50;i++) //continues pulse for 50 times
{
servo=1; //set servo pin high
DelayUs(250);
DelayUs(250);
DelayUs(200); //delay 250+250+200= 700us = 0.7ms
//These delay only valid using 20MHz!
servo=0; //set servo pin low
DelayMs(19); //remain --> 20ms-0.7ms=19.3ms
DelayUs(250);
DelayUs(50); //19ms+0.250ms+0.050ms=19.3ms
//These delay only valid using 20MHz!
}
// _ _ _
// | | | | | |
// | | | | | | ~~50 times
// | |_________________| |________________| |____________________
// 0.7ms 19ms 0.7ms 19ms 0.7ms 19ms
// | |
// |<-------20ms------>|
for(i=0;i<50;i++) //continues pulse for 50 times
{
servo=1; //set servo pin high
DelayMs(2); //delay 2ms
//These delay only valid using 20MHz!
servo=0; //set servo pin low
DelayMs(18); //delay 18ms
//These delay only valid using 20MHz!
}
// ___ ___ ___
// | | | | | |
// | | | | | | ~~50 times
// | |_______________| |_______________| |____________________
// 2ms 18ms 2ms 18ms 2ms 18ms
// | |
// |<-------20ms------>|
}
}
//subroutine
//============================================================================
void DelayMs(unsigned char y)
{
unsigned char i;
do {
i = 4;
do {
DelayUs(250);
} while(--i);
} while(--y);
}
|
This is the code that was supply by the manufacturer to control the servo motor. This code is working with my servo. It can turn left and right. |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Sat Jan 01, 2011 9:01 am |
|
|
Code: |
#include <16F877A.h>
#device adc=8
#use delay(clock=4000000)
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#define MAX_VALUE 200
#define CCW_ROTATION MAX_VALUE - 20
#define CW_ROTATION MAX_VALUE - 10
#define STOP_ROTATION MAX_VALUE
#define THRESHOLD_VALUE 50
#define A0 PIN_a0
#define A1 PIN_a1
#define B1 PIN_B1
#define ADFM = 0; //1 for ADC result to be right-justified, 0 for left-justified
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value = 0;
unsigned char ldr_left;
unsigned char ldr_right;
int8 ldr_diff;
static void interrupt_isr(void)
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
if(INT_TIMER0)// TIMER0 Interrupt Flag
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RB1
}
if (pulse_top == top_value) {
output_high(B1); // Turn On RB1
}
set_timer0(206) ; // Initial Value for 0.1ms Interrupt
clear_interrupt(int_timer0); // Clear TIMER0 interrupt flag
}
}
void main(void)
{
int1 done1;
int1 done2;
port_b_pullups(TRUE);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// Init Servo Pulse
pulse_max=0;
pulse_top=0;
top_value = MAX_VALUE; // top_value = MAX_VALUE: Servo Motor Stop
// Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
set_timer0(206) ; //interrupt every 0.1ms
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
// Read the ADC here
for(;;){
A0;
set_adc_channel(0);
read_adc(ADC_READ_ONLY);
done1 = adc_done();
while(!done1) {
done1 = adc_done();
}
ldr_left=read_adc(ADC_READ_ONLY);
delay_us( 30 );
A1;
set_adc_channel(1);
read_adc(ADC_READ_ONLY);
done2 = adc_done();
while(!done2) {
done2 = adc_done();
}
ldr_right=read_adc(ADC_READ_ONLY);
delay_us( 30 );
// Get the different
ldr_diff = ldr_left - ldr_right;
if ((ldr_diff >= -THRESHOLD_VALUE) && (ldr_diff <= THRESHOLD_VALUE))
{
top_value = MAX_VALUE; // Stop the Servo Motor
}
else
{
if (ldr_diff > THRESHOLD_VALUE)
{
top_value = CCW_ROTATION; // Counterclockwise Rotation
}
else
{
top_value = CW_ROTATION; // Clockwise Rotation
}
}
}
} |
I try to change a lot of the code but still to no avail :( |
|
![](templates/subSilver/images/spacer.gif) |
wind88
Joined: 29 Dec 2010 Posts: 37
|
|
Posted: Sun Jan 02, 2011 10:03 am |
|
|
Code: |
static void interrupt_isr(void)
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
if(INT_TIMER0)// TIMER0 Interrupt Flag
{
pulse_max++; // Pulse Max Increment
pulse_top++; // Pulse Top Increment
/* MAX_VALUE=200 turn off the pulse */
if (pulse_max >= MAX_VALUE) {
pulse_max=0;
pulse_top=0;
output_low(B1); // Turn off RB1
}
if (pulse_top == top_value) {
output_high(B1); // Turn On RB1
}
set_timer0(206) ; // Initial Value for 0.1ms Interrupt
}
}
|
Can anyone tell me if there is something wrong in this part? Thanx. |
|
![](templates/subSilver/images/spacer.gif) |
|