In SX Microcontrollers, SX/B Compiler and SX-Key Tool, g_daubach wrote: Frasse, ok, you found one important bug by yourself - the missing initialization of w before the RETIW instruction. This caused RTCC to be modified by whatever was in w, so the ISR timing was definitely wrong. Now let's look at the voltage levels. When you pull a MAX232 Tin line low, the assoviated Tout line goes to a positive level (approx. +9V), and when you pull the input high, the output goes to a negative Level (-9V). The idle state on an RS-232 line is the negative level. So when you connect an SX output pin to a MAX232 Tin pin, the SX pin should be set to high for idle (see line 14 in the code sample). Each transmission must begin with a start bit, i.e. the RS-232 line must go to positive level for one bit period, i.e. the SX pin must go low for the start bit (see the diagram at the beginning of the code sample). The start bit is followed by eight data bits. Note that they are in "reverse order", i.e. bit 0 first, bit 7 last. Bit 7 must be followed by at least one stop bit, i.e. the RS-232 line must go to negative level, so the SX pin must go high. To serialize the data, you would use a shift register in hardware. Here, we use SX registers, and rotate instructions to perform this task. The SX registers are 8 bits wide, i.e. wide enough to hold the data bits to be transmitted but each serial character actually contains 10 bits (the start bit, 8 data bits, and the stop bit). The UART VP code handles this quite tricky (the original code was written by Chip Gracey, who is a real specialist in writing "tricky" but compact and fast code :-) ). Important for the serialization are the two TxHigh and TxLow registers AND the carry flag. If you look at line 11 in the code sample, you see that bit 6 in TxLow is transferred to the SX output pin. IOW, TxLow.6 is our "UART output". Before TxLow.6 is copied to the output pin, there are three important instructions in lines 7, 8, an 9: In line 7, the carry flag is set - as you will see, this becomes our stop bit later. Next TxHigh is rotated right, i.e. the carray flag is moved into TxHigh.7, and TxHigh.0 (i.e. data bit 0) is moved into the carry flag. As the carry flag was set before, TxHigh.7 is set now. Next, TxLow is rotated right. So, TxLow.7 is moved into TxLow.6, and the carry flag (i.e. data bit 0) is moved into TxLow.7 As TxLow was cleared in the main program, TxLow.7 was 0 before the rotate right, so TxLow.6 is low now. (BTW, it does not matter if you clear TxLow in the main program, or if you do a clrb TxLow.7, as only bits 7 and 6 in TxLow are of importance here). After the two rotates, TxLow.6 is copied to the output pin, so it goes low then. Eight more rotate rights are neccessary to shift the eight data bits from TxHigh through TxLow.6, and to output them. After these eight rotate rights, the former TxHigh.7 bit that was set on the first rotate rights for the start condition has "arrived" in TxLow.7. The final rotate rights move it into TxLow.6, our "output bit", so the output pin will go high for the stop bit. This is why it is so important to set the carry flag in line 7. Although it is not neccessary to set the carry flag before each rotate, it does not harm if it is done in order to simplify the code. In the original UART code, Chip used "negative logic", i.e. movb TxDpin, /TxLow.6 to output the bits. In order to get the right polarity for the start bit and the data bits, you must setb TxLow.7, and move the inverted data byte into TxHigh in this case, when preparing the transmitter. In order to get the stop bit right, it is also neccessary to clear the carry flag in line 7 instead of setting it. I have copied the code snippets, below, from one of my applications that make use of a MAX232: [code] ; 19,200 Baud @ 50 MHz system clock BaudBit = 4 IntPeriod = 163 ORG 0 ISR bank Serial ; Data Bits ; 0 1 2 3 4 5 6 7 8 ; _____ _ _ _ _ _ _ _ _ _ _ ; |_|_|_|_|_|_|_|_|_|_| ; ^ ^ ; | | ; Start Stop :Transmit clrb TxDividePC.BaudBit ; 1 clear xmit timing count flag inc TxDivide ; 2 only execute the transmit routine stz ; 3 set zero flag for test snb TxDivide.BaudBit ; 4 every 2^baud_bit interrupt test TxCount ; 5 are we sending? jz :ExitInt ; 6 if not, go to next VP stc ; 7 Yes, ready stop bit rr TxHighPC ; 8 and shift to next bit rr TxLowPC ; 9 dec TxCount ;10 decrement bit counter movb TXDpin, TxLow.6 ;11 output next bit :ExitInt mov w, #-IntPeriod ;12 retiw ;13 Main ; Initializations go here... setb TxDpin ;14 Make sure that TxD is idle ; Sample to send an endless stream of "X"es :Loop bank Serial ;15 mov TxHigh, #'X' ;16 clr TxLow ;17 mov TxCount, #10 ;18 :WaitTx test TxCount ;19 sz ;20 jmp :WaitTx ;21 jmp :Loop ;22 [/code] ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=155203#m155498 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)