Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   using picc on a pic1f627 (http://www.velocityreviews.com/forums/t946310-using-picc-on-a-pic1f627.html)

Andre 05-17-2012 08:32 AM

using picc on a pic1f627
 
First, I am retired and doing all this just for fun ;-) and it's a
looong time since I used C language

I need to write 4 bits to PORTB without disturbing the others bit
RB1, RB2 are ( will be ) used by the UART.
If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
still there?

I think I could create a structure ( or a type ) with 4 bits such as
BCD { RB3
RB4
RB5
RB6
}

But I keep trying, no luck ( so far )
Can someone give a hand??
Many thanks in advances
André

nick_keighley_nospam@hotmail.com 05-17-2012 08:46 AM

Re: using picc on a pic1f627
 
On Thursday, May 17, 2012 9:32:52 AM UTC+1, Andre wrote:

<snip>

> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
> still there?


lost me. You've cleared (set to zero the top 4 bits). You can't actually /destroy/ bits!

> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }


bitfields. Pretty non-portable. Use masks and shifts

> But I keep trying, no luck ( so far )
> Can someone give a hand??


void setTopBits (unsigned char new_bits)
{
unsigned char value;
value = read_port (PORT_B);
value &= 0xf; /* clear top bits */
value |= (new_bits << 4); /* set new top bits */
write_port (PORT_B, value);
}

uncompiled. Assumes reading and writing bytes. The code could be more compact.

value = (value & 0xf) | (new_bits << 4);

And setTopBits() is a bit ungeneric

Willem 05-17-2012 09:04 AM

Re: using picc on a pic1f627
 
Andre wrote:
) First, I am retired and doing all this just for fun ;-) and it's a
) looong time since I used C language
)
) I need to write 4 bits to PORTB without disturbing the others bit
) RB1, RB2 are ( will be ) used by the UART.
) If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
) still there?

How does the PIC documentation say you should set/clear bits on a port?
IIRC, it's more complicated than simply setting the port register to
a given value.

If you know how to do it in ASM, it should be easy to transfer that to C,
and if not I'm sure there are people willing to help you with that.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Lanarcam 05-17-2012 09:33 AM

Re: using picc on a pic1f627
 
Le 17/05/2012 10:32, Andre a écrit :
> First, I am retired and doing all this just for fun ;-) and it's a
> looong time since I used C language
>
> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
> still there?
>
> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }
>


The usual way is to define macros, for instance :


#define cbi(portb, bit) ((portb) &= ~(1 << (bit)))

#define sbi(portb, bit) ((portb) |= (1 << (bit)))

cbi stands for clear bit and sbi for set bit.

#define RB3 3 // Bit position 3
#define RB4 4 // Bit position 4
#define RB5 5 // Bit position 5
#define RB4 6 // Bit position 7

volatile uint8_t * const portb = (uint8_t *) 0xfffb1234;

To set RB3 and RB5 :

uint8_t temp = *portb;
sbi(temp,RB3);
sbi(temp,RB5);
*portb = temp;

To clear RB4 and RB6

temp = *portb;
cbi(temp,RB4);
cbi(temp,RB6);
*portb = temp;

By reading first portb (temp = *portb;), you make sure
that you leaves the other bits untouched.


BartC 05-17-2012 10:27 AM

Re: using picc on a pic1f627
 


"Andre" <pas.mois@ailleur.be> wrote in message
news:4fb4b7b4$0$3115$ba620e4c@news.skynet.be...
> First, I am retired and doing all this just for fun ;-) and it's a looong
> time since I used C language
>
> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but still
> there?
>
> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }


Forget structs. I assume the device allows you to read and then rewrite
exactly the same bits?

Then, it you want to write bits 5,4,3,2, and leave alone bits 1,0 (ie.
RB6,5,4,3, and leave RB2,1), try:

bcdvalue=7; /* say you want to write binary 0111 to the 'bcd' bits */

CC = (CC&3) | (bcdvalue<<2);

This reads all six bits, clears all except the bottom two, then writes your
pattern into the next 4 bits (bcdvalue has to be shifted up a couple of
bits).

