Jump to content

Test_bit Function. Not Working?


Recommended Posts

I am more than willing to admit that it may not be working as I expect due to me not understanding how it is supposed to work. I am new to all of this (PICs and C).

 

#include <system.h>

volatile bit ra0@0x6.0;

volatile bit ra1@0x6.1;

unsigned int counter=0;

int aborted=0;

void main()

{

trisa=00000000b;

trisb=11111111b;

 

while ( 1 )

{

set_bit(porta,0); // Light the power LED.

if (ra0 == 1 )

{

set_bit(porta,1); // light the 'activated' LED.

 

for (counter=0;counter<5000;counter++) // 5000x1ms gives me about 5 seconds. Will want 60-120 when it's live.

{

if (ra1 == 1) // The Abort button was pressed.

{

clear_bit(porta,1); // Light the Aborted LED (only for debugging purposes).

delay_ms(5);

counter=5000; // This to get out of the 'active' loop right away.

}

delay_ms(1);

}

if (test_bit(porta,1)==1) // In theory this should be 1 if abort was not pressed.

{

set_bit(porta,2); // This will activate a relay. This is an LED now.

delay_s(1); // This is to let me see what is what.

}

}

}

}

 

 

 

After this didn't work for me, I had the 'abort' loop assign 'aborted=1'. I then had the final if statement check the value of 'aborted'. That didn't work out for me.

 

I finally resorted to having the 'abort' loop assign 'counter=5500'. I then had the final if statement check for 'counter==5000'. That did the trick so I now have a PIC that does exactly as I want it to do.

 

However, I would like to know what I did wrong in this first attempt. I'd really like to know how to use 'test_bit correctly for future projects.

 

I am currently using the free BoostC license, if that helps any.

 

Thanks!

Link to post
Share on other sites

You need to look at the test_bit macro:

 

#define test_bit( reg, bitNumb ) ((reg) & (1 << (bitNumb)))

 

This returns an 8-bit result.

 

The statement: if (test_bit(porta,1)==1) will never be true because test_bit(porta,1) expands to: ((porta)&(2))

 

When using the test_bit only test the result for ==0 or !=0.

Edited by cac001
Link to post
Share on other sites
You need to look at the test_bit macro:

 

#define test_bit( reg, bitNumb ) ((reg) & (1 << (bitNumb)))

 

This returns an 8-bit result.

 

The statement: if (test_bit(porta,1)==1) will never be true because test_bit(porta,1) expands to: ((porta)&(2))

 

When using the test_bit only test the result for ==0 or !=0.

 

#include <system.h>

volatile bit ra0@0x6.0;

volatile bit ra1@0x6.1;

unsigned int counter=0;

 

void main()

{

trisa=00000000b;

trisb=11111111b;

 

while ( 1 )

{

set_bit(porta,0); // Light the power LED.

if (ra0 == 1 )

{

set_bit(porta,1); // light the 'activated' LED.

 

for (counter=0;counter<5000;counter++) // 5000x1ms gives me about 5 seconds. Will want 60-120 when it's live.

{

if (ra1 == 1) // The Abort button was pressed.

{

clear_bit(porta,1); // Light the Aborted LED (only for debugging purposes).

delay_ms(5);

counter=5500; // This to get out of the 'active' loop right away.

}

delay_ms(1);

}

if (test_bit(porta,1)==0) // In theory this should be 0 if abort was not pressed.

{

set_bit(porta,2); // This will activate a relay. This is an LED now.

delay_s(1); // This is to let me see what is what.

}

}

}

}

 

 

When using that, it always seems to execute the bits inside the last 'if' statement. Regardless of me pressing the 'abort' button or not. !=0 seems to have it never execute that section of code (as expected based on the ==0 results.)

 

Neither way seems to fly. I am at a loss with it at this point. I DID find a way that gets the job done, as I mentioned earlier. I'd really like to do it the right way though.

 

I also do know that the 'abort' button IS working, as pushingit get me out of the 'active' loop immediately. using the above code, is just happens to cut the wait time short. It seems to have no other effect, which is disappointing to say the least. ;)

 

I apprecaite your help, and await any and all replies.

 

Thanks!

Edited by mkomar
Link to post
Share on other sites
Neither way seems to fly. I am at a loss with it at this point. I DID find a way that gets the job done, as I mentioned earlier. I'd really like to do it the right way though.

 

