Thanks Paul for your shared codes!!! It is great.
I did the same test, but used PIC16LF877(3.0V) and FM25V10(3.0V,1Mbit). I think the communication is the same, only with some minor modifications. I spent almost one day on it,still get no result yet.... Can you help me to check if there is anything wrong with it?
Thanks!
Code:'**************************************************************** '* Name : HARDWARE_SPI_FRAM TEST.BAS * '* Author : [select VIEW...EDITOR OPTIONS] * '* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 3/17/2010 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** '**************************************************************** Define OSC 10 'INCLUDE "modedefs.bas" DEFINE LOADER_USED 1 Define LCD_DREG PORTD Define LCD_DBIT 4 Define LCD_RSREG PORTE Define LCD_RSBIT 0 Define LCD_EREG PORTE Define LCD_EBIT 1 Low PORTE.2 ' LCD R/W line low (W) ADCON1 = %10000010 ' Set PORTA analog and right justify result Pause 500 ' Wait .5 second Low PORTE.2 ' LCD R/W line low (W) ADCON1 = %10000010 ' Set PORTA analog and right justify result Pause 500 ' Wait .5 second Ticks VAR word ' Tick count (61 ticks = 1 sec) Hour VAR byte ' Hour variable Minute VAR byte ' Minute variable Second VAR byte ' Second variable Disp VAR byte ' Disp = 1 to update display ' Interrup handling bits GIE var INTCON.7 PEIE var INTCON.6 TMR2IE VAR PIE1.1 TMR2ON VAR T2CON.2 TMR2IF VAR PIR1.1 ' Definations for the SPI communication protocal '------------------------------------------------------------------ 'TRISB.5=0 ' This is for the CS PIN FM_CS VAR PORTA.5 ' SPI FRAM CHIP CS PIN FM_CS_TRIS VAR TRISA.5 ' SPI FRAM CHIP CS PIN DIRECTION SCK VAR PORTC.3 ' SPI CLOCK SCK_TRIS VAR TRISC.3 ' SPI CLOCK PIN DIRECTION CONTROL SDI VAR PORTC.4 ' SPI DATA IN SDI_TRIS VAR TRISC.4 ' SPI DATA IN PIN DIRECTION SDO VAR PORTC.5 ' SPI DATA OUT PIN SDO_TRIS VAR TRISC.5 ' SPI DATA OUT PIN WCOL VAR SSPCON.7 'SSP WRITE COLLISION SSPEN VAR SSPCON.5 'SSP ENABLE SSPIF VAR PIR1.3 'SSP INTERRUPT FLAG '--------------------------------------------------------------------- '-----------------------A/D setups -------------------------------------------- 'Define ADC_BITS 10 ' Set number of bits in result 'Define ADC_CLOCK 2 ' Set clock source (3=rc) 'Define ADC_SAMPLEUS 20 ' Set sampling time in uS 'TRISA = %11111111 ' Set PORTA to all input 'ADCON1 = %10000010 ' Set PORTA analog and right justify result '------------------------------------------------------------------------------- '-------------SPI PORT REGISTERS SETUP---------------------------------------- SSPSTAT=%01000000 ' SAMPLE AT THE MIDDLE OF DATA OUTPUT TIME, TRANSMIT ON IDLE RISING EDGE OF SCK SSPCON=%00100000 ' SPI MASTER MODE, CLOCK=Fosc/4 ENABLE HARDWARE SPI PORT SSPEN=1 ' ENABLE HARDWARE SPI PORT '------------------------------------------------------------------------------- '---VARIABLES FOR THE ADDRESS AND DATA MANAGEMENT------------------------------- 'TX_LEN CON 1 'SENDING DATA LENGTH TX_BUFF var byte'[TX_LEN] 'SENDING DATA ARRAY 'RX_LEN CON 1 'RECEIVING DATA LENGTH RX_BUFF var byte'[RX_LEN] 'RECEIVING DATA ARRAY ADD VAR WORD 'ADDRESS FOR THE MOMEORY(LOW 16BITS) BLOCK0 VAR BYTE 'HIGH EIGHT BITS OF MEMORY ADDRESS BLOCK1 VAR BYTE 'HIGH EIGHT BITS OF MEMORY ADDRESS '------------------------------------------------------------------------------- '-------------INITIALIZATION-------------------------------------------------- FM_CS=1 'FRAM CHIP DISABLED FM_CS_TRIS=0 'OUTPUT SDO=1 'START SPI PIN WITH HIGH SDO_TRIS=0 'OUTPUT SDI_TRIS=1 'INPUT BLOCK0=%00000000; BLOCK1=%00000001; add=0; B0 Var byte b0=100; X1 VAR BYTE X2 VAR BYTE X3 var BYTE X4 var BYTE 'Delay VAR byte ‘ Used to Debounce button 'TRISA = 0 ‘ PORTA is output 'TRISB = 3 ‘ RB0,RB1 are inputs 'CMCON = 7 ‘ PORTA digital I/O 'PAUSE 500 ‘ Wait 0.5sec for LCD to initialize ' ' Clear Hour, Minute, Second and Ticks to zero ' Hour = 0 Minute = 0 Second = 0 Ticks = 0 ' T2CON=%01001100 ' Set the prescaler to 1, and postscale to 10 ON INTERRUPT GOTO ISR ' ISR routine 'PR2=156 ' Set PR2 Register 10ms for timer2 'PR2=249 ' Set PRS2 Register PR2=224' Set PR2 Resiger for 1ms timer2 GIE=1 PEIE=1 TMR2IE=1'Enable the Timer2 interrupt. TMR2ON=1' ' Defines for the SPI-Control Registers '------------------------------------------------------------------------------------- TRUE con 1; FALSE CON 0; CONT_WREN CON %00000110 'F-RAM WRITE ENBALE OP-CODE CONT_RDSR CON %00000101 'F-RAM READ STATUS REIGSTER OP-CODE CONT_WRSR CON %00000001 'F-RAM WRITE STATUS REGISTER OP-CODE CONT_READ CON %00000011 'F-RAM READ MOMEORY OP-CODE CONT_WRITE CON %00000010 'F-RAM WRITE MEMORY OP-CODE '------------------------------------------------------------------------------------- LOOP: '-------Write the OP-CODE and the three Bytes of address----- FM_CS=0 TX_BUff=cont_WREN gosub writespi fm_cs=1 fm_cs=0 tx_buff=cont_write gosub writespi '-----send three bytes of address------------- tx_buff=block0; gosub writespi tx_buff=add.byte1 gosub writespi tx_buff=add.byte0 gosub writespi '----------------------Write the first four bytes the desired data-------------- tx_buff=$02 gosub writespi tx_buff=$03 gosub writespi tx_buff=$04 gosub writespi tx_buff=$05 gosub writespi FM_CS=1 ADD=0 '----------------------Read the four bytes------------------------------------ fm_cs=0; tx_buff=cont_read gosub writespi '------------------Sending three byts of address--------------------------- tx_buff=block0; gosub writespi tx_buff=add.byte1 gosub writespi tx_buff=add.byte0 gosub writespi '-----------------Read data into the variables------------------------------- gosub readspi x1=rx_buff gosub readspi x2=rx_buff gosub readspi x3=rx_buff gosub readspi x4=rx_buff 'hserout [dec4 hour]; 'hserout [dec4 Minute]; 'hserout [dec4 Ticks]; 'hserout [hex ]; 'hserout [dec4 ]; 'hserout [dec4 ]; 'hserout [dec4 ]; IF Disp = 1 THEN LCDOUT $FE, 2 LCDOUT hex X1, ":",hex X2, ":",hex x3,":",dec4 Ticks PAUSE 20 ENDIF Disp = 0 'PAUSE 1000 GOTO LOOP '-----------------Sub routines for the SPI write and read----------------------- WriteSPI: WCOL=0 Rx_buff=SSPBUF ' CLEAR THE BUFFER SSPIF=0 ' CLEAR THE INTERRUP FLAG SSPBUF=tx_buff ' SEND THE BYTE IF(wcol) THEN RETURN WHILE(!SSPIF) WEND SSPIF=0; RETURN ReadSPI: rx_buff=SSPBUF ' Clear the buffer SSPIF=0 ' Clear the interrup flag SSPBUF=0 ' Shift out a dummy byte What is this? while(!sspif) ' wait for receive byte wend rx_buff=SSPBUF ' Get the byte return DISABLE ISR: 'pause 3 'pauseus 400 'TMR2ON=0' TURN OFF TMR2 Ticks = Ticks + 1 'IF Ticks < 4 THEN NoUpdate ' ' 1 second has elapsed, now update seconds and if necessary minutes and hours. ' if Ticks=1000 then ticks=0 Second = Second + 1 ' Update second IF Second = 60 THEN Second = 0 Minute = Minute + 1 ' Update Minute IF Minute = 60 THEN Minute = 0 Hour = Hour + 1 ' Update Hour IF Hour = 24 THEN Hour = 0 ENDIF ENDIF ENDIF endif Disp = 1 ' Set to update display ' ' End of time update ' NoUpdate: TMR2IF=0 ' Re-enable TMR2 interrupts Resume ENABLE ' Re-enable interrupts END END ' End of program




Bookmarks