It also clears the top two bits of a presumably 8-bit value. To leave those
top two bits alone, use instead:

CC = (CC&0xC3) | (bcdvalue<<2);

Then maybe put the whole thing into a macro or function called
setbcd(bcdvalue).

--
Bartc




Paul 05-17-2012 05:55 PM

Re: using picc on a pic1f627
 
Andre wrote:
> First, I am retired and doing all this just for fun ;-) and it's a
> looong time since I used C language
>
> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
> still there?
>
> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }
>
> But I keep trying, no luck ( so far )
> Can someone give a hand??
> Many thanks in advances
> André


From a digital logic point of view, you do things
like this with bitwise "AND" and "OR".

You "mask" fields with a bitmask and the "AND" function.
So the "& 0x0F" thing you did, is an example of selecting
the four lowest bits.

Now, imagine you kept a temporary variable, where the upper bits
were a valid copy of the register in question. Or, you were allowed
to do a read on the register right now. To "not disturb the bits",
you could mask with "& 0xF0" , which makes a copy of the upper
four bits of the byte. Next, "OR" together the desired value
for the lower bits, with the output of the "& 0xF0" step.
When written back, the upper bits will not be disturbed, in the
sense that when the register in the UART is written, you'll be
writing back the identical values for the upper bits.

http://cboard.cprogramming.com/c-pro...r-not-etc.html

"In C you can achieve this by using '&&' for AND, '||' for OR,
'!' for NOT, '^' for XOR, '&' bitwise AND,'|' Bitwise OR ."

http://www.cs.umd.edu/class/spring20...p/bitwise.html

Typically, hardware doesn't allow writing to individual bits.
Usually, the hardware has "registers" or groups of bits, and
the registers are a common width. If you have an eight bit
wide register, and you need to write four bits of it,
you simply write identical values to what are already
stored in the other bits.

If the register contains 0x34 right now, and you want to
write a "5" into the lower bits, you mask and make a copy
of the upper bits (giving 0x30) and bitwise OR that with
the 0x05, giving 0x35 as the result. Then write that to
the UART. The "3" part is then undisturbed. It means,
somehow, you have to keep track of the value of the "undisturbed"
section of the register, in order to know it is 0x30 and
the upper part already holds a "3". That could be done with
a temporary variable, or if the hardware allows it, by doing
a read cycle on the register.

HTH,
Paul

Andre 05-18-2012 08:24 AM

Re: using picc on a pic1f627
 
Le 17/05/2012 10:32, Andre a écrit :
> First, I am retired and doing all this just for fun ;-) and it's a
> looong time since I used C language
>
> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
> still there?
>
> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }
>
> But I keep trying, no luck ( so far )
> Can someone give a hand??
> Many thanks in advances
> André



Many thanks to who responded, but
the pic16f627 has a UART and RB1 (RXD ) and RB2 ( TXD ) are the serial
in/out bits. So reading the 'register' is not a very good option has
between the read and the write back the status of TXD and / or RXD may
have changed ( UART is running in interrupt mode) .
For the moment I am more loking into something like:
if ( registerAB0 ) { RB3 = 1 } else { RB3 = 0 }
if ( registerAB1 ) { RB4 = 1 } else { RB4 = 0 }
and so on.
But seems to me, it's only a temporary solution, a better should be found.
André

BartC 05-18-2012 11:21 AM

Re: using picc on a pic1f627
 


"Andre" <pas.mois@ailleur.be> wrote in message
news:4fb60737$0$3112$ba620e4c@news.skynet.be...
> Le 17/05/2012 10:32, Andre a écrit :
>> First, I am retired and doing all this just for fun ;-) and it's a
>> looong time since I used C language
>>
>> I need to write 4 bits to PORTB without disturbing the others bit
>> RB1, RB2 are ( will be ) used by the UART.
>> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
>> still there?
>>
>> I think I could create a structure ( or a type ) with 4 bits such as
>> BCD { RB3
>> RB4
>> RB5
>> RB6
>> }
>>
>> But I keep trying, no luck ( so far )
>> Can someone give a hand??
>> Many thanks in advances
>> André

