///////////////////////////////////////////////////////////////////////
// [U]my first digital voice recorder using PIC16F877A and MMC[/U]//
// push button at RE0 to select play or record mode //
// http://www.youtube.com/watch?v=Mn1VsM-i8QI //
///////////////////////////////////////////////////////////////////////
#include<pic.h>
#define _XTAL_FREQ 20e6
#define CS RC2
#define RS RB2
#define EN RB1
#define fst cmd(0x80)
#define snd cmd(0xc0)
unsigned int i;
unsigned char j,k,rec,dat,tempbuf,readdata,u;
unsigned int count;unsigned long int wcount;
unsigned long int mul=1,arg=0;
const char *q="VINOD ";
/*-----------------LCD BEGIN----------------------------*/
void LCD_STROBE(void)
{
EN = 1;
__delay_us(0.5);
EN = 0;
}
void data(unsigned char c)
{
RS=1;
__delay_us(40); PORTD = ( c >> 4 );LCD_STROBE();
PORTD = ( c );LCD_STROBE();
}
void cmd(unsigned char c)
{
RS=0;
__delay_us(40); PORTD = ( c >> 4 );LCD_STROBE();
PORTD = ( c );LCD_STROBE();
}
void clear(void)
{
cmd(0x01);
__delay_ms(2);
}
void lcd_init()
{
__delay_ms(20);
cmd(0x30 );
__delay_ms(1);
cmd(0x30 );
__delay_ms(1);
cmd(0x30 );
cmd(0x28 ); // Function set (4-bit interface, 2 lines, 5*7Pixels)
cmd(0x28 ); // Function set (4-bit interface, 2 lines, 5*7Pixels)
cmd(0x28 ); // Function set (4-bit interface, 2 lines, 5*7Pixels)
cmd(0x0c); // Make cursorinvisible
clear();
clear(); // Clear screen
cmd(0x6); // Set entry Mode
}
void string(const char *q)
{
clear();
while(*q) {data(*q++);}
}
void istring(unsigned int q)
{
cmd(0x81);
data(48+(q/100));q%=100;
data(48+(q/10));q%=10;
data(48+(q));
__delay_ms(500);
}
/*-----------------------LCD END--------------------*/
/*-----------------------USRT BEGIN--------------------*/
void usrt_init()
{
TRISC6=0;
TXSTA=0b00100110;
RCSTA=0b11010000;
SPBRG=10;
}
void printf(const char *p)
{
while(*p)
{
TXREG=*p;
while(TRMT==0);
p++;
}
}
void txd(unsigned char vv)
{
TXREG=vv;
while(TRMT==0);
}
/*-----------------------USRT END-------------------*/
/*----------------------PWM BEGINS--------------------*/
void pwm_init()
{
TRISC1=0;
T2CKPS1=0;T2CKPS0=0;
PR2=0x50;
CCPR2L=0x17;
TMR2ON=1;
CCP2CON=0b00001100;
}
void pwm_disable(){CCP2CON=0b00000000;}
void pwm_enable(){CCP2CON=0b00001100;}
/*--------------------PWM END------------------------*/
/*-------------------mmc BEGIN-----------------------*/
void spi_init()
{
TRISC4=1;
RC2=1;RC3=0;RC5=0;
TRISC2=TRISC3=TRISC5=0;
SSPCON=0b00100010;
SSPEN=1;
SMP=1;
CKE=1;
CKP=0;
}
void spi_write(unsigned char kk)
{
SSPBUF=kk;
while(BF==0);
}
void spi_read()
{
SSPBUF=0xff;
while(BF==0);
readdata=SSPBUF;
}
void command(char command, unsigned long int fourbyte_arg, char CRCbits )
{
spi_write(0xff);
spi_write(0b01000000|command);
spi_write((unsigned char)(fourbyte_arg >> 24));
spi_write((unsigned char)fourbyte_arg >> 16);
spi_write((unsigned char)(fourbyte_arg >> 8));
spi_write((unsigned char)fourbyte_arg);
spi_write(CRCbits);
spi_read();
}
void mmc_init()
{
CS=1;
for(u=0;u<50;u++){spi_write(0xff);}
CS=0;
__delay_ms(1);
command(0,0,0x95);
count=0;
while((readdata!=1)&&(count<1000)){spi_read();count++;}
if(count>=1000){string("CARD ERROR-CMD0 ");while(1);}
command(1,0,0xff);
count=0;
while((readdata!=0)&&(count<1000)){command(1,0,0xff);spi_read();count++;}
if(count>=1000){string("CARD ERROR-CMD1 ");while(1);}
command(16,512,0xff);
count=0;
while((readdata!=0)&&(count<1000)){spi_read();count++;}
if(count>=1000){string("CARD ERROR-CMD16");while(1);}
string("MMC INITIALIZED!");__delay_ms(1000);
SSPCON=SSPCON&0b11111101;
}
void write()
{
pwm_disable();
/*write*/
command(25,arg,0xff);
while(readdata!=0){spi_read();string("WRITE ERROR");}
string("WRITING MMC");
h: spi_write(0xff);
spi_write(0xff);
spi_write(0b11111100);
for(int g=0;g<512;g++)
{
ADGO=1;
while(ADGO);
spi_write(ADRESL); PORTD=~ADRESL;
}
spi_write(0xff);
spi_write(0xff);
spi_read();
while((readdata&0b00011111)!=0x05){spi_read();}
while(readdata!=0xff){spi_read();}
if(RE0==1)
{
spi_write(0xff);
spi_write(0xff);
spi_write(0b11111101); //stop token
spi_read();spi_read();
while(readdata!=0xff){spi_read();}
goto exit1;
}
goto h;
exit1:;
}
void read()
{
pwm_enable();
command(18,(arg),0xff);
while(readdata!=0){spi_read(); string("READ ERROR");}
string("READING MMC");
g: while(readdata!=0xfe){spi_read();}
for(int g=0;g<512;g++)
{
spi_read(); __delay_us(16.5);
CCPR2L=readdata;
PORTD=~readdata;
}
spi_write(0xff);
spi_write(0xff);
if(RE0==1)
{
command(12,arg,0xff);
spi_read();
while(readdata!=0){spi_read();}
while(readdata!=0xff){spi_read();}
goto exit2;
}
goto g;
exit2:pwm_disable();
}
/*--------------------mmc end----------------------*/
/*-----------------ADC functions-------------------*/
void adc_init()
{
TRISA0=1;
ADCON0=0b10000001;
ADCON1=0b10001110;
}
main()
{
CS=1;PORTD=0;
TRISC4=0;TRISC5=0;TRISD=0;TRISB2=0;TRISB1=0;
TRISE0=1;
lcd_init();
adc_init();
usrt_init();
spi_init();
mmc_init();
pwm_init();
lcd_init();
count=0;
CS=0;
mul=1;arg=0;
while(1)
{
arg=0;
fst;
string("READ MODE");
__delay_ms(1000);
read();
arg=0;
fst;
string("WRITE MODE");
__delay_ms(1000);
write();
}
}