Working with Registers

Tips, Tricks and methods for programming, learn ways of making your programming life easier, and share your knowledge with others.

Moderators: Benj, Mods

User avatar
Jay Dee
Posts: 352
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 116 times
Been thanked: 134 times
Contact:

Working with Registers

Postby Jay Dee » Sat Sep 22, 2018 10:57 am

Working With Registers.
Hi Guys, as someone who drops in and out of Flowcode I often forget things so I started to write some of it down. Working with registers is something that took a little while for me to get my head around, so the following may help others who are new on the path to knowledge! Please point out my errors, bound to be a few :) ( as I've smashing this out whilst waiting in the airport)
!Sorry, Had to use lots of code blocks to keep the correct spacing!

(Simply) A register is a storage location on the PIC. These predefined memory slots are used to hold the settings and options for the various features of the PIC. Using the info below you should be able to read, write and modify registers

!! Get the Microchip Datasheet for your PIC. !! Towards the end of each section they list all of the relevant registers.
For some of examples I'm use the PIC18F4455 INTRUPT registers but it can be applied to any register.

Reading a Register
For example INTCON2 the “INTERRUPT CONTROL REGISTER 2”
Create a Byte variable in FC, for example MyReg1

In C component load the register value into the FC variable

Code: Select all

FCV_MYREG1 = INTCON2;

Note that UPPER CASE is used. The FC Variable name is preceded by FCV_ And the ; used at the end of each line.

Back in FC, simply display the value of MyReg1 on an LCD.

Masking a Register
You may only be interested in the state of a single bit, say bit 5. So Mask the value to find the bit state.

Code: Select all

Bit Number      7   6    5    4   3   2   1   0
Binary Value   128  64   32   16  8   4   2   1

To mask for bit 5 and get its Boolean (0 or 1) state;

In a FC calculation component, Bitshift the value by 5 then Bitwise AND by 1.

Code: Select all

Bit5State = ( MyReg1 >> 5 ) & 1

Now simply display the value of Bit5State on your LCD or whatever..

Its the same for any bit...for example, For bit 6 I would Bitshift by 6 and then bitwise AND by 1.

Code: Select all

Bit6State = ( MyReg1 >> 6 ) & 1


Setting/Writing A Register (Byte)
Read the PICs register document and determine what state you need for each bit.

For example,

Code: Select all

Bit Number    7   6   5   4     3   2   1   0
Bit  Value    0   0   1   1     0   0   0   1     (Note this is my desired bit settings)
Hex Value              3               1              (and convert into HEX)

In a C component

Code: Select all

INTCON2 = 0x31


Setting a Specific Bit in a Register
In this example we'll take a source Byte and force bit2 to logic 1 using Bitwise OR.
Note the use of the | (pipe) symbol for Bitwise OR.

Code: Select all

Bit Number      7   6    5    4   3   2   1   0
Binary Value   128  64   32   16  8   4   2   1

Source value    0   0    1    1   0   0   0   1
Bit to Set      0   0    0    0   0   1   0   0
OR them         
Result          0   0    1    1   0   1   0   1

Note the state of bit 2 changed to 1

So in FC, in a calculation component;

Code: Select all

MyReg1 = MyReg1 | 0x04

Note the use of the | (pipe) symbol for Bitwise OR.

Alternatively,I find showing my values a binary can be more readable so I could have done..

Code: Select all

MyReg1 = MyReg1 | 0b00000100


Another Method - Thanks to medelec Martin!
This method is good because you don't have to work out the mask, just know the bit number.
Register = Register | (1<< BitToClear)

Say we want to set Bit 7.
First a mask is made for you by Bit shifting the value 1 right by the bit number.
Bitwise | (Or) the Register with this, to set the specified bit.

Code: Select all

MyReg1 = MyReg1 | (1<<7)

For other bits, just change the value 7.


Clearing a Specific Bit in a Register
In this example we'll take a source Byte and clear bit4 to logic 0, using Bitwise AND
Note the use of the & (Ampersand) symbol for Bitwise AND.

Code: Select all

Bit Number     7   6    5    4    3   2   1   0
Binary Value  128  64   32   16   8   4   2   1

Source value   0    0    1    1   0   0   0   1
Bit to Clear   1    1    1    0   1   1   1   1   (Note the inverted mask in selecting the bit)
AND them         
Result         0    0    1    0   0   1   0   1

Note the state of bit 4 changed to 0

So in FC, in a calculation component;

Code: Select all

MyReg1 = MyReg1 & 0xEF

Alternatively,

Code: Select all

MyReg1 = MyReg1 & 0b11101111


Another Method - Thanks to medelec Martin!
This method is good because you don't have to work out the mask, just know the bit number.
Register = Register & ~(1<< BitToClear)

Say we want to clear Bit 5.
First a mask is made for you by;
Bit shifting the value 1 right by the bit number.
Inverting this byte to give the Mask.
Bitwise & (And) as before to clear the specified bit.

Code: Select all

MyReg1 = MyReg1 & ~(1<<5)

For other bits, just change the value 5. Neat!

Toggling a Specific Bit in a Register
Sometimes you want to toggle a bits state, this can be neater than repeatedly setting and clearing a specific bit in a program.

In this example we'll take a source Byte and toggle bit3, using Bitwise XOR.
Note the use of the ^ (Caret) symbol for Bitwise XOR.

Code: Select all

Bit Number      7    6    5    4   3   2   1   0
Binary Value   128   64   32   16  8   4   2   1

Source value    0    0    1    1   0   0   0   1
Bit to toggle   0    0    0    0   1   0   0   0   
XOR them         
Result          0    0    1    1   1   0   0   1

Note the state of bit 3 toggled to 1
Repeating this will toggle that specific bit back, using exactly the same method.

Code: Select all

Bit Number      7    6    5    4   3   2   1   0
Binary Value   128   64   32   16  8   4   2   1

Prev Result     0    0    1    1   1   0   0   1 (Note the Previous Result of the last operation)
Bit to toggle   0    0    0    0   1   0   0   0 (Note bit mask stays the same)
XOR them         
Result          0    0    1    1   0   0   0   1

Note the state of bit 3 has now toggled back to 0

In a FC calculation component,

Code: Select all

MyReg1 = MyReg1 ^ 0x08

Alternatively,

Code: Select all

MyReg1 = MyReg1 ^ 0b00001000


Reacting to a Specific Bit - Thanks to mnf Martin!
In some situations you may wish to check a specific bit in a register and react based on that bits state.
A good example is when data is received into a buffer and sets a 'flag' bit. By checking for this flag, you can read the buffer only when there is a reason to do so.

By using an Decision block, then bitwise & the Register with a relevant Binary value, you can create two options for you program.

Code: Select all

Bit Number      7    6    5    4   3   2   1   0
Binary Value   128   64   32   16  8   4   2   1

Register & 32 (For reacting to bit 5 being set (Logic 1) )

decision.png
decision.png (7.01 KiB) Viewed 2612 times
Last edited by Jay Dee on Mon Sep 24, 2018 7:25 pm, edited 2 times in total.
These users thanked the author Jay Dee for the post (total 10):
medelec35 (Sat Sep 22, 2018 12:42 pm) • mnf (Sat Sep 22, 2018 2:51 pm) • kersing (Sat Sep 22, 2018 9:29 pm) • Steve (Tue Sep 25, 2018 9:17 am) • Benj (Tue Sep 25, 2018 3:49 pm) • Docara (Wed Sep 26, 2018 6:29 pm) • Steve001 (Fri Oct 05, 2018 12:58 pm) • Zane (Mon Oct 15, 2018 1:39 am) • electronix (Wed Oct 17, 2018 3:43 pm) • ronaldlijs (Thu May 16, 2019 5:25 pm)
Rating: 52.63%
 

kersing
Valued Contributor
Valued Contributor
Posts: 1873
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 530 times
Been thanked: 1040 times
Contact:

Re: Working with Registers

Postby kersing » Sat Sep 22, 2018 12:17 pm

Jay,

Great write-up.

Did you test

Code: Select all

Bit5State = ( MyReg1 >> 5 ) & 32


Because I think you need to use the '&' before shifting or '&' with 1. Now if the value is 32 the result is:
32 = 0010 0000
0010 0000 >> 5 = 0000 0001
0000 0001 & 0010 0000 (32) = 0
These users thanked the author kersing for the post:
Jay Dee (Sat Sep 22, 2018 12:55 pm)
Rating: 5.26%
 
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

User avatar
Jay Dee
Posts: 352
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 116 times
Been thanked: 134 times
Contact:

Re: Working with Registers

Postby Jay Dee » Sat Sep 22, 2018 1:03 pm

Thanks Kersing!
Yep, my mistake. Original post now updated.
Its good to have online proof reading! :)

