Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

How to read MCP3302 using SPI ?

Status
Not open for further replies.

milan.rajik

Banned
Joined
Apr 1, 2013
Messages
2,524
Helped
540
Reputation
1,078
Reaction score
524
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);
}




broken link removed
 

Attachments

  • error.png
    error.png
    28.9 KB · Views: 90
Last edited by a moderator:

Min clock frequency is 100KHz , Decrease the delay from 20us to 4us.
 

Tried 4 us and 2 us but still getting errors.
 

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.
 

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

  • ADC MCP3302 LCD PIC18F46K22.rar
    80.9 KB · Views: 48
Last edited:

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

  • ADC MCP3302 SSD.rar
    130.3 KB · Views: 39

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

  • ADC MCP3302.rar
    77.2 KB · Views: 46
  • ADC MCP3302 soft spi.rar
    78.2 KB · Views: 47

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top