Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

How to read MCP3302 using SPI ?

Status
Not open for further replies.

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
How to read MCP3302 using SPI ?

I have to use CH0 of MCP3302 (single ended mode) Please algorithm or C code to read the adc value. It uses SPI. I am using PIC18F46K22. I will use Software SPI.

- - - Updated - - -

I have written this code but it is not working as expected.

Datasheet page no. 24 I have read.

I need MCP3302 single ended, CH0, 12 bit ADC value.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
double MCP3302_Read() {
 
       char i = 0;
       unsigned int adcVal = 0, mask = 0x800;
       
       
       CS = 1;
       Delay_us(50);
       CS = 0;
       Delay_us(50);
       
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
       
       DOUT = 1;
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
       
       DOUT = 0;
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
       
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
       
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
       
       CLK = 1;
       Delay_us(50);
       CLK = 0;
       Delay_us(50);
                    
       for(i = 0; i < 12; i++) {
       
             adcVal >>= 1;
             if(DIN) {
                 adcVal = adcVal | mask;
             }            
                          
             CLK = 1;
             Delay_ms(2);
             CLK = 0;
             Delay_ms(2);      
       }
       
       CS = 1;
       
       return (double)(adcVal & 0x0FFF);
}



- - - Updated - - -

I wrote the code. It is working and it is giving correct values but I am getting this error continuously.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
double MCP3302_Read() {
 
       char i = 0;
       unsigned int adcVal = 0, mask = 0x800;
       
       CLK = 1;
       
       CS = 1;
       Delay_us(20);
       CS = 0;
       Delay_us(20);
       
       DOUT = 1;
       
       CLK = 0;
       Delay_us(20);
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       DOUT = 1;
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       DOUT = 0;
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
       
       CLK = 1;
       Delay_us(20);
       CLK = 0;
       Delay_us(20);
                    
       for(i = 0; i < 13; i++) {
       
             adcVal <<= 1;
             adcVal = adcVal | DIN;                         
                          
             CLK = 1;
             Delay_us(20);
             CLK = 0;
             Delay_us(20);      
       }
       
       CS = 1;
       
       return (double)(adcVal & 0x0FFF);
}




 

Attachments


Vbase

Full Member level 6
Joined
Apr 7, 2015
Messages
367
Helped
74
Reputation
148
Reaction score
72
Trophy points
28
Activity points
1,997
Min clock frequency is 100KHz , Decrease the delay from 20us to 4us.
 

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
Tried 4 us and 2 us but still getting errors.
 

Vbase

Full Member level 6
Joined
Apr 7, 2015
Messages
367
Helped
74
Reputation
148
Reaction score
72
Trophy points
28
Activity points
1,997
You have to send to the ADC 4 bits of config at the end of the first byte and then the data returns in 2 bytes. It is total of 24 bits with 24 clocks. I can't find all this in your code.
 

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
I modified the code. Now I have used Hardware SPI for comminication but still getting the errors in Proteus. Please somebody have a look at the project. I am attaching mikroC PRO PIC project and Proteus file.

I am getting correct adc values but also getting errors.
 

Attachments

Last edited:

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
I have modified the code but now I am not getting any output from ADC3302. What is the problem in my code. I am sending data to ADC on falling edges and also reading data on falling edges.
 

Attachments


milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,528
Helped
540
Reputation
1,078
Reaction score
523
Trophy points
1,393
Activity points
0
I modified the code a little but I am always getting 0 as adc value. What is wrong ?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
double MCP3302_Read(char singDiff, char channel) {
      
       char i = 0;
       unsigned int receivedByte = 0;
              
       Delay_ms(20);
       
       CLK = 0;
       CS = 0;
       Delay_us(50);
                  
       CLK = 1;
       
       DIN = 1;
       Delay_ms(2);
       CLK = 0;
       Delay_ms(2); 
       
       CLK = 1;
       
       DIN = singDiff;
       Delay_ms(2);
       CLK = 0;
       Delay_ms(2); 
       
       CLK = 1;
       
       DIN = channel.B2;
       Delay_ms(2);
       CLK = 0;
       Delay_ms(2); 
       
       CLK = 1;
       
       DIN = channel.B1;
       Delay_ms(2);
       CLK = 0;
       Delay_ms(2); 
       
       CLK = 1;
       
       DIN = channel.B0;
       Delay_ms(2);
       CLK = 0;
       Delay_ms(2); 
             
       for(i = 0; i < 3; i++) {
               CLK = 1;
               
               DIN = 0;
               Delay_ms(2);
               CLK = 0;
               Delay_ms(2);                    
       }
                           
       for(i = 0; i < 12; i++) {
       
             CLK = 1;
             
             receivedByte <<= 1;
             receivedByte |= DIN;
             Delay_ms(2);          
             CLK = 0;
             Delay_ms(2);      
       }
       
       CS = 1;
       
       
       return (double)receivedByte;
}



- - - Updated - - -

Please somebody help. This is my new code. It still doesn't work.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
void SPI_Write(char sdata) {
     char mask = 0x80, i = 0;
     
     for(i = 0; i < 8; i++) {
           SoftSpi_CLK = 1;
           
           if(sdata & mask)
                SoftSpi_SDO = 1;
           else SoftSpi_SDO = 0;
           
           Delay_us(10);
           SoftSpi_CLK = 0;    
     }
}
 
unsigned char SPI_Read(char sdata) {
     char mask = 0x80, i = 0;
     unsigned char rdata = 0;
     
     for(i = 0; i < 8; i++) {
           SoftSpi_CLK = 1;
           
           if(sdata & mask)
                SoftSpi_SDO = 1;
           else SoftSpi_SDO = 0;
           
           rdata <<= 1;
           rdata |= SoftSpi_SDI;
           Delay_us(10);
           SoftSpi_CLK = 0;    
     }
     
     return rdata;
}
 
double MCP3302_Read(char singDiff, char channel) {
      
      unsigned short data_read1 = 0, data_read2 = 0;
      
      unsigned int val = 0;
      
      char i = 0, mask = 0x80, data2Send = 0;
      
      
      
      
      Chip_Select = 0;
      
      SPI_Write(0b00001100);
      data_read1 = SPI_Read(0x80);
      data_read2 = SPI_Read(0x00);
      
      Chip_Select = 1;
      
      val = data_read1;
      val = val << 8;
      val |= data_read2;
      val &= 0xFFF;
      
      return (double)val;
}



- - - Updated - - -

This is my latest project. It is not working. Please provide me a solution. Proteus file is also included.

- - - Updated - - -

I used software spi of mikroC PRO PIC and it is working but I get error in Proteus.
 

Attachments


Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top