needginer
Mar 2 2008, 9:04 AM
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, 10:43 AM
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? 
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, 11:15 AM
thank, do have any example or sample of pic16f877a asm code? asm o c will be easy for beginner?
Ajay
Mar 3 2008, 2: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, 5: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?
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, 2:22 AM
default is 9600 kbps
needginer
Mar 4 2008, 4:35 AM
any tutorial to teach how to write a program to interface with serial port max232?
Ajay
Mar 4 2008, 10:54 AM
have you written something?
what is the clock frequency? and what is the baud rate you want?
what is the clock frequency? and what is the baud rate you want?
Ajay
Mar 4 2008, 11:05 AM
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.
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, 11:26 AM
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, 1:46 PM
maybe this help you..
http://ww1.microchip.com/downloads/en/DeviceDoc/31018a.pdf
please write something.. are u using C?
http://ww1.microchip.com/downloads/en/DeviceDoc/31018a.pdf
please write something.. are u using C?
needginer
Mar 15 2008, 7: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, 8:04 AM
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.
Suggestion is download a MPASM from Microchip's website where you downloaded MPLAB.
needginer
Mar 15 2008, 8:28 AM
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
CODE:
;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, 8:31 AM
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..

i beleive u have not included the 16fxx.lkr kinda linker file in your project so is the error..

needginer
Mar 15 2008, 8:33 AM
thank, where the 16fxx.lkr should be?
Ajay
Mar 15 2008, 8:38 AM
you said you are trying serial port.. so why this LCD coming?
shyam
Mar 15 2008, 8:51 AM
the linker file should be automatically fetched sill check if u made the project right atke a look at how it shud be done
how_to_use_mplab_ver6.rar
how_to_use_mplab_ver6.rarneedginer
Mar 15 2008, 8:53 AM
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, 9:06 AM
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.
Otherwise you can just take out the initialization, sending and receiving part of serial from the tutorial.
needginer
Mar 16 2008, 2: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, 3:53 PM
its software's problem.. something might be missing.. please check what shyam said. the linker file..
needginer
Mar 17 2008, 4:32 PM
thank. i can compile it already, because i missed some step when compile it before.
Ajay
Mar 17 2008, 5:10 PM
ok
so things working without LCD part?
so things working without LCD part?Matt Lim
Jul 29 2008, 4: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?
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, 4: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?
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?
Ajay
Jul 29 2008, 11:25 AM
for sure PIC will not be pin compatible with 8051, try using polling for IR instead of interrupt or use three pins both anded and connected to interrupt, so whenever interrupt occurs you check which line caused the interrupt.
lcd connections will remain same. do check for the coding part.
lcd connections will remain same. do check for the coding part.
Matt Lim
Jul 30 2008, 1:40 AM
The code for the AT89C51 is this
the schematic circuit is shown. what should i do if i wanna change it to PIC16F877A and LCD?

CODE:
#include <AT89C51.h>int i=o,j,k,l,m, a[]={63,6,91,79,102,109,125,7,127,,111};
void enter (void) interrupt 0
{
i++;
if(i>999) i=999;
P3_1=1;
}
void exit (void) interrupt 2
{
i--;
if (i<0) i=0;
P3_0=0;
for (m=0;m<=1000; m++);
P3_0=1;
}
void main ()
{
IE=133;
TCON=5;
P3_0=1;
P3_1=1;
i=0;
while(1)
{
j=i%10;
k=i/10;
l=i/100;
k=k-l*10;
P2=a[j];
P0=a[k];
P1=a[l];
}
}
void enter (void) interrupt 0
{
i++;
if(i>999) i=999;
P3_1=1;
}
void exit (void) interrupt 2
{
i--;
if (i<0) i=0;
P3_0=0;
for (m=0;m<=1000; m++);
P3_0=1;
}
void main ()
{
IE=133;
TCON=5;
P3_0=1;
P3_1=1;
i=0;
while(1)
{
j=i%10;
k=i/10;
l=i/100;
k=k-l*10;
P2=a[j];
P0=a[k];
P1=a[l];
}
}
the schematic circuit is shown. what should i do if i wanna change it to PIC16F877A and LCD?

