|
|
View previous topic :: View next topic |
Author |
Message |
CCSNewbie
Joined: 15 May 2008 Posts: 12
|
|
Posted: Sun May 18, 2008 3:14 pm |
|
|
AHHHHHHHHHH. It's a silly mistake that took me almost two days to realise.
I changed the value of the processor clock frequency in the simulation before this, and i did not undo the change.
The timing screwed up because of that.
*slaps self silly*
I plan to link a few PIC16F877As together (Master/Slave SPI configuration).
Anybody here with links regarding SPI that might help this beginner link his first few F877A together?
Any reading material or introduction will do. So far the links that i found were not really THAT helpful. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
CCSNewbie
Joined: 15 May 2008 Posts: 12
|
|
Posted: Mon May 19, 2008 2:40 pm |
|
|
Decided to change the topic for my main post since it's not relevant anymore.
Anyway, i managed to work the problem concerning the interrupts thanks to the forumers that were very helpful in helping out (especially PCM Prog, RLScott).
Now i have another problem which i could use some help.
Everywhere else in the code works ,except from Line 136-Line 196 (look for the *****)
I am trying to set a counter without using the interrupts (line 136-147).
But i dont know where i should insert the code. It's not possible to put them in the 'main' function since the while(1) is always true, please correct me if i am wrong.
Line 167-195 (the ones with $$$$ sign) are supposed to send out outputs from RC0,RC1 and RC2. But i guess without the working codes in line 136-147, these are redundant.
Thank you for your time!!
Code: | //----------------------------------------------------------------------
// DEFINES
//
// With a 4 MHz oscillator, a RTCC pre-scaler of 256, and a RTCC
// preload of 39, we get an rtcc interrupt rate of 100.16 Hz (Approx.
// every 10 ms).
// This will be our "tick" clock that we use for various event timers.
#define RTCC_PRELOAD (256 - 39)
// Multiply the following values x 10 ms to get the delay times,
// since each timer tick is 10 ms.
#define PED_SENS_TICKS 10 // 100 ms
#define CAR_SENS_TICKS 500 // 5000 ms
#include <16F877A.h>
#use delay(clock=4M)
// GLOBALS
int ped_sens_timer; // Defining
int ped_sens_timer2; // the
int car_sens_timer; // variables
int ped_sens_status; //
int16 ped_sens_det; //
int16 car_counter;
int car_sens_status;
char traffic_status;
char LOW;
char MEDIUM;
char HIGH;
void ped_sens(void); // Declaring
void ped_sens2(void); // the
void ped_sens_check(void); // functions
void ped_sens_check2(void); //
void car_sens(void); // main
void car_output(void); //
main()
{
set_tris_b(0b00000000);/*configure pins of PORTb as output*/
set_tris_a(0b00001111);/*configure A0,A1,A2,A3 as input*/
set_tris_c(0b00000000);//Configure pins of PORTC as output
output_b(0b00000000); //
output_a(0b00000000); // Setting the outputs to 0.
output_c(0b00000000); //
// Initializing the software timers for each task
ped_sens_timer = PED_SENS_TICKS;
ped_sens_timer2 = PED_SENS_TICKS;
car_sens_timer = CAR_SENS_TICKS;
// Setup the RTCC interrupts.
setup_counters(RTCC_INTERNAL, RTCC_DIV_256);
set_rtcc(RTCC_PRELOAD);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
// This is the main loop for the tasks.
while(1)
{
ped_sens();
ped_sens_check();
car_sens();
car_output();
}
}
//==============================
// PEDESTRIAN SENSOR 1
// If a pedestrian is detected for a period of longer than 5 seconds at PIN_A0,
// the counter will keep on counting until a period of 5th interrupts.
// At 1000ms each interrupt, 5 interrupts is almost equivalent to 5 seconds.
void ped_sens(void)
{
if(ped_sens_timer)
return;
else
{
ped_sens_timer = PED_SENS_TICKS;
}
//Status for pedestrian crossing 1
ped_sens_status = (input(PIN_A0)); // Initialize the button status
// Have the switches changed ?
if(ped_sens_status == 0) //If pedestrian is not detected -> reset
{
Ped_sens_det = 0;
output_bit( PIN_B0 , 0);
}
else if(ped_sens_status == 1) // If pedestrian is detected,-> counter +
{
Ped_sens_det++; // Increments the counter
output_bit( PIN_A0, 0); // and resets the PIN_A0 to 0 for next
// interrupt(to receive next input)
}
else
return;
}
//-----------------------------------------------------------
// This part of the coding checks to see whether the 500th interrupt had
// been achieved. If it is the 500th interrupt then another process will be
// called.
// After 5 secs, output of 0.2s is sent from B0
void ped_sens_check(void)
{
if(ped_sens_det == 50) // The Xth interrupt which determines the time
// A0 has to be HIGH before output is sent from B0
{
output_bit( PIN_B0 , 1);
ped_sens_det =-1; // Grace period before the next detection (-1 to
// 1 = 2 interrupts = 20ms)
}
else if(ped_sens_det ==1)
{
output_bit( PIN_B0, 0);;
}
else
Return;
}
//--------------------------------------------------------
//***************************************************************************
//***************************************************************************
// This part of the code calculates the number of times PIN_A2 is HIGH
// After an increment is made, PIN_A2 is reset to 0 after a 10ms delay.
void car_sens(void)
{
Car_sens_status = (input( PIN_A2));
if(car_sens_status == 1)
{
car_counter++;
delay_ms(10);
output_bit(PIN_A2 ,0);
}
else
return;
// The amount of times that PIN_A2 stays high determines the traffic_status
// The traffic status is based on car_counter, in which when it is from 1-5
// it is LOW, from 5-10 it is MEDIUM, and from 11 onwards it is HIGH
if(1<= car_counter <=5)
{
traffic_status = LOW;
}
Else if(5 <= car_counter <= 10)
{
traffic_status = MEDIUM;
}
else
{
traffic_status = HIGH;
}
}
//---------------------------------------------------------------------------
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
void car_output(void)
{
if(car_sens_timer)
return;
else
car_sens_timer = CAR_SENS_TICKS;
if(traffic_status == LOW)
{
output_bit( PIN_C0 ,1);
delay_ms(10);
output_bit( PIN_C0 , 0);
car_counter =0;
}
else if(traffic_status == MEDIUM)
{
output_bit( PIN_C1 , 1);
delay_ms(10);
output_bit( PIN_C1 , 0);
car_counter =0;
}
else if(traffic_status == HIGH)
{
output_bit(pin_C2 , 1);
delay_ms(10);
output_bit( PIN_C1 , 0);
car_counter =0;
}
}
//--------------------------------------------------------
// The rtcc interrupt occurs when the rtcc rolls over from FF to 00.
// I have programmed it to interrupt at a 100 Hz rate.
//
// RTCC interrupt rate = Fosc / (4 * rtcc pre-scaler * rtcc pre-load)
//
// = 4 MHz / (4 * 256 * 39)
//
// = 100.16 Hz
//
// This gives us a timer tick approx. every 10 ms (9.98 ms actually).
#int_rtcc
void rtcc_isr(void)
{
// Reload the RTCC, so it will keep overflowing every 10 ms.
set_rtcc(RTCC_PRELOAD);
// Decrement any timers that are running.
if(ped_sens_timer)
ped_sens_timer--;
if(ped_sens_timer2)
ped_sens_timer2--;
if(car_sens_timer)
car_sens_timer--;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 19, 2008 2:51 pm |
|
|
You're defeating the whole purpose of the multi-tasking program design
by putting static delays (of 10ms) inside tasks. All delays are supposed
to be done by counting down ticks.
You need to research it and think about what you're doing. |
|
|
CCSNewbie
Joined: 15 May 2008 Posts: 12
|
|
Posted: Mon May 19, 2008 3:05 pm |
|
|
Instead of using SPI for the Master/Slave configuration, i plan to use the pin outputs to signal my other PIC16F877A(lets call it PIC 2) which would be used to control the timing for the traffic lights depending on the inputs received from the 'PIC 1' which is the one i'm programming.
So basically once the PIC 1 have obtained the traffic_status through the sensors and counters, the results will be sent out (either HIGH,MEDIUM or LOW) to 'PIC 2', which will periodically check the inputs whether they are HIGH/MEDIUM/LOW and perform actions based on that.
While the actions are performed, the multitasking in PIC 1 can be halted temporarily, or completely reset. That is the reason i thought that using delay was an OK.
I could not think of a way to build a counter based on the interrupts.
Oh well i'm probably (or most definitely) wrong... more research needed indeed!! :D |
|
|
CCSNewbie
Joined: 15 May 2008 Posts: 12
|
|
Posted: Mon May 19, 2008 3:14 pm |
|
|
hrmm, i think i can make use the interrupt instead of delay after all.
Probably every 10ms i'll check whether the current input is the same as current output, and if it's not the same it definitely means that something just passed through the sensor..
so if current input =/= previous input , increment! (these are the moments where people usually go 'EUREKA!!' but i'll stay pessimistic for now)
will try it tomorrow i guess.
it's 5am i think i should zzz
Thanks though PCM, bbl~ |
|
|
|
|
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
|