Home - Search - Members
Full Version: PIC16F877A to PC serial port using RS232.
Pages: 1, 2, 3
needginer
Mar 2 2008, 2:04 PM
I have a PIC16F877A which has an 8 bit ADC output. I want to connect it using the Max232 interface to a PC's serial port (COM1) using RS232. I am looking for the asm code on the PIC side as well as the VB or C code (or hyperterminal with steps) on the PC side. im doing a data acquisition system. may i have an sample ASM code about this, plz...

Ajay
Mar 2 2008, 3:43 PM
As you know about site rules.. no giving codes.. but we can correct your codes if you have made any mistake.. for that you have to write something yourself..
Our motive is to make you learn...

So for you.. download PIC16F87XA datasheet and read page starting from 116. I hope you will write something once you care done with controller side.. we will work on VB ok?

needginer
Mar 2 2008, 4:15 PM
thank, do have any example or sample of pic16f877a asm code? asm o c will be easy for beginner?

Ajay
Mar 3 2008, 7:42 AM
Just take a look at the page i told you. It has got complete algorithm of how to configure PIC for UART. for beginner C is easy.. but do work on assembly also, coz its the basic.
needginer
Mar 3 2008, 10:33 AM
In my lecture is learning with C using pic16f84 but online tutorial mostly using assembly.
i had connected the pic with MAX232 and serial port.

PIC16F877A with the MAX232
pin26 RC7 -> pin10 TxD
pin25 RC6 -> pin9 RxD

MAX232 with the Serial Port
pin7 -> pin2
pin8 -> pin3

what is baud rate?
norms
Mar 4 2008, 7:22 AM
default is 9600 kbps
needginer
Mar 4 2008, 9:35 AM
any tutorial to teach how to write a program to interface with serial port max232?
Ajay
Mar 4 2008, 3:54 PM
have you written something?
what is the clock frequency? and what is the baud rate you want?
Ajay
Mar 4 2008, 4:05 PM
one more thing.. please correct your connections:

PIC16F877A with the MAX232
pin26 RC7 -> pin9 TxD
pin25 RC6 -> pin10 RxD

MAX232 with the Serial Port
pin7 -> pin2
pin8 -> pin3

Baud rate is rate at which data is transferred measured in bits per second.
needginer
Mar 4 2008, 4:26 PM
since my friend is using 9600 for the baud rate, so i decide to use 9600 too... the connection was incorrect? i only wrote something about ADC program...
Ajay
Mar 4 2008, 6:46 PM
maybe this help you..
http://ww1.microchip.com/downloads/en/DeviceDoc/31018a.pdf
please write something.. are u using C?
needginer
Mar 15 2008, 11:46 AM
hello everybody.. i had try some code in assembly. by the way im using MPLAB to try it. there is an error. when im trying to [build all] 'compile' the code, come out an error "DOS ERROR: FILE NOT FOUND". what is mean "Skipping link step. The project contains no linker script."? thank for concern

Ajay
Mar 15 2008, 12:04 PM
well the thing is.. MPLAB alone is just an editor so alone it wont work. You need an assembler or a compiler to be installed along with MPLAB and set the preferences in MPLAB to use it for assembling your codes.

Suggestion is download a MPASM from Microchip's website where you downloaded MPLAB.
needginer
Mar 15 2008, 12:28 PM
thank, i got the MPASM compiler but there are still the same error pop out, here is the code that i get from the tutorial. i am trying to understanding the code and make it to achieve my objective.

 
;Tutorial 11
;Reading an analogue input, and displaying it on the LCD and RS232


	LIST	p=16F876, W=2, X=ON, R=DEC	;tell assembler what chip we are using
	include "P16F876.inc"			;include the defaults for the chip
	ERRORLEVEL	0,	-302		;suppress bank selection messages
	__CONFIG    0x393A			;sets the configuration settings (oscillator type etc.)


		cblock	0x20			;start of general purpose registers
			count
			count1	
			counta	
			countb	
			LoX		
			Bit_Cntr	
			Timer_H		
			Flags		
			Flags2		
			tmp1		
			tmp2		
			tmp3			
			NumL	
			NumH	
			TenK		
			Thou	
			Hund	
			Tens			
			Ones		
			templcd	
			templcd2	
			Point			;position of decimal point
		endc

LCD_PORT	Equ	PORTB
LCD_TRIS	Equ	TRISB
LCD_RS		Equ	0x04			;LCD handshake lines
LCD_RW		Equ	0x06
LCD_E		Equ	0x07

LEADZ         	Equ   	0x00   			;set to display leading zeros
LCD		Equ	0x01			;set to print to LCD
RS232		Equ	0x02			;set to print to RS232

