; CC5X Version 3.4, Copyright (c) B Knudsen Data ; C compiler for the PICmicro family ; ************ 24. Jun 2009 9:07 ************* processor 16C54 radix DEC TMR0 EQU 0x01 PCL EQU 0x02 PORTB EQU 0x06 Carry EQU 0 Zero_ EQU 2 RS232_out EQU 0 RS232_in EQU 1 bitCount EQU 0x0A limit EQU 0x0B serialData EQU 0x0C dout EQU 0x08 ti EQU 0x09 i EQU 0x07 ci EQU 0x08 ; FILE test\serial.c ;/* ; SERIAL COMMUNICATION (RS232) ; ============================ ; ; Using 9600 baud, one stop bit, no parity. ; Baudrate 9600 baud => 104.167 microsec. per bit ; TMR0 counts each 8th microsec. => 13.02 steps per bit ; ; ______ _____ _____ _____ _____ _____ _____ _____ _____ _____ ; |_____|_____|_____|_____|_____|_____|_____|_____|_____| ; Start bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 Stop ; ; NOTE: RS232 signal levels are different from the CMOS levels ; used by the PIC device. A level converter is required: ; ; Logic level CMOS RS232 ; 1 (default) +Vcc -2.8V to -15V ; 0 0 V +2.8V to +15V ;*/ ; ;#define _4_MHz /* 4 MHz system clock */ ; ;// optional items ;//#define UseTMR0 ;#define USE_CONST ; ; ;#pragma bit RS232_out @ PORTB.0 ;#pragma bit RS232_in @ PORTB.1 ; ;#ifdef _4_MHz ; #define TimeStartbit 4 ; #define BitTimeIncr 13 ;#endif ; ;char bitCount, limit; ;char serialData; ; ;#ifdef _4_MHz ; #ifdef UseTMR0 ; #define delayStart limit = TMR0; ; #define delayOneBit \ ; limit += BitTimeIncr; \ ; while (limit != TMR0) \ ; ; ; #else ; #define delayStart /* empty */ ; #define delayOneBit { \ ; char ti; \ ; ti = 30; \ ; do ; while( --ti > 0); \ ; nop(); \ ; } /* total: 5 + 30*3 - 1 + 1 + 9 \ ; = 104 microsec. at 4 MHz */ ; #endif ;#endif ; ;void sendData( char dout) ;/* sends one byte */ ;{ _const1 MOVWF ci MOVLW 12 SUBWF ci,W BTFSC 0x03,Carry RETLW 0 MOVF ci,W ADDWF PCL,1 RETLW 72 RETLW 101 RETLW 108 RETLW 108 RETLW 111 RETLW 32 RETLW 119 RETLW 111 RETLW 114 RETLW 108 RETLW 100 RETLW 33 sendData MOVWF dout ; RS232_out = 0; /* startbit */ BCF 0x06,RS232_out ; delayStart ; for (bitCount = 9; ; bitCount--) { MOVLW 9 MOVWF bitCount ; delayOneBit m001 MOVLW 30 MOVWF ti m002 DECFSZ ti,1 GOTO m002 NOP ; if (bitCount == 0) MOVF bitCount,1 BTFSC 0x03,Zero_ ; break; GOTO m003 ; Carry = 1; /* incl. stopbit */ BSF 0x03,Carry ; dout = rr( dout); RRF dout,1 ; RS232_out = Carry; BTFSS 0x03,Carry BCF 0x06,RS232_out BTFSC 0x03,Carry BSF 0x06,RS232_out ; } DECF bitCount,1 GOTO m001 ;} m003 RETLW 0 ; ; ;#define NText 12 ; ;#ifndef USE_CONST ;char text( char i) ;{ ; skip(i); ; #pragma return[NText] = "Hello world!" ;} ;#else ;const char text[NText] = "Hello world!"; ;#endif ; ; ;void main( void) ;{ main ; char i; ; ; /* NOTE: some devices like the 16F877 have an on-chip analog to ; digital converter with analog input pins that should be ; configured. */ ; //ADCON1 = ..; // Refer to the data sheet for init values. ; ; PORTB = 0x03; // xxxx xx11 MOVLW 3 MOVWF PORTB ; TRISB = 0xFE; // xxxx xx10 MOVLW 254 TRIS PORTB ; OPTION = 2; // prescaler divide by 8 MOVLW 2 OPTION ; ; for (i = 0; i < NText; i++) { CLRF i m004 MOVLW 12 SUBWF i,W BTFSC 0x03,Carry GOTO m005 ; #ifndef USE_CONST ; sendData( text(i)); /* text string */ ; #else ; sendData( text[i]); /* text string */ MOVF i,W CALL _const1 CALL sendData ; #endif ; } INCF i,1 GOTO m004 ; ; WaitNextIO: ; while (RS232_in == 1) m005 BTFSC 0x06,RS232_in ; ; GOTO m005 ; ; Start_RS232: ; /* sampling once per bit */ ; TMR0 = 0; CLRF TMR0 ; limit = TimeStartbit; MOVLW 4 MOVWF limit ; while (limit != TMR0) m006 MOVF limit,W XORWF TMR0,W BTFSS 0x03,Zero_ ; ; GOTO m006 ; if (RS232_in == 1) BTFSC 0x06,RS232_in ; goto StartBitError; GOTO m005 ; ; bitCount = 8; MOVLW 8 MOVWF bitCount ; do { ; limit += BitTimeIncr; m007 MOVLW 13 ADDWF limit,1 ; while (limit != TMR0) m008 MOVF limit,W XORWF TMR0,W BTFSS 0x03,Zero_ ; ; GOTO m008 ; Carry = RS232_in; BCF 0x03,Carry BTFSC 0x06,RS232_in BSF 0x03,Carry ; serialData = rr( serialData); /* rotate carry */ RRF serialData,1 ; } while (-- bitCount > 0); DECFSZ bitCount,1 GOTO m007 ; ; limit += BitTimeIncr; MOVLW 13 ADDWF limit,1 ; while (limit != TMR0) m009 MOVF limit,W XORWF TMR0,W BTFSS 0x03,Zero_ ; ; GOTO m009 ; if (RS232_in == 0) BTFSC 0x06,RS232_in GOTO m005 ; goto StopBitError; ; ; /* 'serialData' can be processed here */ ; /* NOTE: limited time (40 - 50 microsec.) */ ; goto WaitNextIO; ; ; StopBitError: ; /* RS232 stopbit error, ; waiting while line is low */ ; while (RS232_in == 0) m010 BTFSC 0x06,RS232_in GOTO m005 ; ; GOTO m010 ; StartBitError: ; goto WaitNextIO; ORG 0x01FF GOTO main END ; *** KEY INFO *** ; 0x0013 21 word(s) 4 % : sendData ; 0x0028 52 word(s) 10 % : main ; 0x0000 19 word(s) 3 % : _const1 ; RAM usage: 6 bytes (3 local), 19 bytes free ; Maximum call level: 1 ; Total of 93 code words (18 %)