I have this code for some time but I can't get it to work, I can't simulate this code in Proteus, it is like it is not receiving any data and I can't find the error in the code, I hope someone can see it because I can't.
Code:
;RS232 9600 8N1 to Manchester 13888 converter.
;This program will receive standard RS232 (9600 baud, 1 start bit, 8 data bits, 1 stop bit),
;and will convert it into Manchester protocol (13888 baud, 1.5 start bits, 8 data bits, 1 ODD parity bit, 0.5 stop bits).
;PIC16f628a
; --------
; | |
; | |-(manchester out)
; | |
; | |
; ground-| |-5V
; | |-470R-LED1
; (rs232 in)-| |-470R-LED2
; | |-470R-LED3
; ground-SW-| |-470R-LED4
; --------
;SW=Normally Opened switch
;-----------------------------------------------------------------------
#DEFINE LED1Off bcf PORTB,LED1_PIN
#DEFINE LED1On bsf PORTB,LED1_PIN
#DEFINE LED2Off bcf PORTB,LED2_PIN
#DEFINE LED2On bsf PORTB,LED2_PIN
#DEFINE LED3Off bcf PORTB,LED3_PIN
#DEFINE LED3On bsf PORTB,LED3_PIN
#DEFINE LED4Off bcf PORTB,LED4_PIN
#DEFINE LED4On bsf PORTB,LED4_PIN
;-----------------------------------------------------------------------
list P=16F628A, R=dec
;-----------------------------------------------------------------------
#INCLUDE P16F628A.INC
#DEFINE FUSESINHEX TRUE
;;pin5 and 14 are 5v and ground
RA0 equ 0 ;pin17* (data out)
RB3 equ 3 ;pin9* (reset switch)
RB4 equ 4 ;pin10*
RB5 equ 5 ;pin11*
RB6 equ 6 ;pin12*
RB7 equ 7 ;pin13*
;
;
DATAOUT_PIN equ RA0 ;pin 17
RESET_PIN equ RB3 ;pin 9 (reset switch)
LED1_PIN equ RB7 ;pin 13
LED2_PIN equ RB6 ;pin 12
LED3_PIN equ RB5 ;pin 11
LED4_PIN equ RB4 ;pin 10
__FUSES _BODEN_OFF & _BOREN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_OFF & _WDT_OFF & _LVP_OFF & _INTOSC_OSC_NOCLKOUT & _MCLRE_OFF
;
cblock 0x20
bytesent
bitcount
parity
time1
endc
;-----------------------------------------------------------------------
org 0x00 ;Reset Vector
goto setupchip
;-----------------------------------------------------------------------
msg dt "RS232 to Manchester v0.2"
;-----------------------------------------------------------------------
start
LED1On
LED3Off
LED4Off
btfsc RCSTA,OERR ;check for overun errors
goto DEAL_OERR
btfsc RCSTA,FERR ;check for framing errors
goto DEAL_FERR
lookforbyte
btfsS PORTB,RESET_PIN ;If you want the chip to start over again, press the switch
GOTO setupchip
BSF PORTA,DATAOUT_PIN
btfss PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
goto lookforbyte ;loop until a byte is found on the RS232 pin
sendbyte
LED1Off
LED2Off
LED3Off
LED4On
movf RCREG,w ;Put the just received byte on W
BCF PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
call xmitbyte ;Call the manchester tx routine.
;The manchester tx will delay less than the time necessary for
;another byte to come on the RCREG.
goto start
;-----------------------------------------------------------------------
DEAL_OERR ;overun errors are fatal
LED2On
btfsc PORTB,RESET_PIN ;Since this is a fatal error, it will go out this loop only if you press the switch.
GOTO DEAL_OERR
movf RCREG,W
BCF PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
movf RCREG,W
BCF PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
call xmitbyte
GOTO setupchip
;-----------------------------------------------------------------------
DEAL_FERR ;framing errors will occur often
LED3On
movf RCREG,W ;We are discarding the byte when a frmaing error occur.
BCF PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
goto start
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------
sendcmdtest ;debugonly
movlw 0x03
call xmitbyte
movlw 0xFD
call xmitbyte
movlw 0x6E
call xmitbyte
movlw 0x92
call xmitbyte
movlw 0xFF
call xmitbyte
movlw 0xFF
call xmitbyte
movlw 0xFF
call xmitbyte
movlw 0xFF
call xmitbyte
movlw 0xFF
call xmitbyte
movlw 0xFF
call xmitbyte
RETURN
;-----------------------------------------------------------------------
;------------------------------------------------------------------------
;------------------------------------------------------------------------
setupchip
banksel PORTA
LED1Off
LED2On
LED3On
LED4Off
btfsS PORTB,RESET_PIN ;To avoid continous resets, it will continue only when the switch is already depressed.
GOTO setupchip
banksel CMCON
movlw b'00000111'
movwf CMCON
banksel OPTION_REG
movlw b'01111000'
MOVWF OPTION_REG
;OPTION_REG bits:
;bit 7 RBPU: PORTB Pull-up Enable bit
;1 = PORTB pull-ups are disabled
;0 = PORTB pull-ups are enabled by individual port latch values
;bit 6 INTEDG: Interrupt Edge Select bit
;1 = Interrupt on rising edge of RB0/INT pin
;0 = Interrupt on falling edge of RB0/INT pin
;bit 5 T0CS: TMR0 Clock Source Select bit
;1 = Transition on RA4/T0CKI pin
;0 = Internal instruction cycle clock (CLKOUT)
;bit 4 T0SE: TMR0 Source Edge Select bit
;1 = Increment on high-to-low transition on RA4/T0CKI pin
;0 = Increment on low-to-high transition on RA4/T0CKI pin
;bit 3 PSA: Prescaler Assignment bit
;1 = Prescaler is assigned to the WDT
;0 = Prescaler is assigned to the Timer0 module
;bit 2-0 PS2:PS0: Prescaler Rate Select bits
;000 = if assigned to TMR0 = 1:2
; if assigned to WDT = 1:1
banksel PORTA
clrf PORTA
banksel TRISA
movlw b'11111110' ;set PORTA: 0 (pin 17) output
movwf TRISA
movlw b'00001011'
movwf TRISB ;RB1 is the RS232 receive pin
call setupserial
banksel PORTA
LED1Off
LED2Off
LED3Off
LED4Off
goto start
;------------------------------------------------------------------------
setupserial
;TXSTA bits:
;bit 7 CSRC: Clock Source Select bit
;Asynchronous mode
;Don’t care
;Synchronous mode
;1 = Master mode (Clock generated internally from BRG)
;0 = Slave mode (Clock from external source)
;bit 6 TX9: 9-bit Transmit Enable bit
;1 = Selects 9-bit transmission
;0 = Selects 8-bit transmission
;bit 5 TXEN: Transmit Enable bit(1)
;1 = Transmit enabled
;0 = Transmit disabled
;bit 4 SYNC: USART Mode Select bit
;1 = Synchronous mode
;0 = Asynchronous mode
;bit 3 Unimplemented: Read as ‘0’
;bit 2 BRGH: High Baud Rate Select bit
;Asynchronous mode
;1 = High speed
;0 = Low speed
;Synchronous mode
;Unused in this mode
;bit 1 TRMT: Transmit Shift Register Status bit
;1 = TSR empty
;0 = TSR full
;bit 0 TX9D: 9th bit of transmit data. Can be parity bit.
;RCSTA bits:
;bit 7 SPEN: Serial Port Enable bit
;(Configures RB1/RX/DT and RB2/TX/CK pins as serial port pins when bits TRISB<2:1> are set)
;1 = Serial port enabled
;0 = Serial port disabled
;bit 6 RX9: 9-bit Receive Enable bit
;1 = Selects 9-bit reception
;0 = Selects 8-bit reception
;bit 5 SREN: Single Receive Enable bit
;Asynchronous mode:
;Don’t care
;Synchronous mode - master:
;1 = Enables single receive
;0 = Disables single receive
;This bit is cleared after reception is complete.
;Synchronous mode - slave:
;Unused in this mode
;bit 4 CREN: Continuous Receive Enable bit
;Asynchronous mode:
;1 = Enables continuous receive
;0 = Disables continuous receive
;Synchronous mode:
;1 = Enables continuous receive until enable bit CREN is cleared (CREN overrides SREN)
;0 = Disables continuous receive
;bit 3 ADEN: Address Detect Enable bit
;Asynchronous mode 9-bit (RX9 = 1):
;1 = Enables address detection, enable interrupt and load of the receive buffer when RSR<8>
;is set
;0 = Disables address detection, all bytes are received, and ninth bit can be used as parity bit
;Asynchronous mode 8-bit (RX9 = 0):
;Unused in this mode
;Synchronous mode
;Unused in this mode
;bit 2 FERR: Framing Error bit
;1 = Framing error (Can be updated by reading RCREG register and receive next valid byte)
;0 = No framing error
;bit 1 OERR: Overrun Error bit
;1 = Overrun error (Can be cleared by clearing bit CREN)
;0 = No overrun error
;bit 0 RX9D: 9th bit of received data (Can be parity bit)
banksel SPBRG
movlw 25 ;SPBRG=25, BRGH=1 for 9600 baud, real baud will be 9615.385, error 0.160%
movwf SPBRG
banksel TXSTA
clrf TXSTA
movlw B'00100100'
movwf TXSTA
banksel RCSTA
clrf RCSTA
movlw B'10010000'
movwf RCSTA
movf RCREG,W
BCF PIR1,RCIF ;BIT 5 INDICATES THAT A BYTE HAS BEEN RECEIVED IN THE RSR REG
clrf RCSTA
movlw B'10010000'
movwf RCSTA
return
;------------------------------------------------------------------------
pausa8bit: ;W should be loaded with a delay value before calling this routine
;T = 3w+2
MOVWF time1 ;(1 cycle)
delay8bit:
DECFSZ time1, F ;(1 cycle)
GOTO delay8bit ;(2 cycles)
RETLW 0 ;(2 cycles)
;------------------------------------------------------------------------
;========================================================================
;========================================================================
;========================================================================
;----------------- ASYNCHRONOUS TRANSMIT SUBROUTINE -----------------
;========================================================================
;========================================================================
;========================================================================
;**************************************************************************************
; The byte to be sent needs to be loaded on W before this routine is called. *
; The byte to be sent will then be loaded on the bytesent register *
; This manchester tx routine manchester simulates 13888 baud rate, 1 bit = 72us *
; Asynchronous tx sequence: *
; 1. Start Bit = Logic 1 for 72 plus logic 0 for 36 us (Total 108 us, 1.5 bits) *
; 2. 8 data bits = 2 bit cell of 36us each where the 1st is opposite of the 2nd and *
; the second contains the real value of the bit to be sent. The data is sent LSB to*
; MSB until the entire byte is sent. *
; 3. Parity Bit = 2 bit cells of 36us each, where the 2nd bit cell contains the real *
; value of the parity bit. The parity is ODD. This means the total number of 1's *
; considering the 8 data bits and the parity bit needs to be ODD. So if you have, *
; let's say, 4 one's in the 8 data bits, the parity will be 1 so you have an ODD *
; number of one's in the total. If the number of one's in the 8 data bits is *
; already ODD (1, 3, 5 or 7), the parity bit will be 0. *
; 4. Stop Bit = Logic zero for 36us *
; *
;Below an example: *
; *
; BYTE = 41h = 01000001b, Parity=ODD *
; *
; | --_ | _- | -_ | -_ | -_ | -_ | -_ | _- | -_ | _- | _ | *
; 110 01 10 10 10 10 10 01 10 01 0 *
; START 1 0 0 0 0 0 1 0 P STOP *
; LSB MSB *
; *
;**************************************************************************************
xmitbyte
MOVWF bytesent
BSF parity,0 ;(1 cycle) Parity bit starts in "1" for ODD parity
MOVLW 0x08 ;(1 cycle) Porque son 8 bits de datos
MOVWF bitcount ;(1 cycle)
;*****************BEGINNING START BIT***********************
;----------------------------------
BSF PORTA,DATAOUT_PIN ;(1 cycle) Data Out = 1. The start bit needs 108us high and 36us low.
;This means it will be high for 3 bit cell (1.5 bits) and low for 1 bit cell (0.5 bits)
;----------------------------------
MOVLW 0x16 ;I need 72us en total. 72-10=62=3w+2
CALL pausa8bit ;(2 cycles) T = 3w+2
;I need 72us en total. 72-4=68=3w+2
;(1 cycle) =>3w=66, w=22
;(2 cycles) T = 3w+2
;----------------------------------
BCF PORTA,DATAOUT_PIN ;(1 cycles) Data Out = 0. This is the second bit cell of the second start bit
;----------------------------------
MOVLW 0x09 ;(1 cycle). I need 36. 36 - 7 = 29
;29=3w+2 => 27=3w, w=9
CALL pausa8bit ;(2 cycles)
;***************END OF START BIT******************************
;***************BEGINNING TX OF 8 DATA BITS **************
byteloop: ;LSB first, each bit composed of 2 bit cells, second bit cell has the real value of each bit.
RRF bytesent,1 ;(1 cycle) ++++++++++++++++++++++++++++++++++++++++++++++
COMF STATUS, W ;(1 cycle) +STATUS: GPWUF -- PA0 /TO /PD Z DC C +
ANDLW 0x01 ;(1 cycle) + b7 b6 b5 b4 b3 b2 b1 b0 +
;---------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++
MOVWF PORTA ;(1 cycle) 1st bit cell (36us)
;----------------------------------
XORWF parity,F ;(1 cycle)
NOP ;(1 cycle)
NOP ;(1 cycle)
MOVLW 0x09 ;(1 cycle) 36-7=29 = 3w+2
;=>27 = 3w, w=9
CALL pausa8bit ;(2 cycle)
;----------------------------------
COMF PORTA,F ;(1 cycle) 2nd bit cell (36us)
;----------------------------------
MOVLW 0x08 ;(1 cycle). I need 36. 36-10=26=3w+2
;=>3w=24, w=8
CALL pausa8bit ;(2 cycles)
DECFSZ bitcount,F ;(1 cycle)
GOTO byteloop ;(2 cycle)
;***************END OF TX OF 8 DATA BITS **************
;***************BEGINNING TX OF 1 PARITY BIT************
NOP ;(1 cycle). I need 36. 36-33=3= 3 NOP
NOP ;(1 cycle)
NOP ;(1 cycle)
COMF parity,w ;(1cycle) first bitcell of parity
;parity on W
;----------------------------------
MOVWF PORTA ;(1 cycle). Data Out = Parity, 1st bit cell;----------------------------------
MOVLW 0x0A ;(1 cycle). I need 36. 36-4=32=3w+2
;=>3w=30, w=10
CALL pausa8bit ;(2 cycles)
;----------------------------------
COMF PORTA,F ;(1 cycle). Data Out = Parity, 2nd bit cell is the opposite of the 1st
;----------------------------------
MOVLW 0x0A ;(1 cycle). I need 36. 36-4=32=3w+2
;=>3w=30, w=10
CALL pausa8bit ;(2 cycles)
;***************END OF TX OF 1 PARITY BIT************
;****************BEGINNING OF THE STOP BIT*********************
;----------------------------------
BCF PORTA,DATAOUT_PIN ;(1 cycle) LOW STOP BIT
;----------------------------------
NOP ;(1 cycle)
NOP ;(1 cycle)
MOVLW 0x0A ;(1 cycle). I need 36. 36-3=32=3w+2
;=>3w=30, w=10 (Stop bit has 36us)
CALL pausa8bit ;(2 cycles)
BSF PORTA,DATAOUT_PIN ;after the stop bit is sent, put the line in idle state
return
;*****************END OF THE STOP BIT***********************
;========================================================================
;========================================================================
;========================================================================
;----------------- ASYNCHRONOUS TRANSMIT SUBROUTINE -----------------
;============================= THE END =================================
;========================================================================
;========================================================================
;========================================================================
end