[SOLVED] SPI bit banging help

Status
Not open for further replies.

pravin b

Member level 5
Joined
May 20, 2012
Messages
85
Helped
2
Reputation
4
Reaction score
1
Trophy points
1,288
Location
Mumbai, India
Visit site
Activity points
2,083
Hello Friends,

I am trying SPI bit banging approach to interface ADC 0832 with AT89C51RD2. I have written following code for same purpose; however I am not able to develop logic for receiving a serial data from ADC 0832 and convert it into readable/usable byte to transmit received byte to PORT 2. Please find the attached code and my hardware simulation in proteus. All type of inputs/help are/is welcome.

Also, when I observe waveforms on oscilloscope at pin dout (P3.2) or MISO, I expect my immediate first bit is to be low (signifies mux settling time as per datasheet) and then 8 bits of data. But in my case I am receiving first bit low (mux settling time), 7 bits of data (I think so) and my 8th bit always remains high (I don’t know why!). Please help me to clear this doubt.

I am here by attaching my code and proteus simulation file & uvision project file for reference.
Thanks & regards,

Pravin B

Code:
#include<reg51.h>
sbit clk=P3^0;
sbit din=P3^1;
sbit dout=P3^2;
sbit cs=P3^3;

#define outport P2

void delay(unsigned int);
void adc_init();
void adc_read();

void main()
{
clk=0;
din=0;
dout=1;
outport=0x00;
while(1)
	{
	adc_init();
	adc_read();
	}
}

void delay(unsigned int count)
{
unsigned int i,j;
for(i=0;i<=count;i++)
	for(j=0;j<=1300;j++);
}

void adc_init()
{
clk=0;
cs=1;
din=0;
delay(1);

clk=0;
cs=0;
din=1;
delay(1);

clk=1;
cs=0;
din=1;
delay(1);

clk=0;
cs=0;
din=1;
delay(1);

clk=1;
cs=0;
din=1;
delay(1);

clk=0;
cs=0;
din=0;
delay(1);

clk=1;
cs=0;
din=0;
delay(1);

clk=0;
cs=0;
din=0;
delay(1);



}

void adc_read()
{
int m, byte_in=0x01;
clk=1;
delay(1);
clk=0;
delay(1);

for(m=0;m<=7;m++)
	{
	clk=1;
	cs=0;
	delay(1);
	clk=0;
	delay(1);
	byte_in=byte_in&dout;
	byte_in=byte_in<<1;
	delay(1);
	}
	outport=byte_in;
	cs=1;

}
 

Attachments

  • hardware.png
    187.8 KB · Views: 88
  • scope_wf.png
    279.4 KB · Views: 90
  • test.zip
    65.4 KB · Views: 67

Hi,

please adjust your scope inputs to "DC" instead of AC.

7 bits low and the LSB high may be a valid 8 bit output. You give 0V into the DAC Ch0. The single LSB high may be because of DAC offset voltage.

Where exactely is your doubt? What did you expect?

Klaus
 
Thank you Klaus!

My doubts are;
1. My first bit on MISO line has to be '0' always? (mux settling time, as mentioned in datasheet).
2.when I apply 0 Volts to ch0 why did I get my LSB "1"; instead of "0"? (which might due to offset voltage as you said, but since I am using proteus simulator I should get '0' ideally; isnt it?)
3.I have written function adc_read() to read the data received on MISO line; but it seems I don't get any value in variable byte_in. thats why my "outport" is always active low i.e. 0x00. Am I going wrong somewhere in code?

Regards,
Pravin
 

Hi,

Looking into the datasheet ADC0832-N Timing shows:


MISO at the first three rising clock edge is TRI-STATE. I recommend to use a pullup on MISO to get a vaild HIGH on TRI STATE.
The next bit is LOW
Then 8 bits MSB first.


But review your ssoftware:

* clock low
* CS low
* wait t-set-up
* loop at least 12 bits: wirting three valid bits folowed by don´t cares, read in the same time 3 bits tristate, 1 bit low, 8 bits data
(to be 8 bit SPI compatible i recommend to loop two times 8 bits simulataneously reading and writing data, then code is reusable and a change to HW SPI is easy)

.. loop:
* set output data
* Wait t-setup
* clock high
* wait thold
* read data input
* clock low

Klaus
 
Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…