Tag Archives: adc

SPI Protocol,Interfacing MCP3202 with 8051 (NXP Philips P89V51RD2)

27 Mar

The clock polarity and clock phase is used for the shift registers used at master and slave end to shift the data in or out more reliably.

Make an effort to go through the data sheet and also the link provided if your dealing with shift registers which is normally present when dealing with a spi interface.

http://www.allaboutcircuits.com/vol_4/chpt_12/2.html

While going through spi protocol,you’ll come across 4 modes,now the question is which mode to select for the project.Well,it depends on the slave device.In the data sheet,the modes to use will be mentioned mostly in the 1st page of the data sheet itself.

Next is the frequency selection,you have to look into the electrical characteristics of the slave device to know what is the fosc (frequency) which is important for data transfer using spi protocol.

For MCP3202,it’s mentioned 100ksps or 5oksps. ksps means kilo samples per sec that adc takes to process.

fsample =100ksps, therefore,fclk=18*fsample

fclk=18*100K=1.8MHz. This the max frequency allowed for 100ksps.

Connections

mcp3202s

Now moving to the spi registers in p89v51rd2 (8051)

3 registers:control register,configuration register,data register.

control register: enable spi,msb or lsb first,master mode, mode of the spi,and spi clock rate.

Since for mcp3202,the max freq is 1.8MHz. I’ve gone with dived by 16 option

My controller is working on a 11.0592MHz crystal oscillator.

11.0592MHz/16=0.692 Mhz which is less than 1.8MHz.

Configuration register:when the data is transferred successfully,the 8th bit is set & that is what we need to check for in the program.

data register:data to be sent & received is data register.

Back to MCP3202

What are the control bits to be sent to the adc?

start bit

single ended or pseudo differential

channel select

msbf

Before you send any data to the slave,make the chip select pin low.

I’ve used single ended,channel 0,MSBF=1

MCP3202D1

Now,when dealing with a 8 bit microcontroller in mode 0,0 go through the below diagram

mcp3202d2

1st data sent to slave: 0x01

Mcu receives: garbage value,discard it

2nd data sent to the slave: 0xa0

Mcu receives: highest nibble of the conversion (4bits)

3rd data sent to the slave: 0xff (any random value)

Mcu receives: next 8 bits

Therefore a total of 12 bits

Club the data together and send it to lcd or uart.

CODE:

#include<p89v51rd2.h>
#include<stdio.h>
sbit cs=P1^4;
sbit MOSI=P1^5; //din
sbit MISO=P1^6; //dout
sbit SCK=P1^7;

sfr info=0x80;
sbit rs=P2^0;
sbit rw=P2^1;
sbit en=P2^2;
void lcd_init();
void delay(unsigned int);
void lcdcmd(unsigned char);
void lcddata(unsigned char);
void str(char []);
void spi();
void convert(unsigned int,unsigned int);
int main()
{
unsigned char c,msb,lsb;
lcd_init();
lcddata(‘r’);
spi();

cs=1;
delay(1);
cs=0;
delay(2);

SPDAT=0x01; // start bit
while(SPCFG!=0x80);
SPCFG=0;
lcddata(‘s’);
c=SPDAT;

SPDAT=0xa0; // SGL/DIFF/MSBF

while(SPCFG!=0x80);
SPCFG=0;
lcddata(‘m’);
c=SPDAT;
if(c&0x10)
{
lcddata(‘n’);
}
msb=c&0x0f;

SPDAT=0xff;

while(SPCFG!=0x80);
SPCFG=0;
lcddata(‘e’);
lsb=SPDAT;

convert(msb,lsb);

cs=1;
while(1);

}
void spi()
{
SPCTL=0x51; // control register
}
void convert(unsigned int c1,unsigned int c2)
{
unsigned int i,c3,c4,a[4],b[4]={256,512,1024,2048};
float c5;
unsigned char x[20];
for(i=0;i<4;i++)
{
c3=c1>>i;
c3=c3&0x01;
a[i]=c3*b[i];
}
c4=a[0]+a[1]+a[2]+a[3];
c2=c2+c4;
// c5=(float)((c2*5000)/4096); // VALUE GOIN OUT OF RANGE
c5=100*c2;
c5=(float)(c5/4096);
c5=(float)(c5*50);
c5=(float)(c5/10);
sprintf(x,”%f”,c5);
str(x);

}
void lcd_init()
{
lcdcmd(0x80);
delay(250);
lcdcmd(0x38);
delay(250);
lcdcmd(0x0f);
delay(250);
lcdcmd(0x01);
delay(250);
lcdcmd(0x06);
delay(250);

}
void lcdcmd(unsigned char val)
{
info=val;
rs=0;
rw=0;
en=1;
delay(1);
en=0;
}
void lcddata(unsigned char value)
{
info=value;
rs=1;
rw=0;
en=1;
delay(1);
en=0;
}
void delay(unsigned int i)
{
unsigned int j,k;
for(j=0;j<i;j++)
for(k=0;k<1275;k++);
}
void str(unsigned char a[])
{
unsigned int i=0;
while(a[i]!=”)
{
lcddata(a[i]);
i++;
}
}

The sensor I’ve used is LM35 (Temperature sensor)