關(guān)于PIC單片機(jī)“讀-修改-寫”的相關(guān)說明
關(guān)于PIC單片機(jī)“讀-修改-寫”的相關(guān)說明
本文引用地址:http://m.butianyuan.cn/article/201611/316225.htmTopic: I have seen references to "Read-Modify-Write" instructions in your datasheet, but I do not know what that is. Can you explain what it is and why I need to know this?
我曾在數(shù)據(jù)手冊里看到“讀-修改-寫”的相關(guān)說明,但我不知道這是什么。你能解釋一下它的含義以及為什么要注意它嗎?
Discussion:
An easy example of a Read-Modify-Write (or RMW) instruction is the bit clear instruction BCF. 一個關(guān)于“讀-修改-寫”的簡單例子就是位清零指令BCF。You might think that the processor just clears the bit, which on a port output pin would clear the pin.你可能認(rèn)為處理器只是清這個位,對于輸出端口就是清零這個管腳。 What actually happens is the whole port (or register) is first read, THEN the bit is cleared, then the new modified value is written back to the port (or register). 而實際發(fā)生的是整個端口(或寄存器)先被讀入,之后相應(yīng)位被清,然后修改后的新值被寫回到這個端口(或寄存器)。Actually, any instruction that depends on a value currently in the register is going to be a Read-Modify-Write instruction. 實際上,任何基于當(dāng)前寄存器內(nèi)值的操作指令都是一個“讀-修改-寫”指令。This includes ADDWF, SUBWF, BCF, BSF, INCF, XORWF, etc... Instructions that do not depend on the current register value, like MOVWF, CLRF, and so on are not RMW instructions.這包括ADDWF,SUBWF,BCF,BSF,INCF,XORWF等等。不基于當(dāng)前寄存器內(nèi)值的指令,如MOVWF,CLRF等不是“讀-修改-寫”指令。
One situation where you would want to consider the affects of a RMW instruction is a port that is continuously changed from input to output and back.如果你不斷地改變一個端口的輸入輸出模式,在這個情形下你應(yīng)該注意“讀-修改-寫”指令的影響。 For example, say you have TRISB set to all outputs, and write all ones to the PORTB register, all of the PORTB pins will go high. 例如,如果說你把TRISB設(shè)為都作輸出,并且將PORTB寄存器都寫“1”,所有PORTB的引腳都將變高。Now, say you turn pin RB3 into an input, which happens to go low. 現(xiàn)在,如果說你把RB3變?yōu)檩斎?,恰好這時的輸入為低。A BCF PORTB,6 is then executed to drive pin RB6 low. 然后你執(zhí)行一個BCF PORTB,6 的指令把RB6輸出低。If you then turn RB3 back into an output, it will also now drive low, even though the last value you put there was a one.這時如果你再把RB3設(shè)回輸出狀態(tài),它將也輸出低,盡管你上次你在PORTB里這個位設(shè)置的值是“1”。
What happened was tha the BCF of the other pin (RB6) cause the whole port to be read, including the zero on RB3 when it was an input. 之所以這樣,是因為對其他引腳(RB6)做BCF時,整個端口都被讀進(jìn)來了,包括當(dāng)RB3引腳處于輸入態(tài)時的低電平。The bit 6 was changed as requested, but since RB3 was read as a zero, zero will also be placed back into that port latch, overwriting the one that was there before. 位6按要求改變了,但是由于RB3讀入為“0”,于是在RB3位的“0”也被放回了端口鎖存器,修改了原來在這個位置的“1”。When the pin is turned back into an output, the new value was reflected. 當(dāng)這個引腳重新變?yōu)檩敵鰬B(tài)時,這個新值反應(yīng)出來,輸出“0”而不是“1”了。
Topic: When I perform a BCF, other pins get cleared in the port. Why?
當(dāng)我執(zhí)行一個BCF命令時,端口的其他管腳也被清零,為什么?
Discussion:
If this is on a PIC16C7X device, you have not configured the I/O pins properly in the ADCON1 register.如果這發(fā)生在PIC16C7X的器件上,可能是因為你沒有正確設(shè)置ADCON1中的IO管腳屬性。 If a pin is configured for analog input, any read of that pin will read a zero, regardless of the voltage on the pin. 如果一個管腳被配置為模擬輸入,對這個管腳讀將始終為“0”,不管在這個引腳上是否有電壓。This is an exception to the normal rule that the pin state is always read. 通常情況下這些管腳始終都是作輸入的,不會有這種現(xiàn)象。You can still configure an anolog pin as an output in the TRIS register, and drive the pin high or low by writing to it, but you will always read a zero. 你也可以通過配置TRIS寄存器來改變這些模擬輸入管腳作為輸出,并且通過寫寄存器驅(qū)動這些引腳為高或低,但是你將一直讀到“0”。Therefore if you execute a Read-Modify-Write instruction (see previous question) all analog pins are read as zero, and those not directly modified by the instruction will be written back to the port latch as zero. 所以當(dāng)你執(zhí)行一個“讀-修改-寫”指令(見前一個問題),所有的模擬管腳讀為“0”,并且在沒有被指令直接修改的情況下,將端口鎖存器的值改為“0”。A pin configured as analog is expected to have values that may be neither high nor low to a digital pin, or floating. Floating inputs on digital pins are a no-no, and can lead to high current draw in the input buffer, so the input buffer is disabled. 一個被配置為模擬口的管腳將被認(rèn)為有一個可能既非高也非低的值,或者是浮空的,相對于數(shù)字口而言。在數(shù)字口上的輸入也是一種非高非低的狀態(tài),并且能夠?qū)е螺斎刖彌_器的大電流泄漏,所以輸入緩沖器被禁止。
Another case where a RMW instruction may seem to change other pin values unexpectedly can be illustrated as follows: 另一種情況下,“讀-修改-寫”指令好像是違背期望地修改了其他引腳的值,一般能被描述如下:Suppose you make PORTC all outputs and drive the pins low. 假設(shè)你把PORTC全作為輸出并驅(qū)動所有管腳為低。On each of the port pins is an LED connect to ground, such that a high output lights it. Across each LED is a 100uF capacitor. 在這個端口的每個管腳上有一個LED連到地,這樣輸出高時將點(diǎn)亮LED。并在每一個LED上有一個100uF的電容。Lets also suppose that the processor is running very fast, say 20MHz. 讓我們也假設(shè)處理器運(yùn)行得非???,比如說20MHz。Now if you go down the port setting each pin in order; BSF PORTC,0 then BSF PORTC,1 then BSF PORTC,2 and so on, you may see that only the last pin was set, and only the last LED actually turns on. 現(xiàn)在如果你清端口后依次去置位引腳,如BSF PORTC,0 然后BCF PORTC,1 接著BCF PORTC,2 這樣下去,你將看到只有最后的一個管腳被真正置位了,只有一個LED點(diǎn)亮。This is because the capacitors take a while to charge. As each pin was set, the pin before it was not charged yet and so was read as a zero. 這是因為電容需要時間來充電。當(dāng)一個管腳被置位時,它前面被置位的那個管腳還沒有充電完全,所以讀到的還是“0”。This zero is written back out to the port latch (RMW, remember) which clears the bit you just tried to set the instruction before. 這個“0”將被寫回端口鎖存器(讀-修改-寫),清掉前面你剛用指令來置“1”的那個位。This is usually only a concern at high speeds and for successive port operations, but it can happen so take it into consideration. 這種情況通常只發(fā)生在高速并且連續(xù)的端口操作中,但這的確會發(fā)生,所以要在設(shè)計中考慮。
另,明顯錯誤的設(shè)計,導(dǎo)致的“讀-修改-寫”問題,不再贅述。
評論