I also do know that the 'abort' button IS working, as pushingit get me out of the 'active' loop immediately. using the above code, is just happens to cut the wait time short. It seems to have no other effect, which is disappointing to say the least. ;)

 

I apprecaite your help, and await any and all replies.

 

Thanks!

I would bash my way through with something like:

if(porta,1)==0
{ 
...
}

and I would have thought that test_bit was a boolean answer so I guess I would write my own when it didn't work.

 

How about using test_bit ==0 or !=0 as the test criterion instead of ==1. This gets away from how many bits we have to deal with.

 

I would also get away from talking about porta,1 & ra1. We know porta,1 works so replace all the ra1 & ra0. Then the code is not so dependant on the chip memory.

Link to post
Share on other sites
and I would have thought that test_bit was a boolean answer so I guess I would write my own when it didn't work.

 

How about using test_bit ==0 or !=0 as the test criterion instead of ==1. This gets away from how many bits we have to deal with.

 

I would also get away from talking about porta,1 & ra1. We know porta,1 works so replace all the ra1 & ra0. Then the code is not so dependant on the chip memory.

 

You raise some good points. I have been changed the code to use only 'portX,1' references instead of a mix.

 

I have still not gotten much further.

 

#include <system.h>

void main()
{
trisb=0b00000011;
portb=0;
unsigned int counter=0;
char activate=0;
char abort=0;

while ( 1 ) 
{
if ( test_bit(portb,0) )
	{
	activate=1;
	counter=0;
	set_bit(portb,3); // light the 'activated' LED.

	while (counter<6000)
		{
		counter++;
		delay_ms(10);
		if (test_bit(portb,1)) // The Abort button was pressed.
			{
			clear_bit(portb,3); // Clear the Active LED
			counter=6000; // This to get out of the 'active' loop right away.
			abort=1;
			activate=0;
			}
		}
	}

if (test_bit(portb,3))
	{
	set_bit(portb,4);
	delay_s(4);
	clear_bit(portb,4);
	}


if (activate==1 && abort==0)
	{
	set_bit(portb,4); // This will activate a relay. This is an LED now.
	delay_s(10); // This is to let me see what is what.
	clear_bit(portb,4);
	activate=0;
	}
}
}

 

The code above works with the exception of the two 'if' statements that I would think would light up port 4 for a few seconds at a time. In theory both of them should light up if I press the 'active' switch and then don't press the 'abort' switch. I think.

 

Anybody else have any words of wisdom for me?

Link to post
Share on other sites
Anybody else have any words of wisdom for me?

 

 

It just struck me that I may need to be switching the port in question back and forth between input and output as I try to poll it. I'll be trying that as soon as I get a chance.

 

What I am not sure about at this point is how do I change a single pin between I/O?

 

I know how to use the 'tris' function to set them all, but I've only ever assigned them all. ie: tris=0b00110110 or so. If I want to alter the state of pin3 and ONLY pin3, what do I do?

Link to post
Share on other sites

It looks like you have a good handle on using the bit functions.

 

The issues you now have are all about the "logic" of your application.

 

There may be some on this forum that may use their psychic geek powers to read your mind and divine what you want.

 

For the rest of us you really need to be very clear with an explanation of all the steps that your application needs to go through to achieve your goals.

 

So far there is no clear picture of what you've got and what you need.

 

Start by thinking about all input events and all of the output states.

 

These question may help get you started:

 

What does the app need to do when a button is pressed?

 

What does the app need to do when a button is released?

 

If one button is not pressed do I need to know the state of the other button?

 

There are two buttons so there are at least four states to define:

0 - Both released

1 - One pressed

2 - The other one pressed

3 - Both pressed

 

Start by defining the output states based one what button or buttons are pressed or released.

 

If these are real world buttons do they need to be debounced before your app will "know" the button status?

 

There are lots of examples of button debounce functions. Keep it simple and clean.

Edited by cac001
Link to post
Share on other sites

My bad. Here is the skinny.

 

Here is the perfect world.

 

1) Device begins in a powered down state.

2) User presses activate button.

3) LED Lights up, and 90 second timer starts.

4) If abort button is pressed during the 90 seconds, the device powers down.

