HCBBS Forum (English)
Submit Chemical Projects / Find Solutions
Amplify Your Requirements on a Broader Chemical Platform *Engineering · Technology · Equipment · Solutions*
Submit Request

Detailed Explanation of Address Concepts in Step7 Programming

2008-01-10View Original

Thread Content

A complete instruction should consist of an operator plus operands (of course, this does not apply to single-instruction commands such as NOT). The operand in this context refers to the target that the instruction is intended to operate on, that is, the address on which the instruction will perform its action.      We know that in a PLC, there are various storage areas designated for different purposes, such as the physical input/output area P, the image input area I, the image output area Q, the bit storage area M, timers T, counters C, data areas DB and L, etc. We also know that each of these areas can be measured, or rather have its exact size specified, in terms of bits (BIT), bytes (BYTE), words (WORD), and double words (DWORD). Of course, timers T and counters C do not have such a measurement system; they are measured only in bits. From this, we can conclude that to describe an address, at least two elements are required: 1) the storage area, and 2) the specific location within that area. For example, in A Q2.0, A is the identifier, while Q2.0 is the operand of A, which constitutes the address. This address consists of two parts:   Q: refers to the image output area.   2.0: is the 0th bit of the second byte in this image output area.   Thus, we conclude that the exact format of an address should be: 〖Storage Area Symbol〗〖Storage Area Size Symbol〗〖Size Value〗.〖Bit Value〗, for example: DBX200.0.   DB X 200.0 Here, we refer to the〖storage area symbol〗 and 〖storage area size symbol〗 together as the address identifier. Thus, a precise address composition can also be written as: Address identifier + precise numerical unit. 【Concept of indirect addressing】 Addressing refers to specifying the address on which an instruction is to operate. The address method for a given instruction operation is the addressing method.   Before discussing indirect addressing, let’s briefly understand direct addressing. Direct addressing, in simple terms, means providing the exact operands for an instruction directly. As mentioned above, A Q2.0 is an example of direct addressing; for the A instruction, Q2.0 is the address on which it operates.      In this light, indirect addressing means providing the exact operands of an instruction indirectly. Yes, that’s the concept.      For example: A Q, A T. The contents marked with square brackets in the program statements indirectly indicate the address at which the instruction should be executed. MD100 and DBW100 in these two statements are known as pointers; they point to the values contained within them, which represents the exact location of the address area where the instruction should actually be carried out. It gets its name indirectly from this.      Siemens' indirect addressing methods fall into two main categories: memory indirect addressing and register indirect addressing.   【Indirect Memory Addressing】 The address format for indirect memory addressing is: address identifier + pointer. The value contained in the storage unit indicated by the pointer is the exact numerical value of the address.      Memory indirect addressing has two pointer formats: word and double word.      The word pointer is a 16-bit structure; its bits range from 0 to 15, indicating a value from 0 to 65535, and this value is the address of the memory area being accessed.      A double-word pointer is a 32-bit structure consisting of 3 bits, ranging from 0 to 2; these bits indicate the address of the bit being referenced in octal format, that is, from 0 to 7 ; The 16 bits, ranging from 3 to 18 bits, indicate a value from 0 to 65535; this value is the address of the byte in question.      Pointers can be stored in the M, DI, DB, and L areas; in other words, the contents of these areas can be used as pointers.      There are significant differences in usage between single-word pointers and double-word pointers. Here are some examples:   L DW#16#35 //Stores the 32-bit hexadecimal value 35 in ACC1.   T MD2 //This value is then stored in MD2, which is a 32-bit bit storage area.   L +10 //Stores the 16-bit integer 10 in ACC1; the 32-bit hexadecimal value 35 is automatically moved to ACC2.   T MW100 //This value is then stored in MW100, which is a 16-bit bit storage area.   OPN DBW //Opens DBW10. Here, it is a single-word pointer; the area where the pointer is stored is region M. The value 10 in MW100 represents the address indirectly specified by the pointer, and it is a 16-bit value!      --------      L L#+10 //In 32-bit format, 10 is stored in ACC1; at this point, the content of ACC2 is: a 16-bit integer of 10. T MD104 //This value is then stored in MD104, which is a 32-bit storage area. A I //Perform an AND operation on I1.2!      =DIX //Assign background data bit DIX6.5!      --------       A DB.DBX // Read the data bit status of DB10.DBX6.5     =Q // Assign it to Q6.5     --------     A DB.DBX // Read the data bit status of DB10.DBX6.5     =Q // Error! ! There is no component called Q10. ----------------------------------------------------------------------------------------- From the examples in the above series, we can at least see one thing: Single-character pointers should only be used when the address identifier is not a bit. Indeed, as described earlier, a single-word pointer has a value range of 0-65535, whereas for specific bit structures such as byte.bit, a double-word pointer is required. This is their first difference. Another limitation of word pointers is that they can only be used to address T, C, DB, FC, and FB; in other words, word pointers can only be used to refer to the identifiers of these memory areas.      Unlike single-word pointers, double-word pointers do not have such limitations; they can address bit addresses as well as BYTE, WORD, and DWORD values, and there are no restrictions on the range of addresses they can access. However, there is a trade-off: when addressing non-bit regions, it is necessary to ensure that their 0-2 bits are all 0!      In summary: Indirect memory addressing using a single-word pointer can only be used when the address identifier is not a bit ; Due to the bit format, double-word pointers have no restrictions on address identifiers. It is also because a double-word pointer is a pointer with bits that, when addressing byte, word, or double-word memory locations, it is necessary to ensure that the content of the double-word pointer is 8 or a multiple of 8.      Now, let’s analyze why AI in the above example ultimately performs an AND logical operation on I1.2.      Through L L#+10, we know that the value stored in MD104 should be: MD104: 0000 0000 0000 0000 0000 0000 0000 1010. When used as a double-word pointer, the bytes are specified by bits 3–18 and the bits are specified by bits 0–2, in order to determine the address on which the instruction will operate; therefore: 0000 0000 0000 0000 0000 0000 0000 1010 = 1.2. [Indirect addressing via address register] In the indirect addressing of memory mentioned earlier, the indirect pointers are specified directly using M, DB, DI, and L; in other words, the content of the memory location pointed to by the pointer represents the exact address value at which the instruction will be executed. But in register indirect addressing, the actual address value unit that the instruction is to execute is not the content of the memory area pointed to by the register; in other words, the register itself also indirectly points to the real address value unit. From the register to the actual address value unit, Siemens provides two approaches: 1. Register indirect addressing within a region; 2. Register indirect addressing between regions. The general format for address register indirect addressing is: 【Address identifier】【Register, P#byte.bit】, such as DIX or M.   〖Register, P#byte.bit〗 is collectively referred to as the register addressing pointer, while the 〖address identifier〗 was discussed in the previous post; it consists of the 〖memory area symbol〗 + 〖memory area size symbol〗. But here, the situation has changed. Compare it with the example from earlier: DIX X. DIX can be considered as the address identifier as we usually define it; DI represents the storage area for background data blocks, while X is a size indicator for this storage area, referring to the number of bits in the background data blocks. But what about M in the next example? X is merely a size specifier for the storage area; so where is the storage area specifier? Without a doubt, in AR1!   In the DIX example, the address range to be addressed is determined in advance; what AR1 can change are only the specific address values within that range. Therefore, this is referred to as register indirect addressing within a range, and the corresponding element here is called the range addressing pointer.      In this X example, neither the address range to be addressed nor the specific address values are determined in advance; only the storage size is specified. This means that we can address different address values within various ranges using the given range size, and therefore this is referred to as inter-region register indirect addressing. Correspondingly, the element used here is called an inter-region addressing pointer.      Since there is a distinction between intra-regional and inter-regional addressing, different contents are stored within the same AR1, each representing a different meaning.      【Format of AR】 The address register is a special pointer area dedicated to addressing. Siemens has two address registers in total: AR1 and AR2, each being 32 bits long.      When used in in-register indirect addressing within a region, we know that the content in the AR merely indicates a value unit; therefore, in in-register indirect addressing, the content of the register is equivalent to the double-word pointer used in memory indirect addressing as mentioned earlier. Specifically, its bits 0-2 designate the bit position, while bits 3-18 designate the bytes. Its 31st bit is fixed at 0.   AR: 0000 0000 0000 0BBB BBBB BBBB BBBB BXXX. With this specification, the possible values for AR are 0.0 to 65535.7. For example, when AR = D4 (hex) = 0000 0000 0000 0000 0000 0000 1101 0100 (in binary), it is equivalent to 26.4.      In inter-register indirect addressing, since the region to be addressed also needs to be specified in the AR, it is clear that the requirements for the content of the AR in this case are different from those in register-based indirect addressing.      AR: 1000 0YYY 0000 0BBB BBBB BBBB BBBB BXXX. By comparing the differences between these two formats, we find that the 31st bit is fixed at 1, while bits 24, 25, and 26 have allowable value ranges. You being smart, you can surely figure out that this is used to specify the storage area. Yes, the values of bits 24–26 determine the area to be addressed. These values are defined as follows:
Area identifier: Bits 26, 25, 24
P (External input/output): 000
I (Input image area): 001
Q (Output image area): 010
M (Bit storage area): 011
DB (Data block): 100
DI (Background data block): 101
L (Temporary data area, also known as local data): 111

