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

Post Reply
User avatar
Jay Dee
Posts: 398
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 121 times
Been thanked: 154 times
Contact:

Working with Registers

Post by Jay Dee »

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
(7 KiB) Downloaded 5470 times
Last edited by Jay Dee on Mon Sep 24, 2018 7:25 pm, edited 2 times in total.

kersing
Valued Contributor
Valued Contributor
Posts: 2045
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 553 times
Been thanked: 1081 times
Contact:

Re: Working with Registers

Post by kersing »

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
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

User avatar
Jay Dee
Posts: 398
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 121 times
Been thanked: 154 times
Contact:

Re: Working with Registers

Post by Jay Dee »

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

mnf
Valued Contributor
Valued Contributor
Posts: 1188
Joined: Wed May 31, 2017 11:57 am
Has thanked: 70 times
Been thanked: 439 times
Contact:

Re: Working with Registers

Post by mnf »

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
(7 KiB) Downloaded 5515 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

medelec35
Matrix Staff
Posts: 9520
Joined: Sat May 05, 2007 2:27 pm
Location: Northamptonshire, UK
Has thanked: 2585 times
Been thanked: 3815 times
Contact:

Re: Working with Registers

Post by medelec35 »

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)
Martin

User avatar
Jay Dee
Posts: 398
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 121 times
Been thanked: 154 times
Contact:

Re: Working with Registers

Post by Jay Dee »

Great stuff! suggestions added into original doc. Thanks Guys.

Docara
Posts: 315
Joined: Sun Jun 23, 2013 1:29 pm
Has thanked: 28 times
Been thanked: 61 times
Contact:

Re: Working with Registers

Post by Docara »

Hi Jay,

Fantastic post!! I have learnt a lot

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

Matt

User avatar
Jay Dee
Posts: 398
Joined: Tue Aug 18, 2009 6:42 pm
Has thanked: 121 times
Been thanked: 154 times
Contact:

Re: Working with Registers

Post by Jay Dee »

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 ?? :)

kersing
Valued Contributor
Valued Contributor
Posts: 2045
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 553 times
Been thanked: 1081 times
Contact:

Re: Working with Registers

Post by kersing »

but it this the correct 'I know what I'm doing' way ??
That is the way I’ve been doing it for years.
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: Working with Registers

Post by LeighM »

Sure is :)

Code: Select all

register = (register AND 0xF0) OR new_value

register = (register & 0xF0) | new_value;

User avatar
Steve001
Valued Contributor
Valued Contributor
Posts: 1189
Joined: Wed Dec 31, 2008 3:37 pm
Has thanked: 460 times
Been thanked: 523 times
Contact:

Re: Working with Registers

Post by Steve001 »

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.

Post Reply