|
|
View previous topic :: View next topic |
Author |
Message |
erpgc82
Joined: 02 May 2020 Posts: 73
|
blink 2 independent LEDs, CCS |
Posted: Sun May 10, 2020 7:45 pm |
|
|
Hello my friends, I am studying C programming at CCS.
I have a lot of attention and notes, but today when practicing a change in a code and I can no longer get frustrated, I would like your help here, if you can!
The example in the book, Example 1, is to blink only one led, when connecting the circuit, this one I did and it worked perfectly.
However when trying to blink 2 leds, I couldn't do it anymore, see below how I did it in examples 2, 3 and 4:
Code: |
// Example 1: 1 LED works ok
#include <16f628a.h>
#use delay (clock = 4000000)
#fuses INTRC_IO // Will use internal clock, and the 2 crystal pins will be available for Input and Output;
#fuses NOWDT // Internal whatchdog, disabled;
#fuses PUT // Wait 72ms to establish the circuit and then turn on the PIC;
#fuses BROWNOUT // Monitor if the circuit drops below 4.5v and reset the PIC;
#fuses NOLVP // Does not record by low voltage;
#fuses NOMCLR // Does not enable MASTER CLEAR MOCLR disabled, you can use the MCLR PIN as Input and Output;
void main () // Main function (main body of the program)
// main () // it also works to type the command only: main ()
{// start of the main function's command block;
int time; // Variable time of 8 bitsl;
time = 100; // assigns the value 100 to the time variable;
// can also be written: "int time = 100;"
while (true) // if true, keep repeating, infinite loop. Declares that the command block to be started below, keeps repeating
{// ***** start of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
output_high (pin_b0); // raise pin B0, turn on the led;
delay_ms (time); // awaits the value of the time variable;
output_low (pin_b0); // lower pin B0, turn off the led;
delay_ms (time); // awaits the value of the time variable;
} // ***** end of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
} // End of the main function command block;
|
Code: |
/ * Example 2: It works 2 LEDs, but delays the flashing of the LED, as you have to go through all the commands to
go back in the first one and that’s not what I wanted to test; * /
#include <16f628a.h>
#use delay (clock = 4000000)
#fuses INTRC_IO // Will use internal clock, and the 2 crystal pins will be available for Input and Output;
#fuses NOWDT // Internal whatchdog, disabled;
#fuses PUT // Wait 72ms to establish the circuit and then turn on the PIC;
#fuses BROWNOUT // Monitor if the circuit drops below 4.5v and reset the PIC;
#fuses NOLVP // Does not record by low voltage;
#fuses NOMCLR // Does not enable MASTER CLEAR MOCLR disabled, you can use the MCLR PIN as Input and Output;
void main () // Main function (main body of the program)
// main () // it also works to type the command only: main ()
{// start of the main function's command block;
int time; // Variable time of 8 bitsl;
time = 100; // assigns the value 100 to the time variable;
// can also be written: "int tempo = 100;"
int time2; // MY TEST
time2 = 250; // MY TEST
while (true) // if true, keep repeating, infinite loop. Declares that the command block to be started below, keeps repeating
{// ***** start of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
output_high (pin_b0); // raise pin B0, turn on the led;
delay_ms (time); // awaits the value of the time variable;
output_low (pin_b0); // lower pin B0, turn off the led;
delay_ms (time); // awaits the value of the time variable;
output_high (pin_b2); // lift pin B2, turn on the led; MY TEST
delay_ms (time2); // awaits the value of the time2 variable; MY TEST
output_low (pin_b2); // lower pin B2, turn off the led; MY TEST
delay_ms (time2); // awaits the value of the time2 variable; MY TEST
} // ***** end of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
} // End of the main function command block;
|
Code: |
// Example 3: As I thought it would work, but only the rb0 LED works correctly;
#include <16f628a.h>
#use delay (clock = 4000000)
#fuses INTRC_IO // Will use internal clock, and the 2 crystal pins will be available for Input and Output;
#fuses NOWDT // Internal whatchdog, disabled;
#fuses PUT // Wait 72ms to establish the circuit and then turn on the PIC;
#fuses BROWNOUT // Monitor if the circuit drops below 4.5v and reset the PIC;
#fuses NOLVP // Does not record by low voltage;
#fuses NOMCLR // Does not enable MASTER CLEAR MOCLR disabled, you can use the MCLR PIN as Input and Output;
void main () // Main function (main body of the program)
// main () // it also works to type the command only: main ()
{// start of the main function's command block;
int time; // Variable time of 8 bitsl;
time = 100; // assigns the value 100 to the time variable;
// can also be written: "int time= 100;"
int time2; // MY TEST
time2 = 250; // MY TEST
while (true) // if true, keep repeating, infinite loop. Declares that the command block to be started below, keeps repeating
{// ***** start of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
output_high (pin_b0); // raise pin B0, turn on the led;
delay_ms (time); // awaits the value of the time variable;
output_low (pin_b0); // lower pin B0, turn off the led;
delay_ms (time); // awaits the value of the time variable;
} // ***** end of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
{// ***** start of the SECOND command block to flash the RB2 led. BLOCK OF INSTRUCTIONS TO BE REPEATED; MY TEST
output_high (pin_b2); // lift pin B2, turn on the led; MY TEST
delay_ms (time2); // awaits the value of the time2 variable; MY TEST
output_low (pin_b2); // lower pin B2, turn off the led; MY TEST
delay_ms (time2); // awaits the value of the time2 variable; MY TEST
} // ***** end of the SECOND command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED; MY TEST
} // End of the main function command block;
|
Code: |
// Example 4: another attempt to blink the other led:
#include <16f628a.h>
#use delay (clock = 4000000)
#fuses INTRC_IO // Will use internal clock, and the 2 crystal pins will be available for Input and Output;
#fuses NOWDT // Internal whatchdog, disabled;
#fuses PUT // Wait 72ms to establish the circuit and then turn on the PIC;
#fuses BROWNOUT // Monitor if the circuit drops below 4.5v and reset the PIC;
#fuses NOLVP // Does not record by low voltage;
#fuses NOMCLR // Does not enable MASTER CLEAR MOCLR disabled, you can use the MCLR PIN as Input and Output;
void main () // Main function (main body of the program)
// main () // it also works to type the command only: main ()
{// start of the main function's command block;
int time; // Variable time of 8 bitsl;
time = 100; // assigns the value 100 to the time variable;
// can also be written: "int tempo = 100;"
int tempo2; // MY TEST
time2 = 250; // MY TEST
while (true) // if true, keep repeating, infinite loop. Declares that the command block to be started below, keeps repeating
{// ***** start of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
output_high (pin_b0); // raise pin B0, turn on the led;
delay_ms (time); // awaits the value of the time variable;
output_low (pin_b0); // lower pin B0, turn off the led;
delay_ms (time); // awaits the value of the time variable;
} // ***** end of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
} // End of the main function command block;
void blink2 () // Function blink2
// main () // it also works to type the command only: main ()
{// start of the main function's command block;
int time2; // Variable time of 8 bitsl;
time2 = 250; // assigns the value 100 to the variable time2;
while (true) // if true, keep repeating, infinite loop. Declares that the command block to be started below, keeps repeating
{// ***** start of the command block to flash the led. BLOCK OF INSTRUCTIONS TO BE REPEATED;
output_high (pin_b2); // lift pin B2, turn on the led;
delay_ms (time2); // awaits the value of the time2 variable;
output_low (pin_b2); // lower pin B2, turn off the led;
delay_ms (time2); // awaits the value of the time2 variable;
} // ***** end of the command block to flash the portB led, pin 2. INSTRUCTIONS BLOCK TO BE REPEATED;
}
|
Where is my error, because I can compile correctly but I cannot blink 2 LEDs independently? _________________ Gradually you will go far with persistence, will and determination! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 11, 2020 4:47 am |
|
|
For anyone who wants to work on his problem, I have taken his example
#4 and stripped out all the comments so the program is readable:
Code: |
// Example 4: another attempt to blink the other led:
#include <16F628A.h>
#use delay (clock=4M)
#fuses INTRC_IO
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP
#fuses NOMCLR
//==================
void main ()
{
int time;
time = 100;
int tempo2;
time2 = 250;
while(true)
{
output_high(PIN_B0);
delay_ms(time);
output_low(PIN_B0);
delay_ms(time);
}
}
//----------------------
void blink2()
{
int time2;
time2 = 250;
while(true)
{
output_high(PIN_B2);
delay_ms(time2);
output_low(PIN_B2);
delay_ms(time2);
}
}
|
|
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Mon May 11, 2020 6:16 am |
|
|
Simply put, you have one program counter and it moves from line to line executing your lines of code. When the processor boots, it starts at the beginning of your main() function. It moves down and becomes trapped in your while loop. This is normal.
You have a function to blink a 2nd LED, but what executes this function? Nothing is calling it, so it is not executed.
IF we did execute blink2(), the program counter would become trapped in the function and never return because you have another while(true){} loop in this function. This will not work.
I'm not going to write your code for you. That would defeat the purpose of learning. But here are some suggestions:
* If your attempt is to learn how to blink 2 LEDs, then put the code to blink both LEDs inside the main's while loop.
* If your attempt here is to learn how to use functions, then try output_toggle() in the blink2() function without a while loop in the function.
-Kyle |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon May 11, 2020 7:18 am |
|
|
and (of course), if you want the two LED's to blink at different rates at
the same time, then you need to be using a counter and loop:
Code: |
#include <16F628A.h>
#use delay (clock=4M)
#fuses INTRC_IO
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP
#fuses NOMCLR
//==================
void main ()
{
int time, time2;
int ctr, ctr2;
time = 100;
time2 = 250;
ctr=time;
ctr2=time2; //initialise counters
while(true)
{
if (--ctr==0)
{
output_toggle(PIN_B0); //toggle first LED
ctr=time; //reset counter
}
if (--ctr2==0)
{
output_toggle(PIN_B2); //toggle second LED
ctr2=time2; //reset second counter
}
delay_ms(1); //1mSec each time round loop
}
}
|
The 'loop' takes just over 1mSec, and each time round, if a counter
reaches zero, it toggles the corresponding LED, and reloads the counter.
Each 'ctr' times round the loop, it toggles B0, and each ctr2 times round
the loop it toggles B2. |
|
|
erpgc82
Joined: 02 May 2020 Posts: 73
|
|
Posted: Mon May 11, 2020 10:21 am |
|
|
Hello friend "Ttelmah" thanks for that example, that's exactly what I wanted to do. As I say: I'm learning, I haven't seen accountants yet, I haven't reached that chapter of the book yet. But that is exactly the result I wanted. I will study and learn a lot from your example, thank you very much!
************* how I did your example **************
Code: |
// # include <example4.1-200511 blink 2 led counter loop.h>
/ *
It is an example that the forum ccs gave me:
http://www.ccsinfo.com/forum/viewtopic.php?t=58721
Uses a loop counter.
* /
#include <16F628A.h>
#use delay (clock = 4M)
#fuses INTRC_IO
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP
#fuses NOMCLR
// ==================
void main ()
{
int time, time2;
int counter, counter2;
time = 100;
time2 = 250;
counter = time;
counter2 = time2; // initialize the counters
while (true)
{
if (--counter == 0)
{
output_toggle (PIN_B0); // toggles the first led
counter = time; // reset the counter
}
if (--contador2 == 0)
{
output_toggle (PIN_B4); // switch according to led
counter2 = time2; // reset the second counter
}
delay_ms (1); // wait 1ms and restart the loop
}
}
|
***This is an alternative as I did, but it is not as perfect as its using counter.***
Code: |
#include <16f628a.h>
#use delay(clock=4000000)
#fuses INTRC_IO
#fuses NOWDT
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP
#fuses NOMCLR
/*
This example below, was a test of mine, different from how it is in the book, I made it blink
in addition to the LED on PORT B, pin 0, I also made pin 4 on port B. The loop starts
the output_high command block (pin_b0); and ends at output_low (pin_b4); and
returns on the first line of the block again, that way the 2 leds flashed, but the interval erased in status 0, is the time that the other is lit in status 1;
*/
void main()
{
int time=100;
int time2=250;
while(true)
{
output_high(pin_b0);
delay_ms(tempo);
output_low(pin_b0);
delay_ms(0);
output_high(pin_b4);
delay_ms(tempo2);
output_low(pin_b4);
delay_ms(0);
}
}
|
Thank you very much for your help and answers! _________________ Gradually you will go far with persistence, will and determination! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon May 11, 2020 11:46 am |
|
|
and (of course), the counter approach can be used with an interrupt
at (say) 50Hz, to give you nice accurate times that don't affect one
another. |
|
|
|
|
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
|