If we represent such AR values in HEX format, then:
When addressing the P area, AR = 800xxxxx
When addressing the I area, AR = 810xxxxx
When addressing the Q area, AR = 820xxxxx
When addressing the M area, AR = 830xxxxx
When addressing the DB area, AR = 840xxxxx
When addressing the DI area, AR = 850xxxxx
When addressing the L area, AR = 870xxxxx

From this, we can draw a preliminary conclusion: if the value in AR starts with 8, then it must be an address to another area ; If addressing is to be done in the DB area, simply add a 40 after 8. 84000000-840FFFFF indicates that the range to be addressed is: 0.0–65535.7 of the DB area.       For example: when AR=840000D4 (hex) = 1000 0100 0000 0000 0000 0000 1101 0100 (b), it is actually equivalent to DBX26.4.   We see that in a structure like the register addressing pointer, what is P#byte.bit then?      【P# Pointer】 In P#, the P stands for Pointer, which is a 32-bit direct pointer. By \"direct,\" it is meant that the value or storage location that follows the # in P# is directly specified by P. In this way, pointers such as P#XXX can be used in instruction addressing as a “constant,” and this “constant” may or may not include a storage area. For example:      ● L P#Q1.0 //Stores the pointer Q1.0 in ACC1; at this point, ACC1’s value is 82000008 (in hex), which corresponds to Q1.0.   ★ L P#1.0 //Stores the pointer 1.0 in ACC1; at this point, ACC1’s value is 00000008 (in hex), which corresponds to 1.0.   ● L P#MB100 //Error! The pointer must be specified in a byte.bit structure.   ● L P#M100.0 //Stores the value of M100.0 in ACC1; at this point, ACC1’s value is 83000320 (in hex), which is equal to M100.0. ● L P#DB100.DBX26.4 //Error! DBX already provides a storage area, so it cannot be specified repeatedly.   ● L P#DBX26.4 // Stores the value DBX26.4 in ACC1; at this point, ACC1’s content is 840000D4 (in hex), which is equivalent to DBX26.4. We can see that when only a numerical value is specified for P#, the value in the accumulator has the same format as that specified by the addressing pointer in the memory area (it also matches the format of a double-word pointer used for indirect memory access) ; And when a storage area is specified for P#, the content in the accumulator is exactly the same as the content of the inter-area addressing pointer. In fact, the value passed to AR determines the manner in which register indirect addressing is carried out. In practical applications, we take advantage of this feature of P#: we specify P# pointers according to different requirements, and then pass them to AR to determine the final addressing method.  In register addressing, P#XXX serves as an offset for the register AR pointer; it is used in addition with the AR pointer, and the result of this operation is the actual address value that the instruction intends to operate on!  Whether for intra-regional or inter-regional addressing, the storage area where the address resides is specified; therefore, P#XXX here can only denote a pure numerical value, such as ★ in the example above.      【Pointer Offset Calculation Rule】 In a register-addressing pointer structure, how does P#byte.bit contribute to the calculations in order to determine the final address?   The rule for the calculation is: the values in AR1 and P# are added together, categorized by BYTE bits and BIT bits. BIT addition is performed according to binary rules, whereas BYTE addition is carried out according to decimal rules.      For example: the register addressing pointer is:, and we analyze it in two cases: AR1=26.2 and DBX=26.2.   When AR1 is equal to 26.2,
AR1: 26.2
+ P#: 2.6
---------------------------
= 29.0 This is the final exact address value for register indirect addressing within a region.

