Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

SCLK and CS timing in program for ADS7816P interfacig PIC16f877A

Status
Not open for further replies.

john86

New Member
Hi guys :)

This is my program for interfacing ADS7816P (a 12bit ADC) with PIC16f877 with MikroC compiler.
please help me for configuring the "Clock pulse and CS pins Timing" in program. :eek:

Is there any other faults in my program? :confused:
please tell me

Regards





/*------------------------------------------------------------------------------
These Macros define I/O Pins of PIC16f877A, connected to the ADS7816P.
------------------------------------------------------------------------------*/

#define CS RC0_bit //As an output.
#define DOUT RC1_bit //As an input.
#define DCLK RC3_bit //As an output.

/*------------------------------------------------------------------------------
This Function reads the "12 bit ADC Digitaized output data" and returns it
in a local variable, named "Sample".
------------------------------------------------------------------------------*/

long int readadc() {
unsigned char i=1,j=1;
long int sample=0;

DCLK=1;
CS=0;


for(j=1;j<=2;j++) //skip two null bits (According to ADS7816P datasheet).
DCLK=0;
delay_us(5);
DCLK=1;

for(i=1;i<=12;i++){
DCLK=0;

sample=sample<<1;

if(DOUT==1) sample=sample | 0b0000000000000001;
else sample=sample & 0b1111111111111110;

delay_us(1);
DCLK=1;

}

CS=1;
return sample;
}

/*------------------------------------------------------------------------------
The mask Function defines the 0-9 digits for common-anode seven-segments
via "switch" statement.
------------------------------------------------------------------------------*/

unsigned short mask(unsigned short num) {

switch (num) {

case 0:
return 0xC0;

case 1:
return 0xF9;

case 2:
return 0xA4;

case 3:
return 0xB0;

case 4:
return 0x99;

case 5:
return 0x92;

case 6:
return 0x82;

case 7:
return 0xF8;

case 8:
return 0x80;

case 9:
return 0x90;

} //case ended.
}

/*------------------------------------------------------------------------------
This is the "Main Program." (Contains the Program for multiplexing a
4 common-anode seven segments display whereas, common pins of seven segments
are connected to RB0, RB1, RB2 and RB3, and the seven segments are
driven through Port_D pins.
------------------------------------------------------------------------------*/

void main() {
unsigned short DD0, DD1, DD2, DD3;
long int val = 0;

TRISC=0x02; //Changes directions of PORTC pins; RC1 as an input,and the others are outputs.

//!----------------------(for 7-seg. display Multiplexing)--------------------
TRISB = 0xC0; //configuring Port_B 0-5 pins to be outputs and Port_B 6&7 pins to be inputs (PGC and PGD).
TRISD = 0x00; //Configuring Port_D directions to be output.
//!---------------------------------------------------------------------------

PORTD = 0xff; //Turn Off all 4, seven-segments.

CMCON=7; // Turn off comparators.
SSPSTAT.SMP=0;
SSPSTAT.CKE=0;
SSPCON=0; //Resets the SSPCON register.
SSPCON2=0;


do {

val=readadc(); //Reads the returned content of "readadc()" function (named sample).

DD0 = val%10; //Extracts Ones Digit of variable "val".
DD0 = mask(DD0);
DD1 = (val/10)%10; //Extracts Tens Digit of variable "val".
DD1 = mask(DD1);
DD2 = (val/100)%10; //Extracts Hundreds Digit of variable "val".
DD2 = mask(DD2);
DD3 = (val/1000); //Extracts Thousands Digit of variable "val".
DD3 = mask(DD3);


PORTD=DD0;
RB0_bit = 0; //Selecting Ones Digit
RB1_bit = 1;
RB2_bit = 1;
RB3_bit = 1;
delay_us(5);

PORTD=DD1;
RB0_bit = 1; //Selecting Tens Digit
RB1_bit = 0;
RB2_bit = 1;
RB3_bit = 1;
delay_us(5);


PORTD=DD2;
RB0_bit = 1; //Selecting Hundereds Digit
RB1_bit = 1;
RB2_bit = 0;
RB3_bit = 1;
delay_ms(5);


PORTD=DD3;
RB0_bit = 1; //Selecting Thousands Digit
RB1_bit = 1;
RB2_bit = 1;
RB3_bit = 0;
delay_us(5);


} while(1);
}
 
