|
|
View previous topic :: View next topic |
Author |
Message |
jjude
Joined: 12 Nov 2007 Posts: 37
|
SWITCH, CASE and BREAK |
Posted: Fri Feb 12, 2010 4:07 am |
|
|
Code: |
switch(xxx)
{
case : 1
{
if(input(PIN_A1)) break;
else yyy = 0;
}
break; //COMING BREAK THIS
default :
{
if(input(PIN_B1)) break;
else yyy = 1;
break; //OR THIS ???
}
} |
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Feb 12, 2010 4:28 am |
|
|
Firstly, what is your question ?
Secondly you have an error.
case : 1 should be case 1:
note the colon is in the wrong place.
And lastly
Code: |
switch(xxx)
{
case 1:
// not required {
if(input(PIN_A1))
break;
yyy = 0; // Could be done like this
// not required }
break; //COMING BREAK THIS
default :
// not required {
if(input(PIN_B1))
break;
else yyy = 1;
// break; NOT REQUIRED
// not required }
}
|
Would look something like this
Code: |
switch(xxx)
{
case 1:
if(!input(PIN_A1))
yyy = 0;
break;
default :
if(!input(PIN_B1))
yyy = 1;
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Feb 12, 2010 4:53 am |
|
|
Much tidier.
It is also worth being aware of a 'limitation' of the CCS implementation.
If you have a 'default' statement, though good in programming practice terms, this forces the switch statements to be individually tested. If instead all states are implemented with no 'default', the compiler uses a jump table. So, for the 'example' of dealing with cases from 1 to 10:
Code: |
if (y<1 || y>10) {
//Default operation outside the 'test' range
}
else switch (y) {
case 1:
case 2:
//Code for these cases
break;
case 3:
case 4:
case 5:
//Code for these cases
break;
case 6:
case 7:
case 8:
//Code for these cases
break;
case 9:
//Code for this case
break;
case 10:
//Code for last case
break;
}
}
|
By not having a 'default', and instead trapping this oneself, the compiler wll generate a jump table for all the used cases, giving equal execution time for all the cases. Slower for only a couple of cases (the compiler when I last tested it, would still perform individual tests for less than four cases), but for larger examples, much quicker.
Then, the original example given, can equally well be coded as:
Code: |
if (xxx==1) {
if(!input(PIN_A1))
yyy = 0;
}
else {
if(!input(PIN_B1))
yyy = 1;
}
|
Though cases are a very tidy way of coding large numbers of choices, for a single value, use the if....
Best Wishes |
|
|
Petar_2010
Joined: 18 Nov 2018 Posts: 5
|
Problem with switch |
Posted: Thu Nov 22, 2018 3:56 am |
|
|
Hello,
I have a problem with my code with the switch sentence.
The code is compiled correctly but the micro doesn´t work.
I want to have a different modules with steady light or intermittent depending of the state of the buttons.
I can´t see where is my error.
I apologize for my bad english.
This is my code:
// LEDS CONTROL
// 29/10/2018
//////////////////////////////////////////////////////////////////////
#include <16F1828.h>
#fuses NOMCLR
#use delay(internal=8MHz)
#use FIXED_IO( A_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3,PIN_A4,PIN_A5 )
#use FIXED_IO( B_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7 )
#use STANDARD_IO(C)
// DEFINE INPUT BUTTONS
#define BUTTON_1 PIN_C0
#define BUTTON_2 PIN_C1
#define BUTTON_3 PIN_C2
#define BUTTON_4 PIN_C3
#define BUTTON_5 PIN_C4
// DEFINE OUTPUT LEDS
#define LED_GREEN PIN_A0
#define LED_AMBER PIN_A1
#define LED_RED PIN_A2
#define LED_WHITE PIN_A4
#define LED_BLUE PIN_A5
#use rs232(baud=9600,bits=8, parity=N,xmit=PIN_b5,rcv=PIN_b4)
// DEFINE FUNCTIONS
void steady_1();
void steady_2();
void steady_3();
void steady_4();
void steady_5();
void interm_1();
void interm_2();
void interm_3();
void interm_4();
void interm_5();
//====================================
//====================================
void main()
{
port_c_pullups(0xff);
int8 estados;
output_a(0x00);
while(true)
{
switch (estados)
{
case 1:
if(input(BUTTON_1)==0)
steady_1();
else
interm_1();
break;
case 2:
if(input(BUTTON_2)==0)
steady_2();
else
interm_2();
break;
case 3:
if(input(BUTTON_3)==0)
steady_3();
else
interm_3();
break;
case 4:
if(input(BUTTON_4)==0)
steady_4();
else
interm_4();
break;
case 5:
if(input(BUTTON_5)==0)
steady_5();
else
interm_5();
break;
default:
output_a(0x00);
} //switch
} //while principal
} //main
//-----------------------------
//FUNCTIONS
//---------
void steady_1()
{
output_high(LED_GREEN);
}
void steady_2()
{
output_high(LED_AMBER);
}
void steady_3()
{
output_high(LED_RED);
}
void steady_4()
{
output_high(LED_WHITE);
}
void steady_5()
{
output_high(LED_BLUE);
}
//------------------------------
void interm_1()
{
output_high(LED_GREEN);
delay_ms(500);
output_low(LED_GREEN);
delay_ms(500);
}
void interm_2()
{
output_high(LED_AMBER);
delay_ms(500);
output_low(LED_AMBER);
delay_ms(500);
}
void interm_3()
{
output_high(LED_RED);
delay_ms(500);
output_low(LED_RED);
delay_ms(500);
}
void interm_4()
{
output_high(LED_WHITE);
delay_ms(500);
output_low(LED_WHITE);
delay_ms(500);
}
void interm_5()
{
output_high(LED_BLUE);
delay_ms(500);
output_low(LED_BLUE);
delay_ms(500);
}
//------------------------------- |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Nov 22, 2018 4:35 am |
|
|
1) Learn to use the code buttons.
2)
Code: |
int8 estados; //at this point estados is uninitialised
//could contain anything....
output_a(0x00);
while(true)
{
//What is going to set 'estados' to anything?. It starts with
//a value that probably does not correspond to any of your switch
//values, and nothing changes it....
//How is anything meant to happen?.
switch (estados)
|
|
|
|
Petar_2010
Joined: 18 Nov 2018 Posts: 5
|
|
Posted: Sat Nov 24, 2018 11:52 am |
|
|
Ttelmah wrote: | 1) Learn to use the code buttons.
2)
Code: |
int8 estados; //at this point estados is uninitialised
//could contain anything....
output_a(0x00);
while(true)
{
//What is going to set 'estados' to anything?. It starts with
//a value that probably does not correspond to any of your switch
//values, and nothing changes it....
//How is anything meant to happen?.
switch (estados)
|
|
Thank you for your attention.
I think that I must to change the way.
I need three states: led ON steady, led ON intermittent and led OFF.
Every time pressing the push button I need to change different state.
Do you have any ideas? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Nov 24, 2018 2:40 pm |
|
|
Yes, just initilise the variable to the default state value, and when you see your button, increment is (and when it reaches '3' set it back to zero.
You show the code using five buttons, now you are only using one?.
Remember also that detecting a button, requires you to look for it changing, not just the act of it being on, and you need to cope with the probability that there will be bounce (a button won't cleanly go 'on'). |
|
|
Petar_2010
Joined: 18 Nov 2018 Posts: 5
|
|
Posted: Sun Nov 25, 2018 9:49 am |
|
|
Thank you for your time Ttelmah,
Yes I need work with five buttons, but I think that is easier work with only one at first and then with five.
I found in that forum a very good example of use of two states of push button - (state up - button released) and (state down - button pressed).
Now I have two states of every of the five buttons, but I need a third state - intermittent.
This is the code:
Code: |
// LEDS CONTROL
// 29/10/2018
//////////////////////////////////////////////////////////////////////
#include <16F1828.h>
#fuses NOMCLR
#use delay(internal=8MHz)
#use FIXED_IO( A_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3,PIN_A4,PIN_A5 )
#use FIXED_IO( B_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7 )
#use STANDARD_IO(C)
// DEFINE INPUT BUTTONS
#define BUTTON_1 PIN_C0
#define BUTTON_2 PIN_C1
#define BUTTON_3 PIN_C2
#define BUTTON_4 PIN_C3
#define BUTTON_5 PIN_C4
// DEFINE OUTPUT LEDS
#define LED_GREEN PIN_A0
#define LED_AMBER PIN_A1
#define LED_RED PIN_A2
#define LED_WHITE PIN_A4
#define LED_BLUE PIN_A5
#use rs232(baud=9600,bits=8, parity=N,xmit=PIN_b5,rcv=PIN_b4)
//====================================
//====================================
void main()
{
port_c_pullups(0xff);
output_a(0x00);
while(true)
{
if((input(BUTTON_1) == 0)) //
{
//GREEN
char count;
count = 0;
while(true)
{
if((input(BUTTON_1) == 0))
delay_ms(10);
if((input(BUTTON_1) == 0)) //debounce - antireplique
count++;
else
count = 0;
if(count == 1)
break;
delay_ms(10);
}
while(true)
{
if (input(BUTTON_1))
delay_ms(10);
if (input(BUTTON_1)) //debounce - antireplique
count++;
else
count = 0;
if(count == 1)
break;
delay_ms(10);
}
count = 0;
output_toggle(LED_GREEN);
}
if((input(BUTTON_2) == 0)) //
{
//AMBER
char count2;
count2 = 0;
while(true)
{
if((input(BUTTON_2) == 0))
delay_ms(10);
if (input(BUTTON_2)) //debounce - antireplique
count2++;
else
count2 = 0;
if(count2 == 1)
break;
delay_ms(10);
}
count2 = 0;
while(true)
{
if (input(BUTTON_2))
delay_ms(10);
if (input(BUTTON_2)) //debounce - antireplique
count2++;
else
count2 = 0;
if(count2 == 1)
break;
delay_ms(10);
}
output_toggle(LED_AMBER);
}
if((input(BUTTON_3) == 0)) //
{
//RED
char count3;
count3 = 0;
while(true)
{
if((input(BUTTON_3) == 0))
delay_ms(10);
if (input(BUTTON_3)) //debounce - antireplique
count3++;
else
count3 = 0;
if(count3 == 1)
break;
delay_ms(10);
}
count3 = 0;
while(true)
{
if (input(BUTTON_3))
delay_ms(10);
if (input(BUTTON_3)) //debounce - antireplique
count3++;
else
count3 = 0;
if(count3 == 1)
break;
delay_ms(10);
}
output_toggle(LED_RED);
}
if((input(BUTTON_4) == 0)) //
{
//WHITE
char count4;
count4 = 0;
while(true)
{
if((input(BUTTON_4) == 0))
delay_ms(10);
if (input(BUTTON_4)) //debounce - antireplique
count4++;
else
count4 = 0;
if(count4 == 1)
break;
delay_ms(10);
}
count4 = 0;
while(true)
{
if (input(BUTTON_4))
delay_ms(10);
if (input(BUTTON_4)) //debounce - antireplique
count4++;
else
count4 = 0;
if(count4 == 1)
break;
delay_ms(10);
}
output_toggle(LED_WHITE);
}
if((input(BUTTON_5) == 0)) //
{
//BLUE
char count5;
count5 = 0;
while(true)
{
if((input(BUTTON_5) == 0))
delay_ms(10);
if (input(BUTTON_5)) //debounce - antireplique
count5++;
else
count5 = 0;
if(count5 == 1)
break;
delay_ms(10);
}
count5 = 0;
while(true)
{
if (input(BUTTON_5))
delay_ms(10);
if (input(BUTTON_5)) //debounce - antireplique
count5++;
else
count5 = 0;
if(count5 == 1)
break;
delay_ms(10);
}
output_toggle(LED_BLUE);
}
} //while principal
} //void main |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Nov 25, 2018 2:15 pm |
|
|
Code: |
int16 buttons[]={PIN_C0, PIN_C1, PIN_C2, PIN_C3, PIN_C4};
int16 leds[]={PIN_A0, PIN_A1, PIN_A2, PIN_A3, PIN_A4};
enum state {OFF, FLASH, ON};
enum states[] = {OFF,OFF,OFF,OFF,OFF}; //initial states
int8 keys[]= {0,0,0,0,0};
#INT_TIMER2
void tick(void)
{
//Tick needs to scan keys, and handle flash state
int8 ctr;
static int8 flashctr=0;
flashctr++;
for (ctr=0;ctr<5;ctr++) //five keys
{
if (input(buttons[ctr])==0)
keys[ctr]++; //increment counter if key pressed
else
keys[ctr]==0; //clear if released
if (keys[ctr>3)
keys[ctr]==3; //prevent key repeating
if (keys[ctr]==2) //after two ticks
{
states[ctr]++; //increment state.
if (states[ctr]>ON)
states[ctr]=OFF; //wrap back to off
}
switch states[ctr] {
case OFF: //LED off
output_low(leds[ctr];
break;
case FLASH: //flash leds
if (flashctr<10)
output_high(leds[ctr]);
else
output_low(leds[ctr]);
break;
case ON:
output_high(leds[ctr]);
break;
}
}
if (flashctr>=20)
flashctr=0;
}
void main(void)
{
setup_timer2(T2_DIV_64, 249, 12); //just under 10Hz
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE);
;
}
|
No guarantees, typed in and not checked. However shows how to be
handling all five keys and leds, with all working. |
|
|
Petar_2010
Joined: 18 Nov 2018 Posts: 5
|
|
Posted: Wed Nov 28, 2018 2:21 am |
|
|
Many, many thanks Ttelmah,
Very good job, but a little bit complicated. I need to learn more for can use your idea.
However, I´m very grateful. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Nov 28, 2018 2:41 am |
|
|
Evil grin....
However it is actually very simple.
A master 'tick'. Happens at about 10Hz.
This tests each button (using an array of button numbers). If the button is 'on'
increments a counter for that button. If off, clears the counter.
If the counter reaches '2', says 'on', and increments the operation state for that
button.
The state has three possibilities. OFF, FLASH, ON.
Then for each button, tests the state. If it is 'OFF' turns the LED off. If ON turns
the LED ON> IF it is in the 'FLASH' state, it turns it on if another counter being
run in the interrupt, is 10 to 20, or off if it is 0 to 9. So flashes the LED.
Now the events never delay, each test passes immediately to the next in
sequence, so the whole thing handles each button, and output in turn.
Problem with your existing code, is it only does one thing after another, and
so while it is flashing LED2 (say), it is not able to check any of the other
keys or flash any other LED. |
|
|
|
|
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
|