When AR1 is equal to DBX26.2,
AR1: DBX26.2
+ P#: 2.6
---------------------------
= DBX29.0 This is the final exact address value for register indirect addressing between regions.

【Assignment of AR’s address data】
As explained earlier, to use register addressing correctly, it is most important to assign values to the register AR. Similarly, determining whether it is intra-regional or inter-regional addressing also depends on the assignment in AR.      There are usually the following methods for assigning values to AR: 1. Direct assignment method. For example: L DW#16#83000320 LAR1. Values can be assigned directly in hexadecimal, integer, or binary form, but it is necessary to ensure that they are 32-bit data. AR1, after being assigned a value, stores both the address value and the storage area; therefore, the register addressing mode at this point is definitely inter-area addressing.     2. Indirect assignment method For example: L LAR1 The content of AR1 can be assigned using a memory indirect address pointer. The specific content is stored in MD100.      3. Pointer assignment method For example: LAR1 P#26.2 This assigns a value to AR using the 32-bit \"constant\" pointer P#.      In short, regardless of the assignment method used, since there are clear specifications for the data format stored in AR, it is necessary to verify before assignment that the value to be assigned complies with the addressing rules.      The main purpose of using indirect addressing is to enable dynamic changes in the results of instruction execution; simplifying programs is the primary goal. In some cases, this type of addressing is necessary, such as when traversing data in a certain storage area. Furthermore, indirect addressing also makes programs more flexible; in other words, it enables standardization.      The following examples illustrate how to make flexible use of these addressing methods:
【Example of memory indirect addressing】
Let’s first look at a sample program:
L 100
T MW 100 // Load the 16-bit integer 100 into MW100
L DW#16#8 // Load the 16-digit hexadecimal number 8; when used as a double-word pointer, it is structured in BYTE.BIT format.
The resulting value is: 8H = 1000B = 1.0
T MD 2 // MD2 = 8H
OPN DB // OPN = DB100
L DBW // L = DB100.DBW1
T MW // T = MW1
A DBX // A = DBX1.0
= M // = M1.0
In this example, the main idea is to transfer the content from DB100.DBW1 to MW1. Here we use two pointers for indirect memory addressing – the word pointer MW100 is used to specify the number of the DB block, while the double-word pointer MD2 is used to specify the word addresses of the DBW and MW storage areas.   --------------------------------------------------------------------------------------------  The proposed addressing method such as DB.DBW is an incorrect approach; here is an explanation: From the perspective of addressing principles, an addressing structure like DB.DBW is understandable, but from the standpoint of how SIEMENS programs operate, it is invalid. In actual programs, for such addressing, the program statements should be written as: OPN DBW, L DBW; L DBW; T MW. Obviously, there is no need to repeat the simple operations in the main program (the red-colored part); instead, simply changing the values assigned to MW100 and MD2 is sufficient to meet the application requirements.      Conclusion: By modifying the content of the indirect addressing pointer, the outcome of the main program’s execution can be changed; such modifications can be dynamic or static.      It is precisely because no changes are made to the actual target program (the main program), and the addressing pointer is the only element in this program that needs to be modified, that the addressing pointer can be considered the input parameter of the main program, just like the input parameters of a function block. Thus, the program can be standardized, achieving portability and versatility.         So how can pointer assignments be dynamically rewritten? It can’t be some other simple and repetitive copying, right?   Let’s improve this sample program with a specific application: transferring the data words 1-11 from DB100 to MW1-11. Before designing a program to accomplish this task, let’s first learn some background knowledge.   【Rules for classifying the size of data objects】 The sizes of data objects are divided into: bit (BOOL), byte (BYTE), word (WORD), and double word (DWORD). It seems like a simple concept, but if MW10=MB10+MB11, then does that mean MW11=MB12+MB13? If your answer is yes, I suggest you keep reading and not skip any parts, as any oversight here can lead to errors in the final procedure.      When dividing the size of a data object into bits and bytes, the offset is based on the bits of the data object. In other words, after 0 bits comes 1 bit, after 1 bit comes 2 bits, and so on until 7 bits, which constitutes the size of one byte; after that, with an additional bit of offset, it moves to the 0 bit of the next byte.      When dividing the size of data objects into single bytes and double bytes, the offset is based on the BYTE of the data object! In other words, MW10 = MB10 + MB11; it is not MW11 = MB12 + MB13. The correct formula is MW11 = MB11 + MB12, and then MW12 = MB12 + MB13!   The importance of this concept is that if you use MW10 in a program, then no operations can be performed on MW11, because MB11 represents the intersection of MW10 and MW11.   In other words, for the specific task of \"transferring the 1-11 data words in DB100 to MW1-11,\" we only need to perform 6 transfer operations on these 6 words: DBW1, DBW3, DBW5, DBW7, DBW9, and DBW11. This is the purpose of dedicating a separate section to explain this seemingly simple concept of the rules for determining the size classification of data objects.      【Structure of iteration】 To \"transfer the data words 1-11 in DB100 to MW1-11\", we need to point the pointer contents sequentially to the corresponding data words. This dynamic modification of the pointer contents is essentially what constitutes iteration. For traversal, nothing is simpler than loops.     A loop consists of the following elements: 1. The initial loop pointer; 2. The increment or decrement of the loop pointer; 3. A condition check to determine whether to continue or exit the loop body. The main part of the program that is to be iterated over must be located after the initial loop pointer, and before the increment or decrement of the loop pointer.  For example:      Initial loop pointer: X=0   Start point of the loop: M   Program code that is iterated over: -------   Increment/decrement of the loop pointer: X+1=X   Loop condition check: X≤10; if False, GO TO M ; True: GO TO N   Loop exit point N.    If X is used as the content of the indirect addressing pointer, then operating on the loop pointer is equivalent to dynamically and cyclically modifying the content of the addressing pointer.   【Transfer the data words 1-11 from DB100 to MW1-11】 L L#1 //Initialize the loop pointer. Here, the loop pointer is the addressing pointer that we need to modify: T MD 102; M2: L MD 102; T #COUNTER_D; OPN DB100; L DBW; T MW; L #COUNTER_D; L L#2. The +2 value is used because the offset basis for data words is in bytes.   +D T MD 102 // Self-incrementing and self-decrementing loop pointer; this is key to dynamically modifying the addressing pointer. L L#11 // Number of iterations = n-1. n=6. This is because entering the loop for the first time is unconditional, but an operation has already been performed in practice.   

Submit a Project

**Looking for Chemical Technology, Equipment & Solutions?** No Registration Required Broader Platform Exposure | Global Chemical Service Provider Connections

Submit Request — Free Consultation

Disclaimer

This is an automated machine translation of the original thread. Some technical terms may have inaccuracies; the original text shall prevail. Click "View Original" at the top right to access the source page, which supports IP-based automatic real-time language translation. Please watch out for contact details and sales inducements to prevent fraud. All content and translations are for reference only, representing solely the poster's personal views. For enquiries, email service@hcbbs.com.