Ajay
Jul 30 2008, 11:32 AM
Its really a simple project...
Is it something like this.. you have two doors, enter and exit and your count increment/decrement when someone cross that IR signal.
its easy to port this on PIC. you while 1 will be something like this
regarding IR reception..
connect your IR i/p to PIC like this..
____
----| \_____INT Pin of PIC
----|____/
^its an AND gate
I/ps of AND gate will be your first IR, second IR and o/p is connected to INTR pin of PIC. so whatever IR goes low you will get interrupt on your MCU, in ISR read the status of both pins separately (IR inputs connected to any two GPIOs of PIC). this way you can do same thing as you done in above code, all you need to add is extra code for LCD instead of 7-segment.
Is it something like this.. you have two doors, enter and exit and your count increment/decrement when someone cross that IR signal.
its easy to port this on PIC. you while 1 will be something like this
CODE:
while(1)
{
j=i%10;
k=i/10;
l=i/100;
k=k-l*10;
LCD_putchar(j+0x30);
LCD_putchar(k+0x30);
LCD_putchar(l+0x30);
LCD_putcmd(0x80); //back to first character
}
{
j=i%10;
k=i/10;
l=i/100;
k=k-l*10;
LCD_putchar(j+0x30);
LCD_putchar(k+0x30);
LCD_putchar(l+0x30);
LCD_putcmd(0x80); //back to first character
}
regarding IR reception..
connect your IR i/p to PIC like this..
____
----| \_____INT Pin of PIC
----|____/
^its an AND gate
I/ps of AND gate will be your first IR, second IR and o/p is connected to INTR pin of PIC. so whatever IR goes low you will get interrupt on your MCU, in ISR read the status of both pins separately (IR inputs connected to any two GPIOs of PIC). this way you can do same thing as you done in above code, all you need to add is extra code for LCD instead of 7-segment.
Matt Lim
Jul 31 2008, 6:54 AM
Are my connections correct for PIC16F877A?
Pin 11 and Pin 32 to 5V
Pin 26 to Pin 2 of 74LS76
Pin 1 to Reset
Pin 25 to Pin 11 of 74LS76
Pin 13 to 12Mhz crystal
Pin 14 to 12 Mhz crystal
Pin 31 to GND
and i use RB0 to RB7 and RD0 to RD7 to my LCD
IR input connect to AND and Output to interrupt pin 33 (RB0)
any other pins that need to be grounded or connect to 5v?
I wanna interface it to my pc with visual basic program. I need to add a RS232 to my circuit right? where should i connect it to? im using Microchip PIC KIT, MPLAB and ICD2
I connect the LCD based on the image given can?

Pin 11 and Pin 32 to 5V
Pin 26 to Pin 2 of 74LS76
Pin 1 to Reset
Pin 25 to Pin 11 of 74LS76
Pin 13 to 12Mhz crystal
Pin 14 to 12 Mhz crystal
Pin 31 to GND
and i use RB0 to RB7 and RD0 to RD7 to my LCD
IR input connect to AND and Output to interrupt pin 33 (RB0)
any other pins that need to be grounded or connect to 5v?
I wanna interface it to my pc with visual basic program. I need to add a RS232 to my circuit right? where should i connect it to? im using Microchip PIC KIT, MPLAB and ICD2
I connect the LCD based on the image given can?