5) If the 90 seconds elapses without being aborted, a relay is activated for 1 second.

6) Device powers down.

 

I guess I'd actually be OK with there only being one button, and if the button is pushed for a second time (after being pushed one to begin the process) then it aborts and powers itself down.

 

Is this something realistic?

Link to post
Share on other sites

Alrighty, here is what I would really love to see this do.

 

Beginning from an unpowered state:

 

1) Users pushes button 1.

2) Led lights up and a 90 second timer begins.

3) If during this process, an abort button is pressed (Which could be the same button), then the sequence stops here and the device powers down.

4) If the 90 seconds is reached, then a relay is activated for 1 second and then the device powers down.

 

 

 

If the powering up/down features are not possible, that is fine. It'd be neat, but that's fine.

 

If I can't have that feature easily, then I would want to add an additional LED to let me know that the device is powered up but not in a timer state, so I remember to turn it off.

 

Though, I could do that bit outside the pic.

 

My other question still stands as far as changing a single bit between I/O on the port. Is that possible? I suspect that it is.

Link to post
Share on other sites

All of the goals that you would like to achieve can be done with the PIC you have chosen. Please don't be too disappointed that a complete ready to run application is not posted here in the next few hours. That kind of help is rarely found on a free forum.

 

You are most likely to find a little help here on a problem that you have defined well and has a very narrow scope.

 

Like your last question:

... changing a single bit between I/O on the port. Is that possible? ...

Yes you can change a single bit on a port from in to out and back by changing the bit of that ports TRISx register.

 

As for all the other stuff you will need to know to complete your project you may need to just try and learn it as best you can. If you do not have the time you may want to hire someone to help.

Link to post
Share on other sites
All of the goals that you would like to achieve can be done with the PIC you have chosen. Please don't be too disappointed that a complete ready to run application is not posted here in the next few hours. That kind of help is rarely found on a free forum.

 

You are most likely to find a little help here on a problem that you have defined well and has a very narrow scope.

 

Like your last question:

... changing a single bit between I/O on the port. Is that possible? ...

Yes you can change a single bit on a port from in to out and back by changing the bit of that ports TRISx register.

 

As for all the other stuff you will need to know to complete your project you may need to just try and learn it as best you can. If you do not have the time you may want to hire someone to help.

 

I hear ya. Not expecting to have someone write it for me. Was hoping I was making a common error that would be easily spotted by someone with some experience. I guess that isn't the case. I'll get it figured out.

 

With regard to the tris question. Can you tell me the command?

 

trisa=0b00011011; will set them all to various things. What if I want to change pin 4 between I/O but don't want to change the others. (Say they are in an unknown state and I don't want to accidently change them).

 

Right now the only way I know to alter the state is to set the state of all of them using either 0bxxxxxxxx or 0xXX ...

 

This is a hobby project I don't have time to devote to as a full time thing, and also isn't worth it to pay dollars to someone to develop. It's a 'neat' hobby project I am working on. The getting there is as important to me as the finished product.

 

I would dig on finding someone local to me (Northern Virginia) I could talk to and maybe barter some tutoring from or so. Know of anybody who meets that criteria?

 

I do appreciate everyone who posts usefull stuff to the forum. I read a lot of it. And do you especially for taking the time to read and comment on this thread.

 

Thanks to all!

Link to post
Share on other sites

// to set as input leaving all other bits undisturbed

bit_set(trisa,4);

 

// to set as output

bit_clear(trisa,4);

 

OR

 

#define BIT_4_MASK 0x10 // ie 0b0001000

#define BIT_1_MASK 0x1 // ie 0b00000001

 

 

// to set as input leaving all other bits undisturbed

 

trisa |= BIT_4_MASK;

 

// to set as output

 

trisa &= ~BIT_4_MASK;

 

// and to flip to the opposite state

 

trisa ^= BIT_4_MASK;

 

 

the bit functions are good for single bits, the mask are better for multiple bits

 

eg

 

trisa |= BIT_4_MASK | BIT_1_MASK;

 

 

trisa=0b00011011; will set them all to various things. What if I want to change pin 4 between I/O but don't want to change the others. (Say they are in an unknown state and I don't want to accidently change them).

 

Right now the only way I know to alter the state is to set the state of all of them using either 0bxxxxxxxx or 0xXX ...

 

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...