|
|
View previous topic :: View next topic |
Author |
Message |
jani20
Joined: 14 Nov 2006 Posts: 14
|
How to reference a bit in an int16 array? |
Posted: Tue Nov 14, 2006 9:45 am |
|
|
Hello!
Pls help me to reference a bit in an int16 array.
Like in PIC Basic.
http://www.picbasic.co.uk/forum/showthread.php?t=544
How can I do that in CCS?
Code: |
MyArray var word[5]
MyArray.0(43)=1
|
Thank you! |
|
|
Ttelmah Guest
|
|
Posted: Tue Nov 14, 2006 10:04 am |
|
|
There is not real advantage to using words, rather than bytes (remember the RAM is always byte orientated), but if you just want to treat the word array as if it was an array of bits, something like:
#define read_bitn(x,y) bit_test(*((int*)x+(y>>3)),y&7)
#define set_bitn(x,y) bit_set(*((int*)x+(y>>3)),y&7)
#define clear_bitn(x,y) bit_clear((*((int*)x+(y>>3)),y&7)
accessed with:
int16 Myarray[5];
set_bitn(MyArray,43);
Which will set the 43rd bit in the array.
The other functions will clear/read the bits respectively.
Best Wishes |
|
|
jani20
Joined: 14 Nov 2006 Posts: 14
|
|
Posted: Tue Nov 14, 2006 10:23 am |
|
|
Thanks!
But isnt that simplier when I make a bit array?
like this:
There is a 10bit ADC value in this 48 bit Myarray.
And I want to save out this 10 bits to an int16 temp.
Can I use custom pointer? Like: I choose the begining position of the
10bits in the RAM, and can I set a custom length for the pointer?
Like 10bits (and not 8 or 16)? |
|
|
jani20
Joined: 14 Nov 2006 Posts: 14
|
|
Posted: Tue Nov 14, 2006 11:29 am |
|
|
I tried to dived the 10bit to an 8bit pointer, and 2 one bit pointer.
But its says that pointing to a bit is not permitted:(
Your first code is a bit comlicated to me.
And the speed is also important.
I have 4 10bits in the array, when I save it out I think it would take a lot of time because this long define line.
in Basic I did it like this:
Code: |
Repeat
ch1.0(i)=Myarray.0(i)
ch2.0(i+10)=Myarray.0(i+10)
ch3.0(i+20)=Myarray.0(i+20)
ch4.0(i+30)=Myarray.0(i+30)
i=i+1
Until i=10 '0-9
|
Or simething like that.
If somebody has a good (and relative fast:) idea, please write it!
Thx! |
|
|
Ttelmah Guest
|
|
Posted: Tue Nov 14, 2006 11:36 am |
|
|
jani20 wrote: | Thanks!
But isnt that simplier when I make a bit array?
like this:
There is a 10bit ADC value in this 48 bit Myarray.
And I want to save out this 10 bits to an int16 temp.
Can I use custom pointer? Like: I choose the begining position of the
10bits in the RAM, and can I set a custom length for the pointer?
Like 10bits (and not 8 or 16)? |
CCS, does not support bit arrays, except in V4, which still has so many other errors, that it is better avoided...
The actual assembler generated from the 'long define line', is about as short as possible.
Best Wishes |
|
|
jani20
Joined: 14 Nov 2006 Posts: 14
|
|
Posted: Wed Nov 15, 2006 12:53 am |
|
|
Is there anyway to freely align an 8bit size pointer?
(bit aligned instead of byte?) (maybe in assembly?)
If this is possible some how than I could copy the 10bits
with 2 8bit pointer (overlaped each other in 6 bits).
Is it possible?
OR
I wrote this in PicBasic:
Code: |
Backup var byte[6] 'in bit: 0-47 8*6bit
channels var word[3] 'in bit: 0-47 3*16bit
counter var byte
Repeat
channels.0(counter+32)=Backup.0(counter+18)
channels.0(counter+16)=Backup.0(counter+28)
channels.0(counter) =Backup.0(counter+38)
counter=counter+1
Until counter=10 '0-9
'each elements of channels[] will hold 10bits
|
And it generated this in the ASM file:
Code: |
RAM_START EQU 00020h
_Backup EQU RAM_START + 01Ch
_channels EQU RAM_START + 022h
_counter EQU RAM_START + 028h
T1 EQU RAM_START + 012h
T2 EQU RAM_START + 014h
#define _channels_0 _channels, 000h
#define _Backup_0 _Backup, 000h
INCLUDE "TE.MAC"
INCLUDE "PBPPIC14.LIB"
LABEL?L L00001
ADD?BCW _counter, 020h, T2
ADD?BCW _counter, 012h, T1
AOUT?TWW _Backup_0, T1, T1
AIN?WTW T1, _channels_0, T2
ADD?BCW _counter, 010h, T2
ADD?BCW _counter, 01Ch, T1
AOUT?TWW _Backup_0, T1, T1
AIN?WTW T1, _channels_0, T2
ADD?BCW _counter, 026h, T1
AOUT?TWW _Backup_0, T1, T1
AIN?WTB T1, _channels_0, _counter
ADD?BCB _counter, 001h, _counter
CMPNE?BCL _counter, 00Ah, L00001
LABEL?L L00002
END
|
How this code is references to Bit in memory?
Is there anyway to do this in C, or simplier in ASM? |
|
|
Ttemah Guest
|
|
Posted: Wed Nov 15, 2006 6:28 am |
|
|
The output code you post, is not the assembler. Most of the commands, are _macros_, which will expand to extra code, in the actual assembler.
There is no way to directly access a bit array in the PIC processor. The basic, has a set of assembler macros, which do this, and are being used in the code you show. Guess what, they produce very similar code to the C macros I posted...
Best Wishes |
|
|
jani20
Joined: 14 Nov 2006 Posts: 14
|
|
Posted: Wed Nov 15, 2006 11:29 am |
|
|
Ok. Can you give some advice about how can I find more info about your C macro? Im just interested in the bit read line.
Is there any similar code explained in some documents, or online?
I searched google but nothing but nothing useable results.
Thank you. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 15, 2006 12:41 pm |
|
|
if you are just trying to extract the 10bit values out of the array of bytes, then take a look at the rotate_left() or rotate_right() functions. You can rotate the value right by the correct number of bits so that the result is right justified. Then just take the first 2 bytes of the array and treat it as an int16. And this with 0x3FF to get the 10 bit result. |
|
|
Ttelmah Guest
|
|
Posted: Wed Nov 15, 2006 1:32 pm |
|
|
The macros are just simple arithmetic. You can access an area of memory, as if it is an array of bytes, using C pointers. So if you have the address of an array (the name of an array, is it's address), and this is treated as an 'int' pointer, then:
*(name)
accesses the byte at this address. While:
*(name+1)
accesses the next byte.
Now because the array used, can be int8, or int16 or int32 values, to ensure that the compiler accesses it a byte at a time, a 'cast' is used:
*((int *)name)
ensures that all the pointer arithmetic is dealing with int8 values (CCS defaults to doing this, but the cast _makes sure_).
Now if you have a 'bit address', you need to access the byte corresponding to this address/8. Division is slow, but binary division (/2, /4 etc.), can be done by simply rotating the value, and is quick. So, given a bit number, the required byte, is accessed with:
*((int*)name+(bit_no>>3))
This takes the bit number/8, and adds it to the address, to find the required byte.
Now you have to access the bit in the byte.
CCS provides a set of functions (bit_set etc.), which access a specified bit in a byte. The bit to be accessed, is the remainder after the division by 8. This is also the low three bits of the original value. This is obtained using:
bit_no&7
Replace 'bit_no', and 'address', with x & y in the macro definitions, and you are there.
Best Wishes |
|
|
jani20
Joined: 14 Nov 2006 Posts: 14
|
|
Posted: Thu Nov 16, 2006 9:08 am |
|
|
Thats is, the bit_test function!!!!
I miss that out in the manual:(
But now I can do everything with this function and a pointer :D
Thank you very much! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|