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.

SPI interface refused to draw data out from EEPROM?

Status
Not open for further replies.

littletransistor

Newbie level 3
Joined
Nov 28, 2009
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,304
Howdy men and women,

I've developed a simple music box, with timer interrupts outputting square waves (2-channel polyphonic) and another timer for timing the duration of these waves (notes).

I'm drawing data out of the EEPROM I have in that circuit through SPI for the frequency and the duration values to the microcontroller so that it won't eat up the space in the processor instead.

However there is one problem: It refuses to draw data out. I checked the SSPBUF in the debug (I used PICKit 2) and it didn't receive or send anything out at all.

The microcontroller is PIC18F4221 and here is the code. For your information - I temporarily put the SPI routines inside before the main function to see whether it could draw out the contents from the 0th address.

Also, ignore the comments on the timer ticks - they are incorrect after the crystal's being PLL'ed. Crystal is 20MHz.

Code:
#pragma config OSC = HSPLL
#pragma config PWRT = OFF, BOR = OFF
#pragma config WDT = OFF
#pragma config DEBUG = OFF, LVP = OFF, MCLRE = OFF

#include <P18F4221.h>
#include <delays.h>
#include <melody_test2_notes.h>

unsigned char f_count1, f_maxcount1;
unsigned char chan1_num;
unsigned int t_count1, t_maxcount1;

unsigned char f_count2, f_maxcount2;
unsigned char chan2_num;
unsigned int t_count2, t_maxcount2;

unsigned char i, temp;

void T0_ISR(void);
void T1_ISR(void);

void SerTx(unsigned char);
unsigned char SPI(unsigned char);

#pragma interrupt chk_isr
void chk_isr(void)
{
	if (INTCONbits.TMR0IF == 1)
	T0_ISR();
	if (PIR1bits.TMR1IF == 1)
	T1_ISR();
}

#pragma code HiPrioInt = 0x0008
void HiPrioInt(void)
{
	_asm
	GOTO chk_isr
	_endasm
}
#pragma code

void main()
{
	PORTA = 0b00000000;
	TRISA = 0b00000011;

	PORTB = 0x02;
	TRISB = 0x00;

	ADCON1 = 0b00001111;
	
	T0CON = 0x08; // no prescale, 20MHz clock
	T1CON = 0b00000000; // no prescale, TMR1 oscillator off, 20MHz clock

	TMR0H = 0xFF; // 13.4 microsec timer tick
	TMR0L = 0xBD;

	TMR1H = 0xFE; // 81.4 microsec timer tick
	TMR1L = 0xFF;
	
	f_count1 = 0;
	f_count2 = 0;

	t_count1 = 0;
	t_count2 = 0;

	SSPSTAT = 0x00;
	SSPCON1 = 0x22;

	TRISCbits.TRISC5 = 0;
	TRISCbits.TRISC4 = 1;
	TRISCbits.TRISC3 = 0;
	TRISDbits.TRISD0 = 0;
	PORTDbits.RD0 = 1; // turn off CS first

	PORTCbits.RC5 = 0;
	PORTCbits.RC4 = 0;
	PORTCbits.RC3 = 0;
	
	TRISBbits.TRISB0 = 0;
	TRISBbits.TRISB1 = 0;
	
	chan1_num = 0;
	f_maxcount1 = channel1_f[chan1_num]; // starting values
	t_maxcount1 = channel1_d[chan1_num];

	chan2_num = 0;
	f_maxcount2 = channel2_f[chan2_num]; // starting values
	t_maxcount2 = channel2_d[chan2_num];

	PORTDbits.RD0 = 0; // chip enable
	SPI(0x03); // read
	SPI(0x00); // read at address 0x00
	temp = SPI(0x00);
	PORTDbits.RD0 = 1; // chip disable


	INTCONbits.TMR0IF = 0;
	INTCONbits.TMR0IE = 1;
	
	PIR1bits.TMR1IF = 0;
	PIE1bits.TMR1IE = 1;
	
	T0CONbits.TMR0ON = 1;
	T1CONbits.TMR1ON = 1;
	
	INTCONbits.PEIE = 1;
	INTCONbits.GIE = 1;

/*	TXSTA = 0x20;
	SPBRG = 15;
	TRISCbits.TRISC6 = 0;
	PORTCbits.RC6 = 0;

	TXSTAbits.TXEN = 1;
	RCSTAbits.SPEN = 1;*/
	
	while(1);
}