Although I don't usually write in C, I think that I have seen some errors in your reading of the ADC.

(In this forum, code should normally be in #code tags, but the colours don't work if I do that)

long int readadc() {
unsigned char i=1,j=1;
long int sample=0;

DCLK=1;
delay_us(5); // There may need to be a delay to give a minimum gap
CS=0;
delay_us(5); // There may need to be a delay to give a minimum gap

for(j=1;j<=2;j++) //skip two null bits (According to ADS7816P datasheet).
{
DCLK=0;
delay_us(5);
DCLK=1;
delay_us(5); // There may need to be a delay to give a minimum time high
} // You hadn't made it a loop


for(i=1;i<=12;i++){
DCLK=0;

sample=sample<<1;

if(DOUT==1)
{sample=sample | 0b0000000000000001;}// I'm not sure if these are needed, but the complier has to know what is the end of the "if" statement
// else sample=sample & 0b1111111111111110; You don't need that line. The shift will force the lsb to zero

delay_us(1);
DCLK=1;
delay_us(1); // as with the other loop you may need a minimum time high
}

CS=1;
return sample;
}


If that doesn't work, fault find with an oscilloscope or a logic analyser. The logic analyser function on the PICkit2 would do.

If you don't have an oscilloscope, put LEDs and series resistors on the CS, clock and data lines. You need a resistor that is 15kΩ or more, and the LEDs won't be very bright, because the ADS7816 can't drive much current. Then increase the delays to several seconds each, and you can watch the whole lot on a human time scale. There is no maximum clock time on the ADS7816
 
Last edited:
hey buddy

I didn't test my program with your reforms on it, yet... but I certainly will. thank you.
But there is an another question. Should I calculate the exact timing delays in the program? I mean, is it important for ADS7816 or PIC, that how much delay I will spot?

I think if we don't spot a significant and exact timing for CS and CLK according to timing graphs in the ADS7816's datasheet, then it may cause problems! I don't know what problems! I just guess! :rolleyes:

And I'm wondering, how much time it takes to execute the below part of program for once? and how much it should take?



Code:
do {

val=readadc(); //Reads the returned content of "readadc()" function (named sample).

DD0 = val%10; //Extracts Ones Digit of variable "val".
DD0 = mask(DD0);
DD1 = (val/10)%10; //Extracts Tens Digit of variable "val".
DD1 = mask(DD1);
DD2 = (val/100)%10; //Extracts Hundreds Digit of variable "val".
DD2 = mask(DD2);
DD3 = (val/1000); //Extracts Thousands Digit of variable "val".
DD3 = mask(DD3);


PORTD=DD0;
RB0_bit = 0; //Selecting Ones Digit
RB1_bit = 1;
RB2_bit = 1;
RB3_bit = 1;
delay_us(5);

PORTD=DD1;
RB0_bit = 1; //Selecting Tens Digit
RB1_bit = 0;
RB2_bit = 1;
RB3_bit = 1;
delay_us(5);


PORTD=DD2;
RB0_bit = 1; //Selecting Hundereds Digit
RB1_bit = 1;
RB2_bit = 0;
RB3_bit = 1;
delay_ms(5);


PORTD=DD3;
RB0_bit = 1; //Selecting Thousands Digit
RB1_bit = 1;
RB2_bit = 1;
RB3_bit = 0;
delay_us(5);


} while(1);


I think this part should execute in a very very short time. Maybe if it takes much time to execute, it will cause the ADS7816 go for a "turn off" or "silence" or something like this?!
Am I right? please tell me what do you think? :rolleyes:
Maybe I'm a stickler person about this! :D
 
Last edited:
I have no idea how long the code takes to execute. You would have to look at the compiled assembler, and count the lines. However it doesn't make any difference, so don't bother.

What I am fairly sure about is that the ADS7816 can run as slowly as you want. There are minimum times that the clock pulses, high and low, should last, but no maximum times. I would not have suggested slowing the clock down to several seconds if I thought that there were maximum times.

The ADS7816 will take slightly more current when enabled than when not, so you can minimise power consumption by clocking as fast as possible so that the ADS7816 can be disabled sooner. However, it takes less than 1 mA when enabled so unless you are wanting to run from batteries for ages, it really makes no difference at all.
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top