oPossum 1,083 Posted May 26, 2011 Share Posted May 26, 2011 Here is some code that can tx at 115.2 kbps while running at only 1 MHz clock. This can be useful for "printf debugging" with minimal impact on code speed. The bit time of 115.2 kbps is aprox 8.68 us. The timing granularity at 1 MHz is only 1 us, so dithering is used to maintain correct average bit time. Most UART look at the middle of the bit, so this generally works well. The jitter is under 500 ns as shown in the following table. ; Bit Exact Int Delta Error ; ---------------------------------- ; Start 0.00 0 - - ; 0 8.68 9 9 +0.32 ; 1 17.36 17 8 -0.36 ; 2 26.04 26 9 -0.04 ; 3 34.72 35 9 +0.28 ; 4 43.40 43 8 -0.40 ; 5 52.08 52 9 -0.08 ; 6 60.77 61 9 +0.23 ; 7 69.44 69 8 -0.44 ; Stop 78.13 78 9 -0.13 This is the code to send one bit... bN rrc R14 Move the next bit to send in to the carry flag, shift all others jc bNh --+ Test the carry flag and jump if one bic.b R15, &P1OUT | The carry flag was zero, so put a zero on the serial output jmp nxb --|--+ Jump to the next bit bNh bis.b R15, &P1OUT <-+ | The carry flag was one, so put a one on the serial output jmp nxb -----+ Jump to the next bit - this jump is required to keep the | code path for the bit isochronous nxb next bit <----+ 9 cycles are required for each bit using that code, so something must be done for the 3 bits that must be sent in 8 cycles. The last jmp can be replace with a nop to reduce the cycle count when a one is sent. To reduce the cycle count when a zero is sent, the second jump is also replaced with a nop and part of the code for the next bit is copied to directly after the nop. This is the code for sending a byte... ; Data to tx is in R14 mov #0x02, R15 ; Setup serial output bitmask in R15 ; ; Start bit bic.b R15, &P1OUT ; 0 jmp bit0 ; ; bit0 rrc R14 ; Bit 0 jc bit0h ; bic.b R15, &P1OUT ; 9 nop ; rrc R14 ; Bit 1 jc bit1h ; bic.b R15, &P1OUT ; 17 jmp bit2 ; bit0h bis.b R15, &P1OUT ; 9 nop ; ; bit1 rrc R14 ; Bit 1 jc bit1h ; bic.b R15, &P1OUT ; 17 jmp bit2 ; bit1h bis.b R15, &P1OUT ; 17 jmp bit2 ; ; bit2 rrc R14 ; Bit 2 jc bit2h ; bic.b R15, &P1OUT ; 26 jmp bit3 ; bit2h bis.b R15, &P1OUT ; 26 jmp bit3 ; ; bit3 rrc R14 ; Bit 3 jc bit3h ; bic.b R15, &P1OUT ; 35 nop ; rrc R14 ; Bit 4 jc bit4h ; bic.b R15, &P1OUT ; 43 jmp bit5 ; bit3h bis.b R15, &P1OUT ; 35 nop ; ; bit4 rrc R14 ; Bit 4 jc bit4h ; bic.b R15, &P1OUT ; 43 jmp bit5 ; bit4h bis.b R15, &P1OUT ; 43 jmp bit5 ; ; bit5 rrc R14 ; Bit 5 jc bit5h ; bic.b R15, &P1OUT ; 52 jmp bit6 ; bit5h bis.b R15, &P1OUT ; 52 jmp bit6 ; ; bit6 rrc R14 ; Bit 6 jc bit6h ; bic.b R15, &P1OUT ; 61 nop ; rrc R14 ; Bit 7 jc bit7h ; bic.b R15, &P1OUT ; 69 jmp bitstop ; bit6h bis.b R15, &P1OUT ; 61 nop ; ; bit7 rrc R14 ; Bit 7 jc bit7h ; bic.b R15, &P1OUT ; 69 jmp bitstop ; bit7h bis.b R15, &P1OUT ; 69 jmp bitstop ; ; bitstop nop ; Stop Bit jmp $ + 2 ; bis.b R15, &P1OUT ; 78 babu 1 Quote Link to post Share on other sites
oPossum 1,083 Posted May 26, 2011 Author Share Posted May 26, 2011 Inline asm version void tx(unsigned c) { __asm(" mov 0(SP), R14"); // Get the char passed on the stack to R14 // __asm(" mov #0x02, R15"); // Setup bitmask in R15 // __asm(" bic.b R15, &P1OUT"); // 0 Start bit __asm(" jmp $ + 2"); // // __asm(" rrc R14"); // Bit 0 __asm(" jc $ + 18"); // __asm(" bic.b R15, &P1OUT"); // 9 __asm(" nop"); // __asm(" rrc R14"); // Bit 1 __asm(" jc $ + 24"); // __asm(" bic.b R15, &P1OUT"); // 17 __asm(" jmp $ + 24"); // __asm(" bis.b R15, &P1OUT"); // 9 __asm(" nop"); // // __asm(" rrc R14"); // Bit 1 __asm(" jc $ + 8"); // __asm(" bic.b R15, &P1OUT"); // 17 __asm(" jmp $ + 8"); // __asm(" bis.b R15, &P1OUT"); // 17 __asm(" jmp $ + 2"); // // __asm(" rrc R14"); // Bit 2 __asm(" jc $ + 8"); // __asm(" bic.b R15, &P1OUT"); // 26 __asm(" jmp $ + 8"); // __asm(" bis.b R15, &P1OUT"); // 26 __asm(" jmp $ + 2"); // // __asm(" rrc R14"); // Bit 3 __asm(" jc $ + 18"); // __asm(" bic.b R15, &P1OUT"); // 35 __asm(" nop"); // __asm(" rrc R14"); // Bit 4 __asm(" jc $ + 24"); // __asm(" bic.b R15, &P1OUT"); // 43 __asm(" jmp $ + 24"); // __asm(" bis.b R15, &P1OUT"); // 35 __asm(" nop"); // // __asm(" rrc R14"); // Bit 4 __asm(" jc $ + 8"); // __asm(" bic.b R15, &P1OUT"); // 43 __asm(" jmp $ + 8"); // __asm(" bis.b R15, &P1OUT"); // 43 __asm(" jmp $ + 2"); // // __asm(" rrc R14"); // Bit 5 __asm(" jc $ + 8"); // __asm(" bic.b R15, &P1OUT"); // 52 __asm(" jmp $ + 8"); // __asm(" bis.b R15, &P1OUT"); // 52 __asm(" jmp $ + 2"); // // __asm(" rrc R14"); // Bit 6 __asm(" jc $ + 18"); // __asm(" bic.b R15, &P1OUT"); // 61 __asm(" nop"); // __asm(" rrc R14"); // Bit 7 __asm(" jc $ + 24"); // __asm(" bic.b R15, &P1OUT"); // 69 __asm(" jmp $ + 24"); // __asm(" bis.b R15, &P1OUT"); // 61 __asm(" nop"); // // __asm(" rrc R14"); // Bit 7 __asm(" jc $ + 8"); // __asm(" bic.b R15, &P1OUT"); // 69 __asm(" jmp $ + 8"); // __asm(" bis.b R15, &P1OUT"); // 69 __asm(" jmp $ + 2"); // // __asm(" nop"); // Stop Bit __asm(" jmp $ + 2"); // __asm(" bis.b R15, &P1OUT"); // 78 } NatureTM, bluehash and RobG 3 Quote Link to post Share on other sites
bluehash 1,581 Posted May 26, 2011 Share Posted May 26, 2011 You have no idea how helpful this is. Thanks for sharing. Quote Link to post Share on other sites
RobG 1,892 Posted May 26, 2011 Share Posted May 26, 2011 I took the easy way out (for my robot project) and used 2553 with 16MHz clock Quote Link to post Share on other sites
oPossum 1,083 Posted June 1, 2011 Author Share Posted June 1, 2011 Discussion in this thread has lead me to a smaller version of the code. This is smaller, but takes a few more cycles overall. putc or #0x0100, R12 ; Stop bit mov #0x02, R15 ; Serial out bitmask jmp bit_start ; ; bit0 rra R12 ; Bit 0/3/6 jc bit0h ; bic.b R15, &P1OUT ; 9/35/61 nop ; rra R12 ; Bit 1/4/7 jc bit1h ; bic.b R15, &P1OUT ; 17/43/69 jmp bit2 ; bit0h bis.b R15, &P1OUT ; 9/35/61 nop ; ; bit1 rra R12 ; Bit 1/4/7 jc bit1h ; bic.b R15, &P1OUT ; 17/43/69 jmp bit2 ; bit1h bis.b R15, &P1OUT ; 17/43/69 jmp bit2 ; ; bit2 rra R12 ; Bit Start/2/5/Stop jc bit2h ; bit_start bic.b R15, &P1OUT ; 0/26/52 jmp bit0 ; bit2h bis.b R15, &P1OUT ; 26/52/78 jne bit0 ; ret Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.