crimebeats
Newbie level 1
Hello,
I have a small project, which basically reads a text file from an SD card and sends the data through serial communication to another pic16f877a which sends it to an LCD. The code has to be written in assembly, so the attached code below is in assembly language. I have found a lot of resources on how to deal with an SD card, but all of them use C/C++ which isn't clear for me. I am attempting to use the SPI module to read from the SD card.
Here is my proteus model iamge:
**broken link removed**
Here is the code for the pic that reads from the image:
The PIC waits until it receives a receive interrupt from serial communication which tells it the number of text file. After that, the card will start reading from the SD card and send what it reads through serial communication to the other pic.
I've used Port D to check if serial communication is working. It is not. And I'm not getting any results on the LCD.
The pic that reads from the SD card:
Here is the code that reads from a push button (the number of file to read) and send it through serial communication to the other pic. The data this PIC receives through serial communication will be displayed on the LCD.
I know the codes are very long, but I'd be very very very grateful if someone helps me with it.
Thank you.
Ps. If you'll try to modify the code please do in the assembly language.
I have a small project, which basically reads a text file from an SD card and sends the data through serial communication to another pic16f877a which sends it to an LCD. The code has to be written in assembly, so the attached code below is in assembly language. I have found a lot of resources on how to deal with an SD card, but all of them use C/C++ which isn't clear for me. I am attempting to use the SPI module to read from the SD card.
Here is my proteus model iamge:
**broken link removed**
Here is the code for the pic that reads from the image:
The PIC waits until it receives a receive interrupt from serial communication which tells it the number of text file. After that, the card will start reading from the SD card and send what it reads through serial communication to the other pic.
I've used Port D to check if serial communication is working. It is not. And I'm not getting any results on the LCD.
The pic that reads from the SD card:
Code:
__CONFIG _DEBUG_OFF&_CP_OFF&_WRT_HALF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_OFF&_WDT_OFF&_XT_OSC
LIST p=16F877a
include "p16f877A.inc"
cblock 0x20
tempChar ;holds the character to be displayed
charCount ;holds the number of the English alphabet
lsd ;lsd and msd are used in delay loop calculation
msd
trapper1
pressedbutton2
numnulls
WTemp
theone
StatusTemp
endc
push macro
movwf WTemp ;WTemp must be reserved in all banks
swapf STATUS,W ;store in W without affecting status bits
banksel StatusTemp ;select StatusTemp bank
movwf StatusTemp ;save STATUS
endm
pop macro
banksel StatusTemp ;point to StatusTemp bank
swapf StatusTemp,W ;unswap STATUS nibbles into W
movwf STATUS ;restore STATUS (which points to where W was stored)
swapf WTemp,F ;unswap W nibbles
swapf WTemp,W ;restore W without affecting STATUS
endm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x00 ; Reset Vector
goto Main
org 0x04 ; Interrupt Vector
goto IntService
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Initial
banksel theone
movlw 0xff
movwf theone
banksel SSPCON
bsf SSPCON, 5 ; Enable synchronous transmission
bcf SSPCON, 0
bcf SSPCON, 1
bcf SSPCON, 2
bcf SSPCON, 3 ; SPI master mode, clock =fosc/64
movlw D'25' ; This sets the baud rate to 9600
banksel SPBRG ; assuming BRGH=1 and Fosc = 4.000 MHz
movwf SPBRG
banksel TRISD
movlw 0x00
movwf TRISD
banksel PORTD
clrf PORTD
banksel PIE1
bcf PIE1, SSPIE ; interrupt enable of synchoronous
bsf PIE1,RCIE
banksel SSPSTAT
bcf SSPSTAT,7
bcf SSPSTAT,6
bcf TRISC, 6 ; Configuring pins RC6 as o/p, RC7 as i/p for
bsf TRISC, 7 ; serial communication
bcf TRISC, 5 ; Configuring pins RC5 as o/p, RC4 as i/p for
bsf TRISC, 4 ; synchronous communication
bcf TRISC, 2
bcf TRISC, 3
banksel RCSTA
bsf RCSTA, SPEN ; Enable serial port
bsf RCSTA, CREN ; Enable Receiver
banksel TXSTA
bcf TXSTA, SYNC ; Set up the port for Asynchronous operation
bsf TXSTA, TXEN ; Enable Transmitter
bsf TXSTA, BRGH ; High baud rate used
banksel PIE1
bsf PIE1,RCIE ; Enable Receiver Interrupt
banksel ADCON1
bsf ADCON1,0
bsf ADCON1,1
bsf ADCON1,2
bsf ADCON1,3
banksel INTCON
bsf INTCON, GIE ; Enable global and peripheral interrupts
bsf INTCON, PEIE
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main
call Initial
banksel numnulls
clrf numnulls
incf numnulls
idle
goto idle
readorsend
movf numnulls,w
sublw pressedbutton2
btfss STATUS,Z
goto justread
goto justsend
justread
banksel SSPBUF
movf SSPBUF,w
btfsc STATUS,Z
goto nullroutine
goto idle
justsend
banksel SSPBUF
movf SSPBUF,w
btfsc STATUS,Z
goto idle
call SENDff
goto idle
nullroutine
banksel numnulls
incf numnulls
goto readorsend
;*********************receive data******8
IntService
push
btfsc PIR1, RCIF ; Check for RX interrupt
call RX_Receive
btfsc PIR1, SSPIF
goto readorsend
rethere
pop
retfie
RX_Receive
bcf PIR1, RCIF ;Pass the value of RCREG to PORTD
banksel RCREG
movf RCREG, W
banksel pressedbutton2
movwf pressedbutton2
banksel theone
clrf theone
banksel PORTC
bcf PORTC,2
banksel pressedbutton2
movf pressedbutton2,W
banksel PORTD
movwf PORTD
return
delay
movlw 0x80
movwf msd
clrf lsd
loopa
decfsz lsd,f
goto loopa
decfsz msd,f
goto loopa
return
;*******************send data**********
SENDff
banksel SSPBUF
movf SSPBUF, W
movwf TXREG
TX_not_done
banksel TXSTA ; Polling for the TRMT flag to check
btfss TXSTA, TRMT ; if TSR is empty or not
goto TX_not_done
return
end
Here is the code that reads from a push button (the number of file to read) and send it through serial communication to the other pic. The data this PIC receives through serial communication will be displayed on the LCD.
Code:
__CONFIG _DEBUG_OFF&_CP_OFF&_WRT_HALF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_OFF&_WDT_OFF&_XT_OSC
;**********************************************************************************
LIST p=16F877a
include "p16f877A.inc"
;**********************************************************************************
cblock 0x20
tempChar ;holds the character to be displayed
charCount ;holds the number of the English alphabet
lsd ;lsd and msd are used in delay loop calculation
msd
trapper1
pressedbutton
StatusTemp
WTemp
endc
;**********************************************************************************
push macro
movwf WTemp ;WTemp must be reserved in all banks
swapf STATUS,W ;store in W without affecting status bits
banksel StatusTemp ;select StatusTemp bank
movwf StatusTemp ;save STATUS
endm
pop macro
banksel StatusTemp ;point to StatusTemp bank
swapf StatusTemp,W ;unswap STATUS nibbles into W
movwf STATUS ;restore STATUS (which points to where W was stored)
swapf WTemp,F ;unswap W nibbles
swapf WTemp,W ;restore W without affecting STATUS
endm
;**********************************************************************************
org 0x00 ; Reset Vector
goto Main
org 0x04 ; Interrupt Vector
goto IntService
;**********************************************************************************
;**********************************************************************************
Initial
Banksel TRISA ;PORTC and PORTB as outputs
Clrf TRISA
Clrf TRISD
movlw 0x0F
movwf TRISB ;pushbuttons and leds
Banksel ADCON1
movlw 07 ;set PORTA as general Digital I/O PORT
movwf ADCON1
Banksel PORTA
Clrf PORTA
Clrf PORTD
Clrf PORTB
movlw d'26'
Movwf charCount ; initialize charCount with 26:
; Number of Characters in the English language
Movlw 0x38 ;8-bit mode, 2-line display, 5x7 dot format
Call send_cmd
Movlw 0x0e ;Display on, Cursor Underline on, Blink off
Call send_cmd
Movlw 0x02 ;Display and cursor home
Call send_cmd
Movlw 0x01 ;clear display
Call send_cmd
movlw D'25' ; This sets the baud rate to 9600
banksel SPBRG ; assuming BRGH=1 and Fosc = 4.000 MHz
movwf SPBRG
banksel RCSTA
bsf RCSTA, SPEN ; Enable serial port
bsf RCSTA, CREN ; Enable Receiver
banksel TXSTA
bcf TXSTA, SYNC ; Set up the port for Asynchronous operation
bsf TXSTA, TXEN ; Enable Transmitter
bsf TXSTA, BRGH ; High baud rate used
banksel PIE1
bsf PIE1,RCIE ; Enable Receiver Interrupt
banksel INTCON
bsf INTCON, GIE ; Enable global and peripheral interrupts
bsf INTCON, PEIE
banksel TRISD ; PORTD is used to display the received commands
clrf TRISD
clrf TRISA
bcf TRISC, 6 ; Configuring pins RC6 as o/p, RC7 as i/p for
bsf TRISC, 7 ; serial communication
banksel ADCON1
movlw 6
movwf ADCON1
banksel PORTD
clrf PORTD
clrf PORTA
clrf PORTB
return
;**********************************************************************************
; Main Routine
;**********************************************************************************
Main
call Initial
loop3
Movf PORTB,f
btfss PORTB,0
goto button1
btfss PORTB,1
goto button2
btfss PORTB,2
goto button3
btfss PORTB,3
goto button4
goto loop3
notbutton1
decfsz trapper1
goto notbutton2
goto button2
notbutton2
decf trapper1
decfsz trapper1
goto button4
goto button3
button1
movlw 0x01
movwf pressedbutton
bsf PORTB,4
bcf PORTB,5
bcf PORTB,6
bcf PORTB,7
goto SEND
button2
movlw 0x02
movwf pressedbutton
bsf PORTB,5
bcf PORTB,4
bcf PORTB,6
bcf PORTB,7
goto SEND
button3
movlw 0x03
movwf pressedbutton
bsf PORTB,6
bcf PORTB,4
bcf PORTB,5
bcf PORTB,7
goto SEND
button4
movlw 0x04
movwf pressedbutton
bsf PORTB,7
bcf PORTB,4
bcf PORTB,5
bcf PORTB,6
goto SEND
SEND
movf pressedbutton, W
movwf TXREG
TX_not_done
banksel TXSTA ; Polling for the TRMT flag to check
btfss TXSTA, TRMT ; if TSR is empty or not
goto TX_not_done
banksel pressedbutton
loop6
goto loop3
loop1
Movf PORTC,f
btfss STATUS,Z
goto loop1
loop2
Movf PORTC,w
btfsc STATUS,Z
goto loop3
call send_char
; code to take the next data from PORTC
goto loop2
; Interrupt Service Routine
IntService
push
btfsc PIR1, RCIF ; Check for RX interrupt
call RX_Receive
pop
retfie
RX_Receive
bcf PIR1, RCIF ;Pass the value of RCREG to PORTD
;************************************************************************************
banksel RCREG
movf RCREG, W
banksel PORTD
call send_cmd
return
Movwf tempChar
CharacterDisplay ; Generate and display all 26 English Letters
Call send_char
Movf tempChar ,w ; ‘A’ has the ASCII code of 65 decimal (0x41), by
Addlw 1 ; adding 1 to it we have 66, which is B. Therefore, by
movwf tempChar ; continuously adding 1 to tempChar we are cycling
movf tempChar ,w ; through the ASCII table (here: alphabets)
decfsz charCount
goto CharacterDisplay
Mainloop
Movlw 0x1c ;This command shifts the display to the right once
Call send_cmd
Call delay
Call delay
Call delay
Call delay
Goto Mainloop ; This loop makes the character rotate continuously
;**********************************************************************************
send_cmd
banksel PORTD
movwf PORTD ; Refer to table 1 on Page 5 for review of this subroutine
bcf PORTA, 1
bsf PORTA, 3
nop
bcf PORTA, 3
bcf PORTA, 2
call delay
return
;**********************************************************************************
send_char
banksel PORTD
movwf PORTD ; Refer to table 1 on Page 5 for review of this subroutine
bsf PORTA, 1
bsf PORTA, 3
nop
bcf PORTA, 3
bcf PORTA, 2
call delay
return
;**********************************************************************************
delay
movlw 0x80
movwf msd
clrf lsd
loopa
decfsz lsd,f
goto loopa
decfsz msd,f
goto loopa
return
;**********************************************************************************
End
I know the codes are very long, but I'd be very very very grateful if someone helps me with it.
Thank you.
Ps. If you'll try to modify the code please do in the assembly language.