Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

help on Serial Communication using software not UART

Status
Not open for further replies.

ece4afe

Junior Member level 1
Joined
Jun 16, 2005
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,422
uart serial communication

hello,

Pls advise me how to implement serial communication tru software programming. il be using a pic16f84a which doesnt have a built in UART. I know the theory of serial communication and I want to implement it thru software programming. Please teach me how to program it or if you have sample code for me to read and understand. This is my first time to program serial communication. my plan is to send ASCII characters from PIC to PC, which will be seen in the hyperterminal. I want to realize and appreciate the theory of serial communication.
Please help me on this.

Tnx,

Chris
 

m_rs096.asm

first choose what programming language you would use so that your computer and mcu would communicate, you could use either C, visual basic and even matlab. For the mcu, you could either make one input be a serial input by just creating a program that would make that port receive serial data
 

what is line feed in serial communication

Hi Chris,
I thought I had some of my own examples, but it has been a long time since I did anything with an F84, however, I did find something that is nicely coded, and should serve you well. I think it came from:https://www.electronic-engineering.ch/microchip/index.html
which is a helpful page. (and you may need some other header files from there)
Anyway, here is the example, I hope it works for you.
Best wishes,
Robert

PS, yes you will need to go to his site and get the m_wait, and m_bank files, but should you have any problems, let me know, and I'll help you as much as I can.
regards

Code:
;***************************************************************************
;                                                                     
;	RS232 Communication Test for PIC 16XXX
;	======================================
;
;	written by Peter Luethi, 26.03.1999, Dietikon, Switzerland
;	[url]https://www.electronic-engineering.ch[/url]
;	last update: 11.04.2004
;
;	V1.02:	Fixed copy/paste issue of ISR context store/restore
;		(nobody is perfect): Erroneously erased INTCON,INTF
;		clearing, resulting in endless ISR calling...
;		Re-structured entire ISR and RS232 echo sub-routines
;		(11.04.2004)
;	V1.01:	ISR context restore improvements (30.12.2000)
;	V1.00:	Initial release (26.3.1999)
;
;	This code and accompanying files may be distributed freely and
;	modified, provided this header with my name and this notice remain
;	intact. Ownership rights remain with me.
;	You may not sell this software without my approval.
;
;	This software comes with no guarantee or warranty except for my
;	good intentions. By using this code you agree to indemnify me from
;	any liability that might arise from its use.
;
;	
;	SPECIFICATIONS:
;	===============
;	Processor:			Microchip PIC 16F84
;	Clock Frequency:		4.00 MHz XT
;	Throughput:			1 MIPS
;	Baud Rate:			9600 baud, 8 bit, no parity, 1 stopbit
;	Code Size of entire Program:	approx. 570 instruction words
;	Required Hardware:		MAX 232, dot matrix LCD display
;
;
;	DESCRIPTION:
;	============
;	Developed and tested on PIC 16F84, executeable on all interrupt
;	featured PICs.
;	Program handles all aspects of
;		Transmission (Register TXD) and
;		Reception (Register RXD) through interrupt.
;	Display of received ASCII characters sent from RS232 host and
;	their decimal representation on the dot matrix LCD display.
;	The microcontroller sends feedback of received characters back to
;	the terminal window.
;
;***************************************************************************

;***** COMPILATION MESSAGES & WARNINGS *****

	ERRORLEVEL -207 	; found label after column 1
	ERRORLEVEL -302 	; register in operand not in bank 0

;***** PROCESSOR DECLARATION & CONFIGURATION *****

	PROCESSOR 16F84
	#include "p16f84.inc"
	
	; embed Configuration Data within .asm File
	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;***** MEMORY STRUCTURE *****

	ORG     0x00			; processor reset vector
  	goto    MAIN			; main program

	ORG     0x04			; interrupt vector
	goto	ISR			; Interrupt Service Routine (ISR)

;***** PARAMETERIZATION *****

	CONSTANT LCDWAIT =	0x02	; LCD wait for initialization
	CONSTANT LCDSPEED =	0x01	; configure according to PIC clock
	
;***** PORT DECLARATION *****

	#define	TXport	PORTA,0x00	; RS232 output port, could be
	#define	TXtris	TRISA,0x00	; any active push/pull port

	LCDtris	equ	TRISB
	LCDport	equ	PORTB