mnf
Valued Contributor
Valued Contributor
Posts: 507
Joined: Wed May 31, 2017 11:57 am
Has thanked: 52 times
Been thanked: 279 times
Contact:

Re: Working with Registers

Postby mnf » Sat Sep 22, 2018 3:02 pm

Thanks Jay,

An excellent guide.

A couple of tweaks - you'd got ^ as Bitwise AND (correct as XOR in previous line) - I've edited for you.

You can get a small speed increase by using the fact that C (and hence Flowcode) uses any non-zero value as true.

Thus you can do:
decision.png
decision.png (7.01 KiB) Viewed 2657 times

Code: Select all

if (register & 32) then
//   Bit 5 is set
// Check bit 5

But whether getting rid of the shift - and the resultant speed gains - are worth the reduction in readability is dependent on your application

Martin
These users thanked the author mnf for the post:
Jay Dee (Sat Sep 22, 2018 3:13 pm)
Rating: 5.26%
 

User avatar
medelec35
Valued Contributor
Valued Contributor
Posts: 8378
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2384 times
Been thanked: 3416 times
Contact:

Re: Working with Registers

Postby medelec35 » Mon Sep 24, 2018 7:13 am

Hi Jay, Thanks for the great write up.
There is another way of clearing a bit by using the bit number in question.
You may want to do that if the bit in question is contained within a variable.
I.e