;start of program

		ORG	0x0000
		NOP
		BCF	PCLATH,	3
		BCF	PCLATH,	4
		GOTO	Initialise

		ORG	0x0004
		RETURN

		ORG	0x0005


Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB
		clrf	PORTC
		clrf	Flags
		BANKSEL ADCON1			;disable A2D
    		movlw   0x06
    		movwf   ADCON1
    		BANKSEL PORTA	
						;variables for decimal numbers display
		bsf	Flags, LEADZ		;show leading zeros
		bsf	Flags, LCD		;set to print to LCD
		bsf	Flags, RS232		;and also to RS232
		movlw	0x02			;set decimal point position to two
		movwf	Point



SetPorts	bsf 	STATUS,		RP0	;select bank 1
		movlw	0x00			;make all LCD pins outputs
		movwf	LCD_TRIS
		bcf 	STATUS,		RP0	;select bank 0
		call	SER_INIT		;initialise serial port
		call	LCD_Init		;setup LCD module
		call	LCD_CurOff		;turn cursor off
		call	Init_ADC		;initialise analogue input

Main
		bcf	Flags,	RS232		;turn off RS232
		call	LCD_Line1		;set to first line
		call	String1			;display title string
		bsf	Flags,	RS232		;turn RS232 back on

		call	LCD_Line2
		call	Read_ADC		;read analogue input
		call	LCD_Decimal		;and display (in decimal)

		bcf	Flags,	RS232		;turn off RS232
		movlw	'V'
		call	LCD_Char		;display a 'V' on LCD only

		bsf	Flags,	RS232		;turn RS232 back on
		bcf	Flags,	LCD		;and turn off LCD
		movlw	0x0A
		call	LCD_Char		;display a LF
		movlw	0x0D
		call	LCD_Char		;display a CR
		bsf	Flags,	LCD		;turn LCD back on

		call	Delay100		;delay to give 10 readings per second

		goto	Main			;loop for ever

Init_ADC
; Set ADCON0
    		movlw   b'10000001'
    		movwf   ADCON0
; Set ADCON1
    		BANKSEL ADCON1
    		movlw   b'10000101'
    		movwf   ADCON1
    		BANKSEL ADCON0
		return

Read_ADC
    		bsf	ADCON0, GO_DONE		;initiate conversion
    		btfsc   ADCON0, GO_DONE
    		goto    $-1			;wait for ADC to finish

    		movf    ADRESH,W
    		andlw   0x03
    		movwf   NumH
    		BANKSEL ADRESL
    		movf    ADRESL,W
    		BANKSEL	ADRESH
		movwf	NumL			;return result in NumL and NumH
		return


;TABLES
HEX_Table  	addwf   PCL       , f
            	retlw   0x30
            	retlw   0x31
            	retlw   0x32
            	retlw   0x33
            	retlw   0x34
            	retlw   0x35
            	retlw   0x36
            	retlw   0x37
            	retlw   0x38
            	retlw   0x39
            	retlw   0x41
            	retlw   0x42
            	retlw   0x43
            	retlw   0x44
            	retlw   0x45
            	retlw   0x46

Xtext		addwf	PCL, f
		retlw	'T'
		retlw	'u'
		retlw	't'
		retlw	'o'
		retlw	'r'
		retlw	'i'
		retlw	'a'
		retlw	'l'
		retlw	' '
		retlw	'1'
		retlw	'1'
		retlw	'.'
		retlw	'4'
		retlw	0x00

;end of tables

String1		clrf	count			;set counter register to zero
Mess1		movf	count, w		;put counter value in W
		call	Xtext			;get a character from the text table
		xorlw	0x00			;is it a zero?
		btfsc	STATUS, Z
		retlw	0x00			;return when finished
		call	LCD_Char
		incf	count, f
		goto	Mess1

;USART Serial routines

SER_INIT
            	BSF     STATUS, RP0           ;select bank 1
     		MOVLW   d'129'                ;9600 baud @ 20 Mhz Fosc +0.16 err
     		MOVWF   SPBRG
     		MOVLW   b'00100100'           ;brgh = 1
     		MOVWF   TXSTA                 ;enable Async Transmission, set brgh
            	BCF     STATUS, RP0           ;select bank 0
     		MOVLW   b'10010000'
     		MOVWF   RCSTA                 ;enable Async Reception
            	RETURN

XMIT_RS232  	btfss   PIR1,	TXIF 	      ;xmit buffer empty?
     		GOTO	XMIT_RS232            ;no, wait
     		MOVWF   TXREG		      ;now send
                RETURN

Rcv_RS232   	BTFSS   PIR1,	RCIF 	      ; check for received data
     		GOTO    Rcv_RS232
                MOVF    RCREG,	W
                RETURN