;***** CONSTANT DECLARATION *****

	CONSTANT BASE = 0x0C		; base address of user file registers

;***** REGISTER DECLARATION *****

	TEMP1	set	BASE+d'0'	; Universal temporary register
	TEMP2	set	BASE+d'1'	; ATTENTION !!!
	TEMP3	set	BASE+d'2'	; They are used by various modules.
	TEMP4	set	BASE+d'3'	; If you use them, make sure not to use
	TEMP5	set	BASE+d'4'	; them concurrently! No use in ISR!

	LO	equ	BASE+d'5'
	LO_TEMP	equ	BASE+d'6'

	FLAGreg	equ	BASE+d'7'
	#define	RSflag	FLAGreg,0x00	; RS232 data reception flag
	#define LCDbusy FLAGreg,0x01	; LCD busy flag
	#define	LCDcflag FLAGreg,0x02	; LCD command/data flag
	#define	BCflag	FLAGreg,0x04	; blank checker for preceeding zeros

	TXD	equ	BASE+d'8'	; TX-Data register
	RXD	equ	BASE+d'9'	; RX-Data register

	W_TEMP	equ	BASE+d'10'	; context register (ISR)
	STATUS_TEMP equ	BASE+d'11'	; context register (ISR)
	PCLATH_TEMP equ	BASE+d'12'	; context register (ISR)
	FSR_TEMP equ	BASE+d'13'	; context register (ISR)

;***** INCLUDE FILES *****

	#include "..\..\m_bank.asm"
	#include "..\..\m_wait.asm"
	#include "..\..\m_lcd_bf.asm"
	#include "..\..\m_lcdv08.asm"
	#include "..\..\m_rs096.asm"	; standard RS232 baud rate

;***** MACROS *****

;***** SUB-ROUTINES *****

RSservice 
	LCD_DDAdr 0x45
	movfw	RXD		; get received RS232 data
	LCDw			; send to LCD display
	LCD_DDAdr 0x4D
	movfw	RXD
	movwf	LO
	LCDval_08		; display decimal value
	
	SEND	TAB
	SEND	'r'
	SEND	'e'
	SEND	'c'
	SEND	'e'
	SEND	'i'
	SEND	'v'
	SEND	'e'
	SEND	'd'
	SEND	' '

	movfw	RXD		; get received RS232 data
	SENDw			; transmit across RS232

	SEND	' '
	SEND	'o'
	SEND	'n'
	SEND	' '
	SEND	'M'
	SEND	'i'
	SEND	'c'
	SEND	'r'
	SEND	'o'
	SEND	'c'
	SEND	'h'
	SEND	'i'
	SEND	'p'
	SEND	' '
	SEND	'P'
	SEND	'I'
	SEND	'C'
	SEND	'1'
	SEND	'6'
	SEND	'F'
	SEND	'8'
	SEND	'4'
	SEND	CR		; Carriage Return
	SEND	LF		; Line Feed

	; end of RS232 service (echo & display)
	bcf	RSflag		; reset RS232 data reception flag
	bsf	INTCON,INTE	; re-enable RB0/INT interrupt
	RETURN


;***** INTERRUPT SERVICE ROUTINE *****

ISR	;************************
	;*** ISR CONTEXT SAVE ***
	;************************

	bcf	INTCON,GIE	; disable all interrupts
	btfsc	INTCON,GIE	; assure interrupts are disabled
	goto	ISR
	movwf	W_TEMP		; context save: W
	swapf	STATUS,W	; context save: STATUS
	movwf	STATUS_TEMP	; context save
	clrf	STATUS		; bank 0, regardless of current bank
	movfw	PCLATH		; context save: PCLATH
	movwf	PCLATH_TEMP	; context save
	clrf	PCLATH		; page zero, regardless of current page
	bcf	STATUS,IRP	; return to bank 0
	movfw	FSR		; context save: FSR
	movwf	FSR_TEMP	; context save
	;*** context save done ***

	;**************************
	;*** ISR MAIN EXECUTION ***
	;**************************
	
	;*** determine origin of interrupt ***
	btfsc	INTCON,INTF	; check for RB0/INT interrupt
	goto	_ISR_RS232	; if set, there was a keypad stroke

	; catch-all
	goto	ISRend		; unexpected IRQ, terminate execution of ISR

	;******************************
	;*** RS232 DATA ACQUISITION ***
	;******************************
