For one pin bi-directional communication, without hardware serial port but with Serin and Serout soft commands; here is something to work on. Just a demo.
I chose 628A for demo because of its popularity around;
It can be any PIC (almost any).
The circuit is for demo purposes only to show how the concept works.
In real application, since this is a communication, a precision external crystal needs to be used and config fuse has to be changed.
In this example, internal weak pull ups are used for buttons; and for comm pin idle state.
If the PIC you use has no internal weak pull ups, then have 22K...100K resisitor connected to Vdd from these pins.
Idea is to use RB0 int pin to detect incoming data pulse; sender (transmitter) first sends two zeros at the beginning of the package; Receiver side jumps into int routine and starts waiting for "ABX" header.
Play as you wish.
Code:
#CONFIG
__config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_OFF & _BODEN_ON & _LVP_OFF & _CP_ON
#ENDCONFIG
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 6
CMCON = 7
VRCON = 0
TRISA = 0
TRISB = 0
PORTA = 0
PORTB = 0
ComPin var PORTB.0
Btn1 var PORTB.3
Btn2 var PORTB.4
ActLED VAR PORTB.7
TxByte var byte
RxByte var byte
RxCount var byte
TOutFlag var bit
' ===== Interrupt routine ============
' Include files for DT's interupt routines.
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _INTX, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
Setup:
input btn1
input btn2
input compin
OPTION_REG.7 = 0 ' pull ups enabled.
OPTION_REG.6 = 0 ' int on falling edge of RB0.
RxCount = 0
lcdout $fe,1,"Hello Mars"
Pause 500
lcdout $fe,1
@ INT_ENABLE INT_INT ; enable int on RB0.
Begin:
rxbyte = 0
toutflag = 0
repeat
lcdout $fe,1,"Idle ?"
pause 10
until compin = 1 ' internal pull up is used for idle state.
ActLED = 0
pause 10
lcdout $fe,1,"Waiting for Data"
Start:
if btn1 = 0 then TX ' somebody pressed the button.
if btn2 = 0 then TX ' somebody pressed the button.
if toutflag then timeout2 ' Last receive attempt was not succesful.
pause 1
goto start
TX:
ActLED = 1
txbyte = 0
if btn1 = 0 then txbyte = 1
if btn2 = 0 then txbyte = 2
SerOut2 compin,396, [0,0,"ABX",txbyte] ' 0,0 is to create an interrupt on the other side. ' 2400 driven true.
input compin ' leave the line in idle state always after each transmit.
BtnBounce: ' button de-bounce.
pause 10
if btn1 = 0 then BtnBounce
if btn2 = 0 then BtnBounce
goto begin
TimeOut2:
lcdout $fe,1,"Time Out"
pause 250
goto begin
INTX:
ActLED = 1
TOutFlag = 1 ' if this flag gets cleared later, then we have a succesfull receive.
SerIn2 compin,396,1000,Timeout1,[wAIT("ABX"),rxbyte] '2400 driven true.
TOutFlag = 0 ' clear the flag;
lcdout $fe,$c0,"Rx:",dec3 rxbyte, " Cnt:", dec3 rxcount
ActLED = 0
rxcount = rxcount + 1
Timeout1:
@ INT_RETURN
end
Bookmarks