helloleong
New Member
Im using the PIC16F727 to communicate with the EEPROM X25650 by SPI
But when i use debugger to debug the code, it cannot get out of the SPI_OUTPUT function while loop,
since the BF (buffer full bits) does not set (the data cannot completely transfer to the buffer?)
here's the code im doin:
Thank you.
But when i use debugger to debug the code, it cannot get out of the SPI_OUTPUT function while loop,
since the BF (buffer full bits) does not set (the data cannot completely transfer to the buffer?)
here's the code im doin:
Code:
#include <stdio.h>
#include <pic.h>
#include <htc.h>
//Detail in MPLAB Configue > Configuration Bits window
__CONFIG(INTIO & WDTDIS & PWRTDIS & MCLREN & BORDIS & UNPROTECT & PLLEN);
__CONFIG(VCAPRA0);
//GLOBAL VARIABLE
unsigned char CStest;
unsigned char SDOtest;
unsigned char SDItest;
unsigned char SCKtest;
unsigned char BFtest;
#define Buzzer RA7
/******* EEPROM ReadWrite.c ***********/
unsigned char Result, dummy; //Data;
unsigned char H_addr=0, L_addr=0, data;
unsigned char miss;
unsigned char Pin_No=0;
unsigned char spi_received=0;
unsigned char Increase=0;
unsigned char ERROR=0;
unsigned char PageSize=32;
unsigned char NHigh=0;
unsigned char NLow=0;
unsigned char Temp;
unsigned char ClearM_Counter=0;
unsigned char W;
//GLOBAL FUNCTIONS
void Init(void);
//EEPROM Funstion
void WREN();
char SPI_OUTPUT (char spi_byte);
void write_data(char L_addr, char H_addr, char data);
char read_data(char L_addr, char H_addr);
void Start_read(char L_addr, char H_addr);
char RDSR();
void WRSR();
//EEPROM defination
#define CS RC7 //active low (Chip Selection)
#define SDI RC5 //serial data input //wrong swap: original #define SDI RC4
#define SDO RC4 //serial data output //wrong swap: original #define SDO RC5
#define SCK RC3 //synchronous clock //**change: original #define SCK RC3
/*******Control2_Main.c*******/
#define BLUE RA1 //TRI-LED BLUE
#define GREEN RA2 //TRI-LED GREEN
#define RED RA3 //TRI-LED RED
/******************************************************************************/
/* Main Routine
/******************************************************************************/
void main(void)
{
Init();
//Test byte to watch on
CStest=RC7;
SDOtest=RC5;
SDItest=RC4;
SCKtest=RC3;
BFtest=BF;
// W = 0x00;
// bank0 SSPBUF = W;
// while(!BF); //Even i put out the code. Still stuck at here. Cannot get out of the loop
// dummy = SSPBUF;
WREN ();
write_data(0x00, 0x00, 0xAB);
Temp = read_data(0x00, 0x00);
if(Temp==0xAB) {
BLUE=1;
GREEN = 0;
RED = 1;
}
else{
BLUE=1;
GREEN = 1;
RED = 0;
}
}
//----------------------------------Initialization-------------------------------//
void Init(void)
{
OSCCON = 0b00100000; // Internal 8Mhz @PLL
//*Port Description*//
//------------------------------------------------------------------------
// 7 6 5 4 3 2 1 0 |
// -- -- -- -- -- -- -- -- |
//PortA Buzzer DS CPS7(1) CPS6(4) LRED LGREEN LBLUE Cap4(1uF)|
//PortB PGD PGC CPS5(7) CPS4(*) CPS3(2) CPS2(5) CPS(8) CPS(0) |
//PortC CE - MOSI MISO SCLCK ALRM LOCK - |
//PortD LS0H L789 L456 L321 CPS11(3)CPS10(6)CPS9(0) CPS8(#) |
//PortE MCLR D0 D1 - |
//------------------------------------------------------------------------
TRISA = 0b01110000; //Setting for input=1 or output=0
ANSELA = 0b01110000; //Setting for analogue=1 or digital=0
TRISB = 0b00111111;
ANSELB = 0b00001111;
TRISC = 0b00010001;
TRISD = 0b00111111;
ANSELD = 0b00111111;
TRISE = 0b1000;
ANSELE = 0b0000;
POR = 1; //No Power-on Reset occured
//Read - SSP control register (Default) bit 0 to 3 need to be set at 0000 for highest SPI speed
SSPCON = 0b00110000;
// bit3-0 |||||____ SSPM<3:0>: Synchronous Serial Port Mode Select bits. 0000 = SPI Master mode, clock = FOSC/4
// bit4 * ||||_____ CKP: Clock Polarity Select bit, 1 = Idle state for clock is a high level. 0 = Idle state for clock is a low level
// bit5 |||______ SSPEN: Synchronous Serial Port Enable bit. 1 = Enables serial port and configures SCK, SDO and SDI as serial port pins(1)
// bit6 ||_______ SSPOV: Receive Overflow Indicator bit. 0 = No overflow
// bit7 |________ WCOL: Write Collision Detect bit. 0 = No collision
//SSPSTAT: SYNC SERIAL PORT STATUS REGISTER (SPI Mode)
SSPSTAT= 0b01000000; //SSP status register (Synchronous Serial Port)
// bit7 ||||||||_ BF: Buffer Full Status bit. 0 = Receive not complete, SSPBUF is empty.
// bit6 |||||||__ No use. Used in I2C mode only.
// bit5 ||||||___ "
// bit4 |||||____ "
// bit3 ||||_____ "
// bit2 |||______ "
// bit1 * ||_______ CKE: SPI Clock Edge Select bit. 1 = Data stable on falling edge of SCK
// bit0 * |________ SMP: SPI Data Input Sample Phase bit. SPI Master mode: 0 = Input data sampled at middle of data output time.
//SSPEN = 1 //Turn on SSP module
SSPIF = 0; // Synchronous Serial Port Interrupt Flag bit
SSPIE = 1; // Synchronous Serial Interrupt Enable bit
PEIE = 1; // Peripheral Interrupt Enable bit
//Interupt Enable
GIE = 1;
BLUE=1;
RED=1;
GREEN=1;
}
/************************************************************************************/
/* WREN(void): Write Enable (Instruct EEPROM by giving input of 0x06)
/************************************************************************************/
void WREN ()
{
CS=0; //Chip Select
dummy = SPI_OUTPUT(0x06); //Set write enable latch
CS=1; //Chip Deselect
}
/************************************************************************************/
/* RDSR(void):Read Status Register (Instruct EEPROM by giving input of 0x05)
/************************************************************************************/
char RDSR ()
{
CS=0;
dummy = SPI_OUTPUT(0x05);
CS=1;
return dummy;
}
/***********************************************************************************/
/* WRSR(void):Write Status Register (Instruct EEPROM by giving input of 0x01)
/***********************************************************************************/
void WRSR()
{
CS=0;
dummy = SPI_OUTPUT(0x01);
dummy = SPI_OUTPUT(0x00); //**Maybe no use
CS=1;
}
/***********************************************************************************/
/* write_data(char *H_addr, char *L_addr, char *data)
/* Write instruction 0x02 to the EEPROM first.
/* Write data of 'data' to 'H_addr & L_addr)
/***********************************************************************************/
void write_data(char H_addr, char L_addr, char data)
{
CS=0;
dummy = SPI_OUTPUT(0x02);
H_addr |= 0x8;
dummy = SPI_OUTPUT (H_addr);
dummy = SPI_OUTPUT (L_addr);
dummy = SPI_OUTPUT (data);
CS=1;
}
/**********************************************************************************/
/* SPI_OUTPUT(char spi_byte)
/* Output to SSPBUF and wait till all transfered into SSPSR
/* Check if BF Full. (BF full = complete_)
/**********************************************************************************/
char SPI_OUTPUT (char spi_byte)
{
if(WCOL) WCOL = 0;
if(SSPOV) SSPOV = 0;
SSPBUF = spi_byte;
//do{}
while(!BF); //Get stuck here
return SSPBUF;
}
/*********************************************************************************/
/* read_data(char *H_addr, char *L_addr)
/* Write instruction 0x03 to the EEPROM first.
/* Read from to H_addr & L_addr. Additional 0x00 is to push 'data' out
/*********************************************************************************/
char read_data(char H_addr, char L_addr) //use low and high add
{
CS=0;
dummy = SPI_OUTPUT(0x03);
dummy = SPI_OUTPUT(H_addr);
dummy = SPI_OUTPUT(L_addr);
CKP=0;
spi_received = SPI_OUTPUT(0x00);
CS=1;
return spi_received;
}
Thank you.