_ISR_RS232
	; first, disable interrupt source
	bcf	INTCON,INTE	; disable RB0/INT interrupt
	; second, acquire RS232 data
	RECEIVE			; macro of RS232 software reception
	bsf	RSflag		; enable RS232 data reception flag
	goto	_ISR_RS232end	; terminate RS232 ISR properly

	;***********************************
	;*** CLEARING OF INTERRUPT FLAGS ***
	;***********************************
	; NOTE: Below, I only clear the interrupt flags! This does not
	; necessarily mean, that the interrupts are already re-enabled.
	; Basically, interrupt re-enabling is carried out at the end of
	; the corresponding service routine in normal operation mode.
	; The flag responsible for the current ISR call has to be cleared
	; to prevent recursive ISR calls. Other interrupt flags, activated
	; during execution of this ISR, will immediately be served upon
	; termination of the current ISR run.
_ISR_RS232error
	bsf	INTCON,INTE	; after error, re-enable IRQ already here
_ISR_RS232end
	bcf	INTCON,INTF	; clear RB0/INT interrupt flag
	;goto	ISRend		; terminate execution of ISR

	;*****************************************
	;*** ISR TERMINATION (CONTEXT RESTORE) ***
	;*****************************************

ISRend	movfw	FSR_TEMP	; context restore
	movwf	FSR		; context restore
	movfw	PCLATH_TEMP	; context restore
	movwf	PCLATH		; context restore
	swapf	STATUS_TEMP,W	; context restore
	movwf	STATUS		; context restore
	swapf	W_TEMP,F	; context restore
	swapf	W_TEMP,W	; context restore
	RETFIE			; enable global interrupt (INTCON,GIE)

;***** END OF INTERRUPT SERVICE ROUTINE *****


;************** MAIN **************

MAIN	LCDinit			; LCD Initialization
	RS232init		; RS232 Initialization
	clrf	FLAGreg		; initialize all flags

	;*** START-UP MESSAGE of LCD ***
	LCDchar	'R'
	LCDchar	'S'
	LCDchar	'2'
	LCDchar	'3'
	LCDchar	'2'
	LCDchar	' '
	LCDchar	'C'
	LCDchar	'o'
	LCDchar	'm'
	LCDchar	'm'
	LCDchar	'u'
	LCDchar	'n'
	LCDchar	'i'
	LCDchar	'c'
	LCDchar	'a'
	LCDchar	'-'

	LCDline	2
	
	LCDchar	't'
	LCDchar	'i'
	LCDchar	'o'
	LCDchar	'n'
	LCDchar	' '
	LCDchar	'o'
	LCDchar	'n'
	LCDchar	' '
	LCDchar	'P'
	LCDchar	'I'
	LCDchar	'C'
	LCDchar	'1'
	LCDchar	'6'
	LCDchar	'F'
	LCDchar	'8'
	LCDchar	'4'

	;*** START-UP MESSAGE to RS232 ***
	; this is done by reading a look-up table
	; define amount of table items for start-up message
	#define	tab_size4 d'48'
	movlw	tab_size4	; store amount of table items in counter
	movwf	TEMP5
	; transmit message
_ILOOP1	movlw	HIGH WelcomeTable ; get correct page for PCLATH
	movwf	PCLATH		; prepare right page bits for table read
	movfw	TEMP5		; get actual count-down value
	sublw	tab_size4	; table offset: w = tab_size4 - TEMP6
	call	WelcomeTable	; call lookup table
	SENDw			; RS232 output
	decfsz	TEMP5,f		; decrement counter
	goto	_ILOOP1

	WAITX	0x1A,  b'00000111'	; wait some time

	; a little bit animation...
	SEND	'a'
	SEND	'n'
	SEND	'i'
	SEND	'm'
	SEND	'a'
	SEND	't'
	SEND	'i'
	SEND	'n'
	SEND	'g'
	SEND	' '
	SEND	'L'
	SEND	'C'
	SEND	'D'
	SEND	'.'
	SEND	'.'
	SEND	'.'
	SEND	CR		; Carriage Return
	SEND	LF		; Line Feed

	movlw	d'16'
	movwf	TEMP5
