Here is some code that I've written to make a pic communicate with Hyperterminal in GCBASIC
I thought I'd share it with you all. I wanted to make the setup serial routine "smarter" but haven't got around to that yet. It works fine with a 16F690 @ 9600 baud, 8/n/1, flow control off. There is come parity checking code in there, but I have commented it out, since it works fine without it.
To use, here is a sample program
******************************
'Filename: test_usart.txt
'A program to test serial communications
'Chip model
#chip 16F690, 8
#config INTRC_OSC_NOCLKOUT, WDT_OFF
#include "usart.h"
'Hardware USART constants
'Main routine
ADOFF
dir PORTC.7 out
SetupSerial '9600 baud, 8/N/1 no flow control
Main:
SET PORTC.7 ON
TransmitSerial_Print("Please type in a character ")
Transmitserial(13)
Transmitserial(10)
Loopx:
Character = ReceiveSerial
If flags.gotnewdata OFF then GOTO Loopx
TransmitSerial_Print("Message received, you entered a: ")
TransmitSerial(Character)
Transmitserial(13)
Transmitserial(10)
Set flags.gotnewdata OFF
SET PORTC.7 OFF
wait 25 ms
goto Main
******************************
' Filename: usart.h
' Hardware USART routines for Great Cow BASIC
' Steve Bell
' February 3, 2007
'Subs
' sub SetupSerial Setup serial port with baudrate 9600 for 8Mhz clock
' sub ReceiveSerial(data) Receive data from serial port into byte data
' sub TransmitSerial(data) Transmit data to serial port
' sub TransmitSerial_Print(PrintData$) Transmit a string to the serial port
'Hardware USART constants
#define GOTNEWDATA 0 'bit that indicates new data received
sub SetupSerial(baud_rate,USARTPORT,USART_TX,USART_RX)
ADOff 'make port digital
DIR PORTB.7 OUT
DIR PORTB.5 IN
SPBRG = 12 ' this value is for 9600 baud with brgh bit = 0 P16F690
TXSTA = b'00100000' 'note, bit 2 is BRGH
RCSTA = b'10010000' 'enable serial port and reception
SET FLAGS.GOTNEWDATA OFF
end sub
sub TransmitSerial(xmitdata)
LoopTransmit:
IF PIR1.TXIF OFF THEN goto LoopTransmit 'check if transmitter is busy
TXDATA = xmitdata
' CalcParity(TXDATA) 'calculate parity
' rotate ParityByte RIGHT 'get parity bit into status.c
' SET TXSTA.TX9D OFF 'set parity bit to zero
' IF STATUS.C = 1 THEN SET TXSTA.TX9D ON 'if status.c is one, set parity bit
TXREG = TXDATA 'transmit data
end sub
sub TransmitSerial_Print(PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
TransmitSerial(PrintData(SysPrintTemp))
next
end sub
sub CalcParity(Temp) 'calculate even parity bit, data starts in paritybyte
'result is in Lsb of ParityByte
Paritybyte = Temp 'get data for parity calculation
rrf Paritybyte,W 'rotate
xorwf Paritybyte,W 'compare all bits against neighbor
movwf Paritybyte 'save
rrf ParityByte,F 'rotate
rrf ParityByte,F 'rotate
xorwf ParityByte,F 'compare every 2nd bit and save
swapf ParityByte,W 'rotate 4
xorwf ParityByte,F 'compare every 4th bit and save
end sub
function ReceiveSerial 'check if data received, and if so, return data
IF PIR1.RCIF OFF THEN GOTO endreceiveserial
IF RCSTA.OERR ON THEN ErrSerialOverr 'if overrun error occured, handle error
IF RCSTA.FERR ON THEN ErrSerialFrame 'if framing error occurred, handle error
' for non-parity just use this below
ReceiveSerial = RCREG
SET FLAGS.GOTNEWDATA ON
GOTO successreceiveserial
' for parity checking use this
' ParityBit = RCSTA.0 get received parity bit and save
' RxData = RCREG get received data
' CalcParity(RxData)
' rotate ParityByte RIGHT get parity bit into status.c
' IF STATUS.C = ParityBit THEN
' SET FLAGS.GOTNEWDATA ON indicate got new data
' ReceiveSerial = RxData
' GOTO successreceiveserial
' END IF
' ErrSerlParity then parity is different, error
endreceiveserial:
ReceiveSerial = 0
successreceiveserial:
end function
sub ErrSerialOverr 'error because OERR overrun errr bit is set
'this code simply clears and continues
SET RCSTA.CREN OFF
SET RCSTA.CREN ON
end sub
sub ErrSerialFrame 'error because FERR framing error bit is set
movf RCREG,W 'discard received data that has error
movf RCREG,W
movf RCREG,W
end sub
sub ErrSerlParity 'error because parity bit is not correct
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
sub SetupSerial
ADOff 'make port digital
DIR PORTB.7 OUT
DIR PORTB.5 IN
SPBRG = 12 ' this value is for 9600 baud with brgh bit = 0 P16F690
TXSTA = b'00100000' 'note, bit 2 is BRGH
RCSTA = b'10010000' 'enable serial port and reception
SET FLAGS.GOTNEWDATA OFF
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Steve your code runs like a charm, but actually your PIC isn't running at 8 Mhz, only GCBasic compile your code for this speed.
Quoted from help:
"The #chip directive is used to specify the chip model and speed that GCBASIC must compile for. model is the model of the PIC chip - something along the lines of "16F819". speed is the speed of the chip in MHz, and is required for the delay and PWM routines."
For let your 16F690 running at 8 Mhz you need to alter OSCCON register; in GCBasic you can do it with:
OSCCON = 0x70 ' Setting internal oscillator to 8 Mhz
The default speed for 16F690 is 4 Mhz
Greetings
Stefano Bonomi
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for the source code. I just used it to test if the serial on my pic with a MAX233A works correctly on my circuit. If I have some spare time I might modify this library to be more general for other PICs with UART thanks a bunch!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is some code that I've written to make a pic communicate with Hyperterminal in GCBASIC
I thought I'd share it with you all. I wanted to make the setup serial routine "smarter" but haven't got around to that yet. It works fine with a 16F690 @ 9600 baud, 8/n/1, flow control off. There is come parity checking code in there, but I have commented it out, since it works fine without it.
To use, here is a sample program
******************************
'Filename: test_usart.txt
'A program to test serial communications
'Chip model
#chip 16F690, 8
#config INTRC_OSC_NOCLKOUT, WDT_OFF
#include "usart.h"
'Hardware USART constants
'Main routine
ADOFF
dir PORTC.7 out
SetupSerial '9600 baud, 8/N/1 no flow control
Main:
SET PORTC.7 ON
TransmitSerial_Print("Please type in a character ")
Transmitserial(13)
Transmitserial(10)
Loopx:
Character = ReceiveSerial
If flags.gotnewdata OFF then GOTO Loopx
TransmitSerial_Print("Message received, you entered a: ")
TransmitSerial(Character)
Transmitserial(13)
Transmitserial(10)
Set flags.gotnewdata OFF
SET PORTC.7 OFF
wait 25 ms
goto Main
******************************
' Filename: usart.h
' Hardware USART routines for Great Cow BASIC
' Steve Bell
' February 3, 2007
'Subs
' sub SetupSerial Setup serial port with baudrate 9600 for 8Mhz clock
' sub ReceiveSerial(data) Receive data from serial port into byte data
' sub TransmitSerial(data) Transmit data to serial port
' sub TransmitSerial_Print(PrintData$) Transmit a string to the serial port
'Hardware USART constants
#define GOTNEWDATA 0 'bit that indicates new data received
sub SetupSerial(baud_rate,USARTPORT,USART_TX,USART_RX)
ADOff 'make port digital
DIR PORTB.7 OUT
DIR PORTB.5 IN
SPBRG = 12 ' this value is for 9600 baud with brgh bit = 0 P16F690
TXSTA = b'00100000' 'note, bit 2 is BRGH
RCSTA = b'10010000' 'enable serial port and reception
SET FLAGS.GOTNEWDATA OFF
end sub
sub TransmitSerial(xmitdata)
LoopTransmit:
IF PIR1.TXIF OFF THEN goto LoopTransmit 'check if transmitter is busy
TXDATA = xmitdata
' CalcParity(TXDATA) 'calculate parity
' rotate ParityByte RIGHT 'get parity bit into status.c
' SET TXSTA.TX9D OFF 'set parity bit to zero
' IF STATUS.C = 1 THEN SET TXSTA.TX9D ON 'if status.c is one, set parity bit
TXREG = TXDATA 'transmit data
end sub
sub TransmitSerial_Print(PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
TransmitSerial(PrintData(SysPrintTemp))
next
end sub
sub CalcParity(Temp) 'calculate even parity bit, data starts in paritybyte
'result is in Lsb of ParityByte
Paritybyte = Temp 'get data for parity calculation
rrf Paritybyte,W 'rotate
xorwf Paritybyte,W 'compare all bits against neighbor
movwf Paritybyte 'save
rrf ParityByte,F 'rotate
rrf ParityByte,F 'rotate
xorwf ParityByte,F 'compare every 2nd bit and save
swapf ParityByte,W 'rotate 4
xorwf ParityByte,F 'compare every 4th bit and save
end sub
function ReceiveSerial 'check if data received, and if so, return data
IF PIR1.RCIF OFF THEN GOTO endreceiveserial
IF RCSTA.OERR ON THEN ErrSerialOverr 'if overrun error occured, handle error
IF RCSTA.FERR ON THEN ErrSerialFrame 'if framing error occurred, handle error
' for non-parity just use this below
ReceiveSerial = RCREG
SET FLAGS.GOTNEWDATA ON
GOTO successreceiveserial
' for parity checking use this
' ParityBit = RCSTA.0 get received parity bit and save
' RxData = RCREG get received data
' CalcParity(RxData)
' rotate ParityByte RIGHT get parity bit into status.c
' IF STATUS.C = ParityBit THEN
' SET FLAGS.GOTNEWDATA ON indicate got new data
' ReceiveSerial = RxData
' GOTO successreceiveserial
' END IF
' ErrSerlParity then parity is different, error
endreceiveserial:
ReceiveSerial = 0
successreceiveserial:
end function
sub ErrSerialOverr 'error because OERR overrun errr bit is set
'this code simply clears and continues
SET RCSTA.CREN OFF
SET RCSTA.CREN ON
end sub
sub ErrSerialFrame 'error because FERR framing error bit is set
movf RCREG,W 'discard received data that has error
movf RCREG,W
movf RCREG,W
end sub
sub ErrSerlParity 'error because parity bit is not correct
end sub
whoops, the Setupserial subroutine should be:
sub SetupSerial
ADOff 'make port digital
DIR PORTB.7 OUT
DIR PORTB.5 IN
SPBRG = 12 ' this value is for 9600 baud with brgh bit = 0 P16F690
TXSTA = b'00100000' 'note, bit 2 is BRGH
RCSTA = b'10010000' 'enable serial port and reception
SET FLAGS.GOTNEWDATA OFF
end sub
Hi Steve your code runs like a charm, but actually your PIC isn't running at 8 Mhz, only GCBasic compile your code for this speed.
Quoted from help:
"The #chip directive is used to specify the chip model and speed that GCBASIC must compile for. model is the model of the PIC chip - something along the lines of "16F819". speed is the speed of the chip in MHz, and is required for the delay and PWM routines."
For let your 16F690 running at 8 Mhz you need to alter OSCCON register; in GCBasic you can do it with:
OSCCON = 0x70 ' Setting internal oscillator to 8 Mhz
The default speed for 16F690 is 4 Mhz
Greetings
Stefano Bonomi
Thanks for the source code. I just used it to test if the serial on my pic with a MAX233A works correctly on my circuit. If I have some spare time I might modify this library to be more general for other PICs with UART thanks a bunch!