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.

Reading from an SD card through PIC16F877A with assembly

Status
Not open for further replies.

crimebeats

Newbie level 1
Newbie level 1
Joined
Dec 21, 2013
Messages
0
Helped
0
Reputation
0
Reaction score
0
Trophy points
0
Visit site
Activity points
15
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:
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.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top