_SHL1	LCDcmd	LCDSL		; shift left LCD display content
	WAIT	0xC0
	decfsz	TEMP5,f
	goto	_SHL1

	; finally, reset/clear LCD
	LCDcmd	LCDCLR
	
	LCDchar	'R'
	LCDchar	'S'
	LCDchar	'2'
	LCDchar	'3'
	LCDchar	'2'
	LCDchar	' '
	LCDchar	'R'
	LCDchar	'e'
	LCDchar	'c'
	LCDchar	'e'
	LCDchar	'p'
	LCDchar	't'
	LCDchar	'i'
	LCDchar	'o'
	LCDchar	'n'
	LCDchar	':'

	LCDline	2
	
	LCDchar	'C'
	LCDchar	'h'
	LCDchar	'a'
	LCDchar	'r'
	LCD_DDAdr 0x47
	LCDchar	'V'
	LCDchar	'a'
	LCDchar	'l'
	LCDchar	'u'
	LCDchar	'e'

	SEND	'r'
	SEND	'e'
	SEND	'a'
	SEND	'd'
	SEND	'y'
	SEND	'.'
	SEND	'.'
	SEND	'.'
	SEND	CR		; Carriage Return
	SEND	LF		; Line Feed
	
	;******************************
LOOP	btfsc	RSflag		; check RS232 data reception flag
	call	RSservice	; if set, call RS232 echo & LCD display routine
	goto	LOOP
	;******************************

	;ORG	0x230		; if necessary, move look-up tables

WelcomeTable
	addwf	PCL,F		; add offset to table base pointer
	retlw	CR
	retlw	LF
	DT	"Microchip PIC16F84 connected and stand-by..." ; create table
	retlw	CR
WTableEND retlw	LF
	IF (HIGH (WelcomeTable) != HIGH (WTableEND))
		ERROR "WelcomeTable hits page boundary!"
	ENDIF

	END
 

uart theory

hello,

my target is to have a serial communication, which is purely software, no UART since f84 has no built in uart, and no interrupt as well. So therefore the program will look like this manner,

let say if i want to send capital C which is 43hex, to PC, i will send first the start bit which is a logic zero, then delay (9600kbps--->about 104us) then the data which is the letter C(01000011 in binary), where in, MSB first, then delay again, then the next bit, delay...............until I arrive at Last or LSB, delay then the stop bit, which is a logic one.

I am using C in programming.

Could you give me atleast a hint on how to attack this problem

Regards,

Chris
 

communicate using uart in c

I believe the best thing you could use will be a constant bit rate, serial communication. and i also recommend to use a null character instead of a start or stop bit,
 

how does software read serial communication

Chris,
If you looked at the assembly I gave you, it is for a 16F84, which I realize has no hardware UART. And if you look at the data sheet for your PIC you will find, on page 3 that it has:
• Four interrupt sources:
- External RB0/INT pin
- TMR0 timer overflow
- PORTB<7:4> interrupt on change
- Data EEPROM write complete
You didn't say how you were programming it, but you did say you wanted
to realize and appreciate the theory of serial communication
which led me to believe you wanted something in assembly. While C is closer to the hardware than most high level languages, it is still a high level language, and you will not get as much out of it as you would assembly. That said, which C compiler are you using? They each have thier own ways of producing hex code, and some even include some libraries. In many compilers, to get the right timing, you will have to inline assembly, at least for the delays, for this to work well.
If I remember, too, you send the LSB first, not the MSB.
Basically, you loop through the byte you want to send. Your line is high in idle, you clear it to send a start bit, then call your delay. Read the first bit of the data you wish to send. If it is a one, then set your pin and call your delay. (This is where is gets tricky with C - how many cycles does it take to get into the dely with your compiler?) Then you shift your bite to the right, and check the next bit. If your bit is high, set the pin. If your bit is low, clear the pin. Then call your delay again. Do this until you have shifted your byte out, and when you are done, send the stop bit.
I would recomend sending just one char until you have it working.
If you are just sending from the PIC, not receiving, you should be able to do it without interrupts, unless you choose to use them for timing.
Again, which compiler are you using?
Regards,
Robert

PS here is a tutorial on software serial comms:https://www.sparkfun.com/commerce/present.php?p=The Serial Biggie Page1
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top