void T0_ISR(void)
{
	f_count1++;
	f_count2++;

	if (f_count1 == 0)
		TRISAbits.TRISA0 = 0;

	if (f_count1 == f_maxcount1)
	{
		TRISAbits.TRISA0 = ~TRISAbits.TRISA0;
	//	PORTAbits.RA0 = ~PORTAbits.RA0;
		f_count1 = 0;
	}

	if (f_count2 == f_maxcount2)
	{	
		TRISAbits.TRISA1 = ~TRISAbits.TRISA1;
	//	PORTAbits.RA1 = ~PORTAbits.RA1;
		f_count2 = 0;
	}

	TMR0H = 0xFF; // reload values into the TMR0H and TMR0L
	TMR0L = 0xBD;	

	INTCONbits.TMR0IF = 0;
}

void T1_ISR(void)
{
	t_count1++;
	t_count2++;
	
	if (t_count1 == 25)
		PORTBbits.RB0 = 1;

	if (t_count1 == 1250)
		PORTBbits.RB0 = 0;

	if (t_count1 == t_maxcount1)
	{
		chan1_num++;
		TRISBbits.TRISB0 = 0;

		if(chan1_num == 133)
			chan1_num = 0;
		
		f_maxcount1 = channel1_f[chan1_num];
		t_maxcount1 = channel1_d[chan1_num];

		t_count1 = 0;
	}

	if (t_count2 == 25) 
		PORTBbits.RB1 = 1;

	if (t_count2 == 1250)
		PORTBbits.RB1 = 0;

	if (t_count2 == t_maxcount2)
	{
		chan2_num++;
		TRISBbits.TRISB1 = 0;
		
		if(chan2_num == 102)// test: 14
			chan2_num = 0;
		t_count2 = 0;

		f_maxcount2 = channel2_f[chan2_num]; // next frequency
		t_maxcount2 = channel2_d[chan2_num]; // next duration
	}
	TMR1H = 0xFE;
	TMR1L = 0xFF; // default: FE69

	PIR1bits.TMR1IF = 0;
}

unsigned char SPI(unsigned char data)
{
	SSPBUF = data;
	while(!SSPSTATbits.BF);
	return SSPBUF;
}

void SerTx(unsigned char c)
{
	while(PIR1bits.TXIF == 0);
	TXREG = c;
}
 

check microchip site, i have found a topic regarding your problem given below,

Interfacing SPI? Serial EEPROMs to PIC16 Devices (application note with source code)

**broken link removed**
 

hanif said:
check microchip site, i have found a topic regarding your problem given below,

Interfacing SPI? Serial EEPROMs to PIC16 Devices (application note with source code)

**broken link removed**

That microcontroller has a hardware based SPI and I don't need the software one that much.

I have implemented it and however it still didn't work. Must I use interrupts?
 

If you have problems with SPI interface, post an example that shows the problem, not all the timer tick stuff.
 

Sorry for the inconvenience. I accidently left out that part there.

Here's the code, with the SPI function.

#pragma config OSC = HSPLL
#pragma config PWRT = OFF, BOR = OFF
#pragma config WDT = OFF
#pragma config DEBUG = OFF, LVP = OFF, MCLRE = OFF

#include <P18F4221.h>
#include <delays.h>
#include <melody_test2_notes.h>

unsigned char f_count1, f_maxcount1;
unsigned char chan1_num;
unsigned int t_count1, t_maxcount1;

unsigned char f_count2, f_maxcount2;
unsigned char chan2_num;
unsigned int t_count2, t_maxcount2;

unsigned char i, temp, d;

void T0_ISR(void);
void T1_ISR(void);

void SerTx(unsigned char);
unsigned char SPI(unsigned char);

#pragma interrupt chk_isr
void chk_isr(void)
{
if (INTCONbits.TMR0IF == 1)
T0_ISR();
if (PIR1bits.TMR1IF == 1)
T1_ISR();
}

#pragma code HiPrioInt = 0x0008
void HiPrioInt(void)
{
_asm
GOTO chk_isr
_endasm
}
#pragma code

