littletransistor
Newbie level 3
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.
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;
}