CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

MCP3021 don't work!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

MCP3021 don't work!
PostPosted: Wed Oct 31, 2007 10:11 am     Reply with quote

Hi there!
I make a code to comunicate with a i2c mcp3021 device but it don'work!
what's wrong with my code?
Code:
struct DoisBytes
{
   int iLsb;
   int iMsb;
};
union Junta_dados
{
   int16 Total_ad;
   struct DoisBytes Msb_Lsb;
}Valor_ad;
int lsb;//varialvel do byte baixo do mcp3021
int msb;//varialvel do byte alto do mcp3021

//*AUTHOR Douglas Ricardo Dos Santos Pereira
//*PURPOSE Le o expander mcp23016 suas entradas
//*DATE_CREATED 01/06/2006
//*CHANGES
int16 Read_ad(){
   int16 temp_pressao;
   i2c_start();
   i2c_write(0b11011001); //coloca endreco do escravo  e como escrita
   msb   = i2c_read(1); //comando de ler o msb
   lsb   = i2c_read(0); //comando de ler o lsb
   i2c_stop();//finaliza leitura
   delay_us(50);
   Valor_ad.Msb_Lsb.iLsb=lsb;
   Valor_ad.Msb_Lsb.iMsb=msb;
   Valor_ad.Total_ad = Valor_ad.Total_ad>>2; // ajusto os bits
   temp_pressao=Valor_ad.Total_ad;
   return temp_pressao;
}


and the main code


Code:
#include <16F628a.H>
#use delay(clock=4000000)
#fuses XT,NOWDT,PROTECT,PUT,NOBROWNOUT,NOLVP
#use i2c(master, scl=pin_a2 ,sda=pin_a3)
#use fast_io(a)
#use fast_io(b)
int16 Valor_pressao;
void main()
{
    set_tris_a(0b00111111);
    set_tris_b(0b00000000);
   
   setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_64);//timer0 com clock interno e prescaler dividindo por 64
   set_timer0(155);
   lcd_init(); // Inicio obrigatorio
   lcd_setcursor(0,0); // ajusta cursor invisivel e modo fixo
   
   // TODO: USER CODE!!
   while(true){
      Valor_pressao=read_ad();
      printf(lcd_putc, "%u  ", Valor_pressao);
   }

}


this is not a precision code to show a converted value, is a very simple attempt to comunicate with mcp3021.
please what can I do to fix it?
Thanks!
_________________
Breaking rocks in the hot sun!
Doglao
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Oct 31, 2007 10:52 am     Reply with quote

I think you have your bits the wrong way around!

i2c_write(0b11011001);

Should be

i2c_write(0b10011011);
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Wed Oct 31, 2007 11:39 am     Reply with quote

Thanks Wayne_!
I'm going to prove with this change, is need firstly to send the device code as lsb. so! this seam like this:
Code:
i2c_write(0b10011011); // first four bits is the device code fallowed by the three address bits
// and finished with a bit that said to device is read or write operation by the master,

very thanks, I return the results
_________________
Breaking rocks in the hot sun!
Doglao
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Oct 31, 2007 1:37 pm     Reply with quote

I would suggest _not_ using fast_io and not trying to set the tris. Just let the compiler take care of things for the I2C bus.

What is the full part number for the A/D? The address is dependant on the part number. Check out the data sheet thoroughly to see what address to send.

Ronald
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Wed Oct 31, 2007 1:42 pm     Reply with quote

Hi! Wayne_
is not running yet! I believe that need a delay time more great than the current for each calling to the read_ad function, but I make the changes and not run to.
my circuit is the same that I use with other i2c device that run perfectly
_________________
Breaking rocks in the hot sun!
Doglao


Last edited by Doglao on Wed Oct 31, 2007 2:02 pm; edited 1 time in total
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Wed Oct 31, 2007 2:00 pm     Reply with quote

Thanks Ronald!
I'm using the default address 101 because the part don't was ordered from microchip.com with a special address. this was buyed from a supplier informal , but is not a bad idea to probe with other addresses.
I return the results.
_________________
Breaking rocks in the hot sun!
Doglao
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Wed Oct 31, 2007 6:09 pm     Reply with quote