;End of serial routines

;LCD routines

;Initialise LCD
LCD_Init	call 	LCD_Busy		;wait for LCD to settle

		movlw	0x20			;Set 4 bit mode
		call	LCD_Cmd

		movlw	0x28			;Set display shift
		call	LCD_Cmd

		movlw	0x06			;Set display character mode
		call	LCD_Cmd

		movlw	0x0c			;Set display on/off and cursor command
		call	LCD_Cmd			;Set cursor off

		call	LCD_Clr			;clear display

		retlw	0x00

; command set routine
LCD_Cmd		movwf	templcd
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high
		call 	LCD_Busy
		retlw	0x00

LCD_CharD	addlw	0x30			;add 0x30 to convert to ASCII
LCD_Char	btfsc	Flags, RS232
		call	XMIT_RS232		;do RS232 if flag set
		btfss	Flags, LCD
		return				;return if LCD not set
		movwf	templcd
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high
		call 	LCD_Busy
		retlw	0x00

LCD_Line1	movlw	0x80			;move to 1st row, first column
		call	LCD_Cmd
		retlw	0x00

LCD_Line2	movlw	0xc0			;move to 2nd row, first column
		call	LCD_Cmd
		retlw	0x00

LCD_Line1W	addlw	0x80			;move to 1st row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_Line2W	addlw	0xc0			;move to 2nd row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_CurOn	movlw	0x0d			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_CurOff	movlw	0x0c			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_Clr		movlw	0x01			;Clear display
		call	LCD_Cmd
		retlw	0x00

LCD_HEX		movwf	tmp1
		swapf	tmp1,	w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		movf	tmp1, w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		retlw	0x00

Pulse_e		bsf	LCD_PORT, LCD_E
		nop
		bcf	LCD_PORT, LCD_E
		retlw	0x00

LCD_Busy
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x0f			;set Port for input
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		bcf	LCD_PORT, LCD_RS	;set LCD for command mode
		bsf	LCD_PORT, LCD_RW	;setup to read busy flag
		bsf	LCD_PORT, LCD_E
		swapf	LCD_PORT, w		;read upper nibble (busy flag)
		bcf	LCD_PORT, LCD_E		
		movwf	templcd2 
		bsf	LCD_PORT, LCD_E		;dummy read of lower nibble
		bcf	LCD_PORT, LCD_E
		btfsc	templcd2, 7		;check busy flag, high = busy
		goto	LCD_Busy		;if busy check again
		bcf	LCD_PORT, LCD_RW
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x00			;set Port for output
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		return

LCD_Decimal
		call    Convert
		btfsc   Flags, LEADZ
		goto    LCD_TENK
		movf    TenK, w
		btfss   STATUS, Z
		goto    LCD_TENK
		movf    Thou, w
		btfss   STATUS, Z
		goto    LCD_THOU
		movf    Hund, w
		btfss   STATUS, Z
		goto    LCD_HUND
		movf    Tens, w
		btfss   STATUS, Z
		goto    LCD_TENS
		goto    LCD_ONES
LCD_TENK
		movlw	0x05			;test if decimal point 5
		subwf   Point, w
		btfss   STATUS    , Z
		goto	NO_DP5
		movlw	'.'
		call	LCD_Char		;display decimal point
NO_DP5		movf    TenK, w
		call    LCD_CharD
		movlw	0x04			;test if decimal point 4
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_THOU
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_THOU
		movf    Thou, w
		call    LCD_CharD
		movlw	0x03			;test if decimal point 3
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_HUND
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_HUND
		movf    Hund, w
		call    LCD_CharD
		movlw	0x02			;test if decimal point 2
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_TENS
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_TENS
		movf    Tens, w
		call    LCD_CharD
		movlw	0x01			;test if decimal point 1
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_ONES
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_ONES
		movf     Ones, w
		call     LCD_CharD
		return


;end of LCD routines


;Delay routines

Delay255	movlw	0xff		;delay 255 mS
		goto	d0
Delay100	movlw	d'100'		;delay 100mS
		goto	d0
Delay50		movlw	d'50'		;delay 50mS
		goto	d0
Delay20		movlw	d'20'		;delay 20mS
		goto	d0
Delay5		movlw	0x05		;delay 5.000 ms (20 MHz clock)
d0		movwf	count1
d1		movlw	0xE7
		movwf	counta
		movlw	0x04
		movwf	countb
Delay_0		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

;end of Delay routines