void main()
{
PORTA = 0b00000000;
TRISA = 0b00000011;

PORTB = 0x02;
TRISB = 0x00;

ADCON1 = 0b00001111;

T0CON = 0x08; // no prescale, 20MHz clock
T1CON = 0b00000000; // no prescale, TMR1 oscillator off, 20MHz clock

TMR0H = 0xFF; // 13.4 microsec timer tick
TMR0L = 0xBD;

TMR1H = 0xFE; // 81.4 microsec timer tick
TMR1L = 0xFF;

f_count1 = 0;
f_count2 = 0;

t_count1 = 0;
t_count2 = 0;

SSPSTAT = 0x00;
SSPCON1 = 0b00110001;


TRISCbits.TRISC5 = 0;
TRISCbits.TRISC4 = 1;
TRISCbits.TRISC3 = 0;
TRISDbits.TRISD0 = 0;
PORTDbits.RD0 = 1; // turn off CS first

PORTCbits.RC5 = 0;
PORTCbits.RC4 = 0;
PORTCbits.RC3 = 0;

TRISBbits.TRISB0 = 0;
TRISBbits.TRISB1 = 0;

chan1_num = 0;
t_maxcount1 = channel1_d[chan1_num];

chan2_num = 0;
f_maxcount2 = channel2_f[chan2_num]; // starting values
t_maxcount2 = channel2_d[chan2_num];


INTCONbits.TMR0IF = 0;
INTCONbits.TMR0IE = 1;

PIR1bits.TMR1IF = 0;
PIE1bits.TMR1IE = 1;

T0CONbits.TMR0ON = 1;
T1CONbits.TMR1ON = 1;

INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;

/* TXSTA = 0x20;
SPBRG = 15;
TRISCbits.TRISC6 = 0;
PORTCbits.RC6 = 0;

TXSTAbits.TXEN = 1;
RCSTAbits.SPEN = 1;*/

while(1)
{
PORTDbits.RD0 = 0; // chip enable
SPI(0x03); // read
SPI(chan1_num); // read at low address 0x00
f_maxcount1 = SPI(chan1_num);
PORTDbits.RD0 = 1; // chip disable

}
}

void T0_ISR(void)
{
f_count1++;
f_count2++;

if (f_count1 == 0)
TRISAbits.TRISA0 = 0;

if (f_count1 == f_maxcount1)
{
TRISAbits.TRISA0 = ~TRISAbits.TRISA0;
// PORTAbits.RA0 = ~PORTAbits.RA0;
f_count1 = 0;
}

if (f_count2 == f_maxcount2)
{
TRISAbits.TRISA1 = ~TRISAbits.TRISA1;
// PORTAbits.RA1 = ~PORTAbits.RA1;
f_count2 = 0;
}

TMR0H = 0xFF; // reload values into the TMR0H and TMR0L
TMR0L = 0xBD;

INTCONbits.TMR0IF = 0;
}

void T1_ISR(void)
{
t_count1++;
t_count2++;

if (t_count1 == 25)
PORTBbits.RB0 = 1;

if (t_count1 == 1250)
PORTBbits.RB0 = 0;

if (t_count1 == t_maxcount1)
{
chan1_num++;
TRISBbits.TRISB0 = 0;

if(chan1_num == 133)
chan1_num = 0;

t_maxcount1 = channel1_d[chan1_num];

t_count1 = 0;
}

if (t_count2 == 25)
PORTBbits.RB1 = 1;

if (t_count2 == 1250)
PORTBbits.RB1 = 0;

if (t_count2 == t_maxcount2)
{
chan2_num++;
TRISBbits.TRISB1 = 0;

if(chan2_num == 102)// test: 14
chan2_num = 0;
t_count2 = 0;

f_maxcount2 = channel2_f[chan2_num]; // next frequency
t_maxcount2 = channel2_d[chan2_num]; // next duration
}
TMR1H = 0xFE;
TMR1L = 0xFF; // default: FE69

PIR1bits.TMR1IF = 0;
}

unsigned char SPI(unsigned char d)
{
SSPBUF = d;
while(!SSPSTATbits.BF);
return SSPBUF;
}


void SerTx(unsigned char c)
{
while(PIR1bits.TXIF == 0);
TXREG = c;
}

As a test, I draw out the frequency data for the first channel only of the system into the f_maxcount1 and this is done for the next frequency data and so forth.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top