is not working! I make the changes in the configuration of porta letting the compiler set your configurations and also change all addresses possibles and not working yet.
is my code wrong on theirs commands?
Code:
   i2c_start();
   i2c_write(0b10011011);  //coloca endreco do escravo  e como escrita
   msb   = i2c_read(1); //comando de ler o msb
   lsb   = i2c_read(0); //comando de ler o lsb
   i2c_stop();//finaliza leitura

thanks!
_________________
Breaking rocks in the hot sun!
Doglao
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 31, 2007 6:51 pm     Reply with quote

Do you have 4.7K pullup resistors on the SDA and SCL signals ?
They are required by the i2c specification.
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Thu Nov 01, 2007 11:32 am     Reply with quote

Thanks to reply PCM Programmer!
Yes !! are existing pullups with those resistors that you mentioned in both lines sda and scl. and this circuit work well with other device 12c mcp23016 that I use in other project. I think that my code is not reliable with the datasheet recommendations.
Thanks again!
_________________
Breaking rocks in the hot sun!
Doglao
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 12:12 pm     Reply with quote

Ok. So, post the full part number and the address that you are attempting to write to.
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Thu Nov 01, 2007 12:53 pm     Reply with quote

Thanks Ronald!

MCP3021A5T-E/OT
the address that I use is 101 that match with the A5 address options of partnumber.
_________________
Breaking rocks in the hot sun!
Doglao
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 1:27 pm     Reply with quote

Doglao wrote:
is my code wrong on theirs commands?
Code:
   i2c_start();
   i2c_write(0b10011011);  //coloca endreco do escravo  e como escrita
   msb   = i2c_read(1); //comando de ler o msb
   lsb   = i2c_read(0); //comando de ler o lsb
   i2c_stop();//finaliza leitura
Have you tried to swap the acknowledge parameter in the two read commands?
I looked at the Microchip Application note AN845 for the similar MCP3221 chip and there they do first an ACK0 and then ACK1. So it becomes:
Code:
   i2c_start();
   i2c_write(0b10011011);  //coloca endreco do escravo  e como escrita
   msb   = i2c_read(0); //ACK 0
   lsb   = i2c_read(1); // ACK 1
   i2c_stop();//finaliza leitura
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 1:51 pm     Reply with quote

The terminology can be a bit confusing here. The command i2c_read(1), which is the default, tells the Master to send an ACK, negative pulse on the SDA line, to the Slave. An i2c_read(0) sends a NOACK. The proper communication sequence is:

Code:
i2c_start();
i2c_write(address);
msb = i2c_read(1);
lsb = i2c_read(0);
i2c_stop();


This would correspond with the I2C standard to send a NOACK on the last read(which tells the slave that the read sequence is over) and it is what the app note states to do.

The most likely problem is that the incorrect address is being sent. That's why I asked for the complete part number of the A/D so I could tell what address should be sent.

Ronald
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 01, 2007 2:46 pm     Reply with quote

Try a more simple program:
Code:
#include <16F628A.H>
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use i2c(master, scl=PIN_A2, sda=PIN_A3)

#include <flex_lcd.c>

//-----------------------------------
#define MCP3021_READ_ADDR 0b10011011

int16 read_mcp3021(void)
{
int8 lsb;
int8 msb;
int16 retval;

i2c_start();
i2c_write(MCP3021_READ_ADDR);   
msb = i2c_read();
lsb = i2c_read(0);
i2c_stop();

retval = make16(msb, lsb) >> 2;

return(retval);
}


//============================
void main()
{
int16 result;

lcd_init();

while(1)
  {
   result = read_mcp3021();
   printf(lcd_putc, "\f%lx    ", result);
   delay_ms(500);
  }
}
Doglao



Joined: 26 Mar 2007
Posts: 11

View user's profile Send private message MSN Messenger

PostPosted: Thu Nov 01, 2007 4:06 pm     Reply with quote

Thanks for all!
it is working now!
I put a 11us delay before read the data, this delay is necessary to make a acquisition time Tacq(1.12usec) plus Conversion Time Tconv(8.96) and this work well, the values changing linearity. the other thing that I know now, is to join msb and lsb with make16() command.
very very very thanks!!
_________________
Breaking rocks in the hot sun!
Doglao
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group