>
>
> Many thanks to who responded, but
> the pic16f627 has a UART and RB1 (RXD ) and RB2 ( TXD ) are the serial
> in/out bits. So reading the 'register' is not a very good option has
> between the read and the write back the status of TXD and / or RXD may
> have changed ( UART is running in interrupt mode) .
> For the moment I am more loking into something like:
> if ( registerAB0 ) { RB3 = 1 } else { RB3 = 0 }
> if ( registerAB1 ) { RB4 = 1 } else { RB4 = 0 }
> and so on.
> But seems to me, it's only a temporary solution, a better should be found.


You might need to read the datasheet for the device more carefully, for
example 5.3 I/O Programming Considerations (on p. 42 of the Microchip docs;
other sources may be different): "Caution must be used when these
instructions are applied to a port with both inputs and
outputs defined."

I don't think this is a C coding problem any more, unless your C compiler
provides more facilities than simply reading or writing a byte from a
memory-mapped port.

Perhaps ask in comp.arch or comp.arch.embedded.

--
Bartc



Andre 05-18-2012 04:34 PM

Re: using picc on a pic1f627
 
Le 17/05/2012 10:32, Andre a écrit :
> First, I am retired and doing all this just for fun ;-) and it's a
> looong time since I used C language
>
> I need to write 4 bits to PORTB without disturbing the others bit
> RB1, RB2 are ( will be ) used by the UART.
> If I Mask 4 bits like CC = CC & 0x0F the upper bits are set to 0 but
> still there?
>
> I think I could create a structure ( or a type ) with 4 bits such as
> BCD { RB3
> RB4
> RB5
> RB6
> }
>
> But I keep trying, no luck ( so far )
> Can someone give a hand??
> Many thanks in advances
> André

FYI

I found somthing, not perfect but OK for the moment

unsigned char counter;
#define bit_set(var,bitno) ((var) |= 1 << (bitno))
#define bit_clr(var,bitno) ((var) &= ~(1 << (bitno)))
#define testbit_on(data,bitno) ((data>>bitno)&0x01)

while (1){

if ( testbit_on(counter,3) ) { RB7 = 1; } else { RB7 = 0; }
if ( testbit_on(counter,2) ) { RB6 = 1; } else { RB6 = 0; }
if ( testbit_on(counter,1) ) { RB5 = 1; } else { RB5 = 0; }
if ( testbit_on(counter,0) ) { RB4 = 1; } else { RB4 = 0; }
_delay(10000);
counter++;
if ( counter == 10 ) { counter = 0; }

..
So that seems to work ( At lease with MPLab ;-//
Many thanks
André

BTW: I will bring update on this if there is such interest.


BartC 05-18-2012 05:20 PM

Re: using picc on a pic1f627
 
"Andre" <pas.mois@ailleur.be> wrote in message
news:4fb67a0d$0$3123$ba620e4c@news.skynet.be...

> I found somthing, not perfect but OK for the moment
>
> unsigned char counter;
> #define bit_set(var,bitno) ((var) |= 1 << (bitno))
> #define bit_clr(var,bitno) ((var) &= ~(1 << (bitno)))
> #define testbit_on(data,bitno) ((data>>bitno)&0x01)
>
> while (1){
>
> if ( testbit_on(counter,3) ) { RB7 = 1; } else { RB7 = 0; }
> if ( testbit_on(counter,2) ) { RB6 = 1; } else { RB6 = 0; }
> if ( testbit_on(counter,1) ) { RB5 = 1; } else { RB5 = 0; }
> if ( testbit_on(counter,0) ) { RB4 = 1; } else { RB4 = 0; }


What are RB4, RB5, RB6 and RB7? Special compiler variables?

Anyway, you can probably simplify:

if ( testbit_on(counter,3) ) { RB7 = 1; } else { RB7 = 0; }

to:

RB7 = testbit_on(counter,3)

etc. Probably there is a way of doing all four bits at once; it depends on
how RB7 etc are implemented.

--
Bartc






All times are GMT. The time now is 06:37 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.