Code: Select all

Result  =  Result & ~(1 << BitToClear)

For example to clear bit 3, you can use:

Code: Select all

Result  =  Result & ~(1 << 3)
These users thanked the author medelec35 for the post:
Jay Dee (Mon Sep 24, 2018 3:05 pm)
Rating: 5.26%
 
Martin

If you read a post that is useful, please show appreciation by clicking on thumbs up Icon.

User avatar
Jay Dee
Posts: 352
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 116 times
Been thanked: 134 times
Contact:

Re: Working with Registers

Postby Jay Dee » Mon Sep 24, 2018 7:26 pm

Great stuff! suggestions added into original doc. Thanks Guys.
These users thanked the author Jay Dee for the post:
medelec35 (Mon Sep 24, 2018 9:24 pm)
Rating: 5.26%
 

Docara
Posts: 285
Joined: Sun Jun 23, 2013 1:29 pm
Has thanked: 21 times
Been thanked: 58 times
Contact:

Re: Working with Registers

Postby Docara » Wed Sep 26, 2018 6:35 pm

Hi Jay,

Fantastic post!! I have learnt a lot

Cant wait for the next installment - cough! cough! :D

Matt

User avatar
Jay Dee
Posts: 352
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 116 times
Been thanked: 134 times
Contact:

Re: Working with Registers

Postby Jay Dee » Fri Oct 05, 2018 12:00 pm

Can someone confirm this is a sensbile way to do the following! :)

I wish to over write the lower 4 bits of a 8 bit register....so I think my process should be

Code: Select all

7   6   5   4   3   2   1   0     Bit Number
   
1   0   1   0   1   0   1   0     This is the Original Register Value
1   1   1   1   0   0   0   0     AND by this mask to clear lower four bits
1   0   1   0   0   0   0   0     Intermediate Result

0   0   0   0   0   1   1   1     OR by this new mask, with previous result, to Set lower four bits
1   0   1   0   0   1   1   1     Final Result and New register Value to be written to Register. 

I'm pretty sure it should work..but it this the correct 'I know what I'm doing' way ?? :)
These users thanked the author Jay Dee for the post:
kersing (Fri Oct 05, 2018 12:05 pm)
Rating: 5.26%
 

kersing
Valued Contributor
Valued Contributor
Posts: 1873
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 530 times
Been thanked: 1040 times
Contact:

Re: Working with Registers

Postby kersing » Fri Oct 05, 2018 12:07 pm

but it this the correct 'I know what I'm doing' way ??

That is the way I’ve been doing it for years.
These users thanked the author kersing for the post:
Jay Dee (Fri Oct 05, 2018 12:51 pm)
Rating: 5.26%
 
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

User avatar
LeighM
Matrix Staff
Posts: 1873
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 438 times
Been thanked: 625 times
Contact:

Re: Working with Registers

Postby LeighM » Fri Oct 05, 2018 12:10 pm

Sure is :)


Code: Select all

register = (register AND 0xF0) OR new_value

register = (register & 0xF0) | new_value;
These users thanked the author LeighM for the post:
Jay Dee (Fri Oct 05, 2018 12:51 pm)
Rating: 5.26%
 

User avatar
Steve001
Valued Contributor
Valued Contributor
Posts: 1081
Joined: Wed Dec 31, 2008 3:37 pm
Has thanked: 440 times
Been thanked: 489 times
Contact:

Re: Working with Registers

Postby Steve001 » Fri Oct 05, 2018 1:00 pm

Hi guys

Great post very informative, need to have another read through when I get more time
Have bookmarked it :D

Steve
Success always occurs in private and failure in full view.