Ajay
Jul 31 2008, 11:14 AM
you cant connect Interrupt pin with LCD as it is used for interrupts only from IR sources. So connect LCD control pins to port A rather or any pin you like.
Matt Lim
Aug 1 2008, 3:50 AM
I wanna interface it to my pc with visual basic program. I need to add a RS232 to my circuit right? where should i connect it to? im using Microchip PIC KIT, MPLAB and ICD2
Ajay
Aug 1 2008, 11:46 AM
yes add RS232 circuit (MAX232) in your circuit.
ExperimenterUK
Aug 5 2008, 8:57 PM
Hi Matt
It seems to me you have too many components, something to avoid
where ever possible.
The 2N3904s and the LM324 are both acting as amplifiers and you don't need both.
You certainly don't need the 7476. Whatever it does should be done in software.
Removing these items will clean up your circuit and make it more reliable.
As for sharing interrupts, why bother ?
The PIC has nothing else to do so why not just connect the detectors to
two pins and continuously poll them as Ajay suggested.
>I need to add a RS232 to my circuit right? where should i connect it to?
Connect pins 25 and 26 to a MAX232 (or similar) level converter chip and connect that
to the tx and rx pins of your PC's D9 connector.
I'll leave it to you to sort out which pins,
but try this handy tutorial.
http://www.8051projects.net/serial-communication/introduction.php
Plus... you could use a smaller PIC as you don't need so many pins for the display.
A minor point, but it's better to use a name like "visitorCount" than "I" as a variable name.
It seems to me you have too many components, something to avoid
where ever possible.
The 2N3904s and the LM324 are both acting as amplifiers and you don't need both.
You certainly don't need the 7476. Whatever it does should be done in software.
Removing these items will clean up your circuit and make it more reliable.
As for sharing interrupts, why bother ?
The PIC has nothing else to do so why not just connect the detectors to
two pins and continuously poll them as Ajay suggested.
>I need to add a RS232 to my circuit right? where should i connect it to?
Connect pins 25 and 26 to a MAX232 (or similar) level converter chip and connect that
to the tx and rx pins of your PC's D9 connector.
I'll leave it to you to sort out which pins,
but try this handy tutorial.
http://www.8051projects.net/serial-communication/introduction.php
Plus... you could use a smaller PIC as you don't need so many pins for the display.
A minor point, but it's better to use a name like "visitorCount" than "I" as a variable name.
Matt Lim
Aug 10 2008, 5:50 AM
Hi ExperimenterUK,
Really appreciate your advice as it really had help me alot.thanks so much. i will try to make some adjustments to my circuit and program first. later if i have any problems i will ask for help.
Really appreciate your advice as it really had help me alot.thanks so much. i will try to make some adjustments to my circuit and program first. later if i have any problems i will ask for help.
Matt Lim
Aug 18 2008, 12:11 PM
the polling of the IR detectors how is it done in hardware? do i just connect them by wires? or do i buy an AND gate component?
Matt Lim
Aug 18 2008, 12:42 PM
[blank]
Ajay
Aug 18 2008, 3:22 PM
matt you do not need opamps inbetween controller and photo-transistor, rather you can directly connect IR Receiver (photo-transistor) to controller pin or connect 2N3904 o/p to controller, which also makes polling simpler..
polling can be done the following way..
lets say normally your sensor o/p is high and when someone crosses it, o/p becomes low..
this is how polling is done.
polling can be done the following way..
lets say normally your sensor o/p is high and when someone crosses it, o/p becomes low..
CODE:
while(sensor1 && sensor2); // wait for any of sensor 1 or 2 to be crossed
if(sensor1 == 0){
//someone crossed sensor1
}
if(sensor2 == 0){
//someone crossed sensor2
}
if(sensor1 == 0){
//someone crossed sensor1
}
if(sensor2 == 0){
//someone crossed sensor2
}
this is how polling is done.
Matt Lim
Aug 19 2008, 9:16 AM
is it i should remove the LM324? what about the flip flop? do i keep it?
sashijoseph
Aug 19 2008, 3:19 PM
Just connect the collectors of the 2 transistors to 2 PIC gpio pins and remove all the rest of the components in between.
Without the comparator you would probably need to tinker a bit with the 3904's biasing to make it trigger the PIC appropriately.
Without the comparator you would probably need to tinker a bit with the 3904's biasing to make it trigger the PIC appropriately.
Matt Lim
Aug 21 2008, 7:24 AM
Ajay, means i have to connect the collector pin of 2N3904 to pin 33 of PIC16 right? so i would remove VR1, LM324, and 74LS76?
cause since polling is done in software means the flip flops wont be of any use correct? the rest of the circuit is ok?
cause since polling is done in software means the flip flops wont be of any use correct? the rest of the circuit is ok?
sashijoseph
Aug 21 2008, 2:44 PM
Yup that's right.
Matt Lim
Aug 26 2008, 9:59 AM
...
Ajay
Aug 26 2008, 10:33 AM
I am not sure how you are able to compile your code coz i found these errors by just seeing the code.. like
int i=o <<-- zero or o
a[]={63,6,91,79,102,109,125,7,127,,111};
before 111, you have put two commas. Please fix them and try running code again.
int i=o <<-- zero or o
a[]={63,6,91,79,102,109,125,7,127,,111};
before 111, you have put two commas. Please fix them and try running code again.
Matt Lim
Aug 27 2008, 3:32 AM
.
Ajay
Aug 28 2008, 4:14 AM
can you please explain what are you trying to do in this program, so will be easier to help out.
Matt Lim
Aug 28 2008, 4:23 PM
by configuring the 8051 as a negative edge triggered interrupt sensor i set IT1=1 and IT0=1 correct? then TCON=5 and IE=133. how do i write when the 8051 received interrupt from the sensor, it will display 1 on each increment of the interruption?
Matt Lim
Sep 2 2008, 3:37 AM
is it correct?
Ajay
Sep 2 2008, 5:23 PM
making ITx bit 1 will make your interrupts edge triggered, so whenever your signal goes high to low, you will get an interrupt.
to increment 1 at every interrupt you have to write an ISR (interrupt service routine). example
to increment 1 at every interrupt you have to write an ISR (interrupt service routine). example
CODE:
void INT0ISR() interrupt 0{
//your increment code here for INT0
}
void INT1ISR() interrupt 2{
//code for INT1
}
//your increment code here for INT0
}
void INT1ISR() interrupt 2{
//code for INT1
}
Matt Lim
Sep 3 2008, 12:34 AM
void INT0ISR() interrupt 0{
i++;
if (i>999) i=999;
P3_1=0;
for (m=0;m<=1000;m++);
P3_1=1;
}
void INT1ISR() interrupt 2{
i--;
if(i<0) i = 0;
P3_0=0;
for (m=0; m<=1000;m++);
P3_1=1;
}
The negative going pulse is applied when the persons interrupts the IR beam from TX2. It will trigger the INT0. The value of the counter increments by '1' when interrupt service routine for INT0 is executed right?
i++;
if (i>999) i=999;
P3_1=0;
for (m=0;m<=1000;m++);
P3_1=1;
}
void INT1ISR() interrupt 2{
i--;
if(i<0) i = 0;
P3_0=0;
for (m=0; m<=1000;m++);
P3_1=1;
}
The negative going pulse is applied when the persons interrupts the IR beam from TX2. It will trigger the INT0. The value of the counter increments by '1' when interrupt service routine for INT0 is executed right?
Ajay
Sep 3 2008, 5:44 AM
matt, whenever you have a problem, create your own thread, coz now you are posting in PIC microcontroller section where as your problem is related to 8051. Please take care of these things.