;This routine downloaded from http://www.piclist.com
Convert:                        ; Takes number in NumH:NumL
                                ; Returns decimal in
                                ; TenK:Thou:Hund:Tens:Ones
        swapf   NumH, w
	iorlw	B'11110000'
        movwf   Thou
        addwf   Thou,f
        addlw   0XE2
        movwf   Hund
        addlw   0X32
        movwf   Ones

        movf    NumH,w
        andlw   0X0F
        addwf   Hund,f
        addwf   Hund,f
        addwf   Ones,f
        addlw   0XE9
        movwf   Tens
        addwf   Tens,f
        addwf   Tens,f

        swapf   NumL,w
        andlw   0X0F
        addwf   Tens,f
        addwf   Ones,f

        rlf     Tens,f
        rlf     Ones,f
        comf    Ones,f
        rlf     Ones,f

        movf    NumL,w
        andlw   0X0F
        addwf   Ones,f
        rlf     Thou,f

        movlw   0X07
        movwf   TenK

                    ; At this point, the original number is
                    ; equal to
                    ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
                    ; if those entities are regarded as two's
                    ; complement binary.  To be precise, all of
                    ; them are negative except TenK.  Now the number
                    ; needs to be normalized, but this can all be
                    ; done with simple byte arithmetic.

        movlw   0X0A                             ; Ten
Lb1:
        addwf   Ones,f
        decf    Tens,f
        btfss   3,0
        goto   Lb1
Lb2:
        addwf   Tens,f
        decf    Hund,f
        btfss   3,0
        goto   Lb2
Lb3:
        addwf   Hund,f
        decf    Thou,f
        btfss   3,0
        goto   Lb3
Lb4:
        addwf   Thou,f
        decf    TenK,f
        btfss   3,0
        goto   Lb4

        retlw	0x00


		end
shyam
Mar 15 2008, 12:31 PM
you dont need to download MPASM it comes integrated with MPLAB...

i beleive u have not included the 16fxx.lkr kinda linker file in your project so is the error..
needginer
Mar 15 2008, 12:33 PM
thank, where the 16fxx.lkr should be?
Ajay
Mar 15 2008, 12:38 PM
you said you are trying serial port.. so why this LCD coming?
shyam
Mar 15 2008, 12:51 PM
the linker file should be automatically fetched sill check if u made the project right atke a look at how it shud be done


needginer
Mar 15 2008, 12:53 PM
thank :-) this the tutorial is about below. Is it ok, if i want to remove all the LCD output? before i remove it, i hope this code could run and do it step by step.

This time we add an extra board, the RS232 Board. The program is essentially Tutorial 11.3, but this time we add a serial output routine to send the data via RS232 to a PC. For the RS232 output we don't send the 'V' at the end, but we do send CR/LF in order to display each reading on a separate line. I've implemented this by modifying the LCD_Char routine and adding a couple of Flags - LCD and RS232 - by setting these flags ON or OFF we can print to either the LCD, the RS232 output, both, or neither.

Ajay
Mar 15 2008, 1:06 PM
if you have LCD on board then try it.. and test it.
Otherwise you can just take out the initialization, sending and receiving part of serial from the tutorial.
needginer
Mar 16 2008, 6:01 AM
but i cant compile it, and cant test with the LCD. with the linker problem :-) the linker problem is a problem in the code o the program?
Ajay
Mar 17 2008, 7:53 PM
its software's problem.. something might be missing.. please check what shyam said. the linker file..
needginer
Mar 17 2008, 8:32 PM
thank. i can compile it already, because i missed some step when compile it before.
Ajay
Mar 17 2008, 9:10 PM
ok so things working without LCD part?
Matt Lim
Jul 29 2008, 8:45 AM
Is this topic closed? if not i would like to add my doubts on my project im working on. Im doing a microcontroller based bidirectional visitor counter. Im using AT89C51, three 7-segments LEDS, one 74LS76 J-K flip flop, one LM324 quad op amp, IR transmitting LED, L14F1 npn phototransistor as my sensors and 2N3904 npn transistor. I would like to change the microcontroller to PIC16F877A and the 7 segments to LCDs. After that i will interface it with the PC with a serial port using RS232. I need some help on a few issues.
1) What pins should be reconnected when i change to PIC16F877A?
2) In AT89C52 i used 2 interrupts to detect the interruption of the sensors but for PIC16F877A i only have one interrupt to work with, how should i solve this?
3) what are the connections for the pins of the LCD?
Matt Lim
Jul 29 2008, 8:52 AM
Additional info:
AT89C51 P0,P1,P2 is connected to the 7segments. Pin 40,Pin31 to 5V. P3 to 74LS76 pin 2. INT0 to 74LS76 pin 15. INT1 to 74LS76 pin 11. P3.1 to 74LS76 pin7. Pin 18 and Pin 19 connected to 12Mhz crystal. Pin20 to GND. For PIC16F877A what should be the changes?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Rickey's World © 2003 - 2007