View previous topic :: View next topic |
Author |
Message |
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
Masking portb |
Posted: Mon Oct 23, 2006 4:28 pm |
|
|
Hello All
Please be patience with me as i am new to using the Pic c Ccs complier.
i want to know how i can masks bits on portb as i going to be using Rb0-Rb3 as inputs and the remaining 4 as outputs
so i am setting my tris B register as below
set_tris_b(F0); // which is 11110000
I am fine with that and everything works if i test the individual bits for inputs like
if (input(PIN_B0)
{
do B0;
}
if (input(PIN_B1)
{
do B1;
}
if (input(PIN_B2)
{
do B2;
}
if (input(PIN_B3)
{
do B3;
}
The above works ok but i am now trying to use the SWITCH CASE command but not quite sure how to impliment the bit maskings part so that B4 to B7 are not affected as they are outputs.
Could someone be kind enough to explain it a bit more as i could understand it from the manual
Best Regard
_________________ BOB_Santana |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 23, 2006 4:44 pm |
|
|
You can read Port B and then shift the upper 4 bits into the lower nybble.
Then use that byte as the parameter in your switch() statement. Example:
Code: |
#include <16F877.h>
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use fast_io(B)
//===================================
int main ()
{
int8 data;
set_tris_b(0xF0);
data = input_b(); // Read Port B.
// Shift upper 4 bits into bit positions 3-0.
data = data >> 4;
switch(data) // Data can be from 0 to 15.
{
case 0:
// do something
break;
// Etc.
}
while(1);
} |
|
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Tue Oct 24, 2006 4:15 pm |
|
|
Thank PCM
I presume that this would only work with fast_io
how can it be done with standard_io
Regards _________________ BOB_Santana |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 24, 2006 4:45 pm |
|
|
I used fast_io because that's what you had in your post.
For standard i/o mode, you can't use the input_b() function because
it would change the TRIS to be inputs for all the Port B pins. You want
to keep four of the pins as outputs.
Here is one way to do it. Define the PortB address with a #byte
statement. Then read PortB as shown below. This method doesn't
change the TRIS.
Code: |
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=4000000)
#byte PortB = 0x06 // For 16F877
//===================================
int main ()
{
int8 data;
data = PortB; // Read Port B.
// Shift upper 4 bits into bit positions 3-0.
data = data >> 4;
switch(data) // Data can be from 0 to 15.
{
case 0:
// do something
break;
// Etc.
}
while(1);
} |
|
|
|
Guest
|
|
Posted: Wed Oct 25, 2006 2:36 am |
|
|
Hi PCM
While you are on this topic i thought you might be able to explain the
shift right command to me in detail as i do get confuse and try not to use it.
example let say a 8bit variable data is 00000001
how would the bit be shifted 4 place as in your example what would be the end value of data would it be 0001000 or 00000000
using the command below
And would say if data was 00000010 be 00100000
// Shift upper 4 bits into bit positions 3-0.
data = data >> 4;
Can you please clarify as i am still very new to the language
Toni |
|
|
Ttelmah Guest
|
|
Posted: Wed Oct 25, 2006 3:14 am |
|
|
This is the key difference between a 'shift', and a 'rotate'. The latter wraps bits out the end, and back round, while the former throws away bits that fall of the end. The '>>' command in C, is defined as a 'shift', so bits in the low four locations are lost. There is a 'caveat' though when dealing with signed numbers, where C does not specify whether the sign should be preserved, leaving this 'implementation dependant'....
Best Wishes |
|
|
Guest
|
|
Posted: Wed Oct 25, 2006 3:34 am |
|
|
Ha
so 0001000 or 00000000
using the command below
And would say if data was 00000010 be 00100000
// Shift upper 4 bits into bit positions 3-0.
data = data >> 4;
when the following data is shifted 4 places it becomes as follow
00010000 >> 4 = 00000001
00100000 >> 4 = 00000010
etc
Thanks for clearing this up
Toni |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Wed Nov 01, 2006 6:59 pm |
|
|
Hi Pcm
Could you be kind enough to tell me what i am doing wrong with this
test program the read the 4bit input connected PortB.0 to PortB.3
when i run my program i always get 0F return on my Lcd
Do the pins need to have pullup/down resistors
As even when i connect nothing to the pins i still get the same result.
Is there something obviousthat i am missing
The test Program
#if defined(__PCM__)
#include <16F877.h>
#ORG 0x1F00,0x1FFF {} // use boot loader for the 8k 16F877
#fuses XT,NOWDT,NOPROTECT,BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 1
#include <LCD_File.c>
#byte PortB = 0x06 // For 16F877
//===================================
void main()
{
int8 i;
int8 BcdData;
set_tris_b(0x0F);
// The lcd_init() function should always be called once,
// near the start of your program.
lcd_init();
printf(lcd_putc, "\f"); // Clear the LCD.
delay_ms(500);
while(1)
{
// Input is B0-B3
printf(lcd_putc, "\f 4 BIT Mask "); // Clear Screen & Write To Line 1.
//BcdData = 0;
BcdData = PortB; // Read Port B.
// Shift upper 4 bits into bit positions 3-0.
BcdData = BcdData >> 4;
printf(lcd_putc,"\n%x",BcdData ); // Write to "Line2 .
delay_ms(4000); // 4 Seconds Delay in mSeconds
}
}
Best Regards _________________ BOB_Santana |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Wed Nov 01, 2006 7:06 pm |
|
|
This was a typo
set_tris_b(0x0F) should be set_tris_b(0xF0); _________________ BOB_Santana |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 01, 2006 7:08 pm |
|
|
if
then you shouldn't >>4. That will lose the bits. Instead you should do this
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 01, 2006 7:14 pm |
|
|
What Mark said, plus the TRIS is incorrect.
Quote: |
read the 4bit input connected PortB.0 to PortB.3
This was a typo
set_tris_b(0x0F) should be set_tris_b(0xF0);
|
You had it right the first time. To make pins B0 to B3 be inputs,
(and pins B4-B7 be outputs) the TRISB register should be set to 0x0F. |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Thu Nov 02, 2006 1:22 am |
|
|
Thank you Pcm & Mark
You have been a great help
The test works now and i can read my values 0 to F
Believe me i have learnt something off you guys today.
Happy Now _________________ BOB_Santana |
|
|
|