View previous topic :: View next topic |
Author |
Message |
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Tue Oct 11, 2016 9:46 pm Post subject: Combing 2 strings |
|
|
Ok, Why doesn't this work? (obviously I'm making a mistake somewhere!
What I want to do is take 2 strings and combine them (not concatenate them)....
Code: |
$regfile = "m2561def.dat"
$crystal = 16000000
$hwstack = 400
$swstack = 550
$framesize = 345
$Baud = 9600
UCSR0A.U2X = 0
Dim A As Byte
Dim TempChar As String * 1
Dim TempChar2 As String * 1
Dim SetPointString As String * 32
Dim SetPointString2 As String * 32
SetPointString = "00000000000000000000000000010010"
SetPointString2 = "00000000000000000000000000001101"
For A = 1 to 32
TempChar = Mid(SetPointString , A , 1)
TempChar2 = Mid(SetPointString2 , A , 1)
If TempChar <> TempChar2 Then Mid(SetPointString , A , 1) = TempChar2
Next
Print "SetPointString After " ; SetPointString |
I expect the result to be 00000000000000000000000000011111 but as you see, it doesn't seem to work out that way!
(BASCOM-AVR version : 2.0.7.9 , Latest : 2.0.7.8 ) |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Tue Oct 11, 2016 9:57 pm Post subject: |
|
|
OK, I see why it doesn't work..duh....but now how to make it work? |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Tue Oct 11, 2016 10:31 pm Post subject: Re: Combing 2 strings |
|
|
KenHorse wrote: | ....but now how to make it work? |
Code: | If TempChar <> TempChar2 Then Mid(SetPointString , A , 1) = "1" |
Btw., string representation of binary data is quite inefficient, isn't it? |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Tue Oct 11, 2016 11:45 pm Post subject: |
|
|
I plan to use the first string that is a string representation of a Dword stored in ERAM. That way I can store bits in ERAM. The 2nd string is the result of an entered number (1 - 32) that is shifted LEFT based on the value of number entered. It then gives me a 2nd string representation of another Dword. The 32 "bits" are then used as flags to represent the whether position X is 1 or 0 instead of a 2D array, which would take more ERAM space than I have left in an existing design.
So this will have to do![/code] |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Oct 12, 2016 1:01 am Post subject: |
|
|
Quote: | If TempChar <> TempChar2 Then Mid(SetPointString , A , 1) = "1" |
That works if there was a 0 that needs to be replaced with a 1 but it doesn't work if there is a 1 that needs to be changed to a 0.
I'm still playing! |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Wed Oct 12, 2016 3:01 am Post subject: |
|
|
I`m steel not get it
Each letter/char needs one byte to code it in ASCII
Where You can store four bytes variable in Eram, read it and store into some four bytes variable.
Then You can easy test any bit for example "If Dword_var.30 = 1 Then..."
also You must know that ASCII representation is only shifted by 48
So if You substract form binary representation 48 and value is from 0 to 9 then this is the number/digit |
|
Back to top |
|
|
O-Family
Joined: 23 May 2010 Posts: 320 Location: Japan
|
Posted: Wed Oct 12, 2016 5:46 am Post subject: |
|
|
Code: |
$regfile = "m2561def.dat"
$crystal = 16000000
$hwstack = 400
$swstack = 550
$framesize = 345
$Baud = 9600
UCSR0A.U2X = 0
Dim A As Byte
Dim Dw1 As Dword , Dw2 As Dword
Dim Tempchar As String * 1
Dim Tempchar2 As String * 1
Dim Setpointstring As String * 32
Dim Setpointstring2 As String * 32
Setpointstring = "00000000000000000000000000010010"
Setpointstring2 = "00000000000000000000000000001101"
Dw1 = Binval(setpointstring)
Dw2 = Binval(setpointstring2)
Dw1 = Dw1 Xor Dw2
Setpointstring = Bin(dw1)
Print "SetPointString After " ; Setpointstring
End
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Oct 12, 2016 6:47 am Post subject: |
|
|
KenHorse wrote: | That works if there was a 0 that needs to be replaced with a 1 but it doesn't work if there is a 1 that needs to be changed to a 0. |
That was not clear from your example, actually you want a XOR, but the desired result can be achieved with an OR.
It's easy, all you have to do is add an else-branch.
Code: | If TempChar <> TempChar2 Then Mid(SetPointString , A , 1) = "1" |
Code: | else Mid(SetPointString , A , 1) = "0" |
|
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Oct 12, 2016 4:25 pm Post subject: |
|
|
Thanks for the continuing ideas but I'm afraid nothing works as I need it to work
If a "bit" is set in setpointstring (setpointstring is the result of ERAM), it should only be changed by setpointstring2 if the "bit" in setpointstring2 in the corresponding position is different. In other words, If there is a 0 in setpointstring at position 3 and a 1 in setpointstring2 at position 3, then setpointstring's position 3 should be changed to a 1.
Likewise if there is a 1 in setpointstring at position 3 and a 0 in setpointstring2 at position 3, then setpointstring's position 3 should be changed to a 0. The same applies to other "bits" at other positions
The idea being that if a particular "bit" stored in ERAM is set one way, it should only be changed if setpointstring2 differs at the same position. I hope I'm being clear enough (no guarantees!)
In the example below, bits are changed that should not be. I desire the result of the following to be 00000000000000000000000000001101 not what it is
Try this code and you'll see what I mean
Code: | $regfile = "m2561def.dat"
$crystal = 16000000
$hwstack = 400
$swstack = 550
$framesize = 345
$Baud = 9600
UCSR0A.U2X = 0
Dim A As Byte
Dim Dw1 As Dword , Dw2 As Dword
Dim Tempchar As String * 1
Dim Tempchar2 As String * 1
Dim Setpointstring As String * 32
Dim Setpointstring2 As String * 32
Setpointstring = "00000000000000000000000000011111"
Setpointstring2 = "00000000000000000000000000001101"
Print "SetPointString " ; SetPointString
Print "SetPointString2 " ; SetPointString2
Dw1 = Binval(setpointstring)
Dw2 = Binval(setpointstring2)
Dw1 = Dw1 Xor Dw2
Setpointstring = Bin(dw1)
Print "SetPointString After " ; Setpointstring
End
|
|
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Oct 12, 2016 6:37 pm Post subject: |
|
|
KenHorse wrote: | I desire the result of the following to be 00000000000000000000000000001101 not what it is |
The "function" matching your request
Quote: | If there is a 0 in setpointstring ... and a 1 in setpointstring2 ... then setpointstring ... should be changed to a 1.
if there is a 1 in setpointstring ... and a 0 in setpointstring2 ... then setpointstring ... should be changed to a 0. |
is, tattaaa
Code: | Setpointstring = Setpointstring2 |
|
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Oct 12, 2016 7:19 pm Post subject: |
|
|
Sorry, I'm not explaining myself very well (in fact, I think I've done a terrible jobs so far).
I'll try it one more time and if that doesn't suffice, I'll just drop it to avoid wasting anyone's time any further.....
Let's say the Dword stored in ERAM is &B00000000000000000000000000010101
I read this ERAM Dword into a string variable so it can be manipulated in my code:
Code: |
Dim TempDWord as DWord
Dim Set_SetPointMOY As ERAM DWord
Dim B As Byte
Dim SetPointString As String * 32
Dim SetPointString2 As String * 32
TempDWord = Set_SetPointMOY
SetPointString = Bin(TempDWord) |
Another string is created by using SHIFT and that string will NEVER contain more than one "1":
Code: |
Function Setbits(ByVal Number As Byte) As String
Local BitMask As DWord
BitMask = 1
Shift BitMask , Left , Number - 1
Setbits = Bin(BitMask)
End Function |
So I call the above function:
Code: |
Input "Enter a value between 1 and 32: " , B
SetPointString2 = SetBits(B)
Print "SetPointString2 " ; SetPointString2
|
The above all works fine. So let's say I enter a 4. The resultant SetPointString2 is 00000000000000000000000000001000, right?
What I want to do after SetPointString2 is created, is to then compare that string to SetPointString, leave ALL THE OTHER BIT "POSITIONS" alone and only set the one in position 4. So the resulting SetPointString becomes 00000000000000000000000000011101.
Whew...... |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Oct 12, 2016 7:43 pm Post subject: |
|
|
KenHorse wrote: | leave ALL THE OTHER BIT "POSITIONS" alone and only set the one in position 4. |
That's the classic OR
Quote: | So the resulting SetPointString becomes 00000000000000000000000000011101. |
as this code proves:
Code: | $Regfile = "m328pdef.dat"
$Crystal = 16000000
$hwstack = 64
$swstack = 32
$framesize = 32
Dim A As DWord
Dim B As DWord
Dim C As DWord
A = &b00000000000000000000000000010101
B = &b00000000000000000000000000001000
C = A Or B
Print Bin(C)
End |
As you do it more complicated with Strings
Code: | If TempChar2 = "1" Then Mid(SetPointString , A , 1) = "1" |
Edit:
And as we now know why you want to reverse strings, see the other thread, this is the equivalent of reversing string "bits" - takes less memory and only 125 cycles.
Code: | $Regfile = "m328pdef.dat"
$Crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 64
$Noramclear
Declare Sub RevBits(src_bits As DWord)
Dim A As DWord
Dim B As DWord
Dim C As DWord
A = &b00000000000000000000000000010101
B = &b00000000000000000000000000001000
C = A Or B
Print Bin(C)
RevBits C
Print Bin(C)
End
Sub RevBits(src_bits As DWord)
LoadAdr src_bits , X
!LD R16, X+
!LD R17, X+
!LD R18, X+
!LD R19, X
!LDI R24, 8
!RotBits:
!LSL R16
!ROR R23
!LSL R17
!ROR R22
!LSL R18
!ROR R21
!LSL R19
!ROR R20
!DEC R24
!BRNE RotBits
LoadAdr src_bits , X
!ST X+, R20
!ST X+, R21
!ST X+, R22
!ST X, R23
End Sub |
|
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Oct 12, 2016 9:32 pm Post subject: |
|
|
That works to set a previously set 0 bit in SetPointString to 1 just fine. However it doesn't change a 1 back to a 0 in SetPointString if that position in SetPointString2 has a 0 in that position
Arrrghh.....
I need to rethink this whole concept... thanks for your time fellas |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Wed Oct 12, 2016 10:33 pm Post subject: |
|
|
KenHorse wrote: | However it doesn't change a 1 back to a 0 in SetPointString if that position in SetPointString2 has a 0 in that position |
You contradict yourself.
Quote: | alone and only set the one in position 4. |
It would be possible to use a mask-bit, at which position the value of a bit of bit-array A is copied into same position of bit-array B. But it makes no sense to think about such, as long the impression prevails, that you do not know what you want.
Maybe your biggest mistake is to describe unsuitable approaches, instead of describing the purpose for which then a solution can be found. |
|
Back to top |
|
|
KenHorse
Joined: 16 Jul 2004 Posts: 523
|
Posted: Wed Oct 12, 2016 11:27 pm Post subject: |
|
|
Fair enough. I really do know exactly what I want, I'm just doing a very poor job of explaining it.
I'm trying use as little ERAM space as possible and this ERAM is to be used to represent an ON/OFF condition for 32 different software switches, which are either ON or OFF. If I were to do this using an array, it would take 32 bytes of ERAM which I do not have available. So it struck me I could use a Dword (which has 32 bits) and only takes 4 bytes of ERAM if I could set individual bits of that Dword as needed ON or OFF (1 or 0).
I'm taking user input in the form of a decimal number 1 to 32, shifting that within another (SRAM) Dword to represent that entered number based on the location within that Dword. LSB would represent the number 1 and MSB would represent the number 32 and everything in between. I then wanted to take that user-shifted Dword, compare it to the stored ERAM Dword and if there is a difference IN THAT POSITION ONLY, change only that position leaving all previous positions untouched in ERAM. The use of a string was to (in my mind at least) give us an index of sorts as each bit could be parsed and location of a particular 1 determined
Does that help? |
|
Back to top |
|
|
|