![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
senator
Joined: 31 Jul 2009 Posts: 17
|
AD7746 |
Posted: Fri Jul 31, 2009 2:14 am |
|
|
Hi,
I have a problem that must be solved urgently. I need to use AD7746 (A capacitance to digital converter chip). I need to get PIC18F4520 read from this chip. I don't know how to go about it. I want to implement i2c for this read operation.
I heard there is a guy called "pcm programmer" on this forum. Please i need the connections and the codes.
Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 31, 2009 2:12 pm |
|
|
It seems to me that you are a complete newbie to C and electronics
and you have chosen a complicated chip to use. You want me to make
a complete driver for you with instructions on how to use it. I don't
want to do that. I'll help you to write your own driver, but you have to
learn C and especially the CCS compiler, and do most of the work
yourself. My advice would be to choose a much more simple chip
than the AD7746, for your first project. |
|
![](templates/subSilver/images/spacer.gif) |
senator
Joined: 31 Jul 2009 Posts: 17
|
|
Posted: Fri Aug 21, 2009 8:14 am |
|
|
Hello PCM programmer, I'm sorry for not communicating for some time now, I've been busy constructing the hardware programmer which i am to use to program the microcontroller pic. I am now to use IC18f4550 and I am trying to construct a schaer and jdm programmer to do this. It's been stressful anyway, but I am still on it.
Because i can't get a model of 'AD7746' on my proteus simulator, i decided to get another sensor that could sense humidity and temperature using also the I2C protocol. It is 'SHT75' sensor but all the same can't get the model on proteus simulator.
So i decided to use a model of PIC microcontroller and 2402 EEPROM which works on the same I2C protocol on proteus simulator. I instructed the microcontroller to write to an address on the EEPROM and read back what was written to the address and display on screen virtual terminal But what i found out was that the microcontroller was displaying the address of what it is supposed to read. I believe if i can simulate this Using I2C protocol then using AD7746 and SHT75 which uses the same I2C protocol wont be a problem. These are the codes please help.
Code: |
#include <18F4520.h>
#device adc=8
#include <2402.C>
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES LP //Low power osc < 200 khz
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV45 //Brownout reset at 4.5V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES XINST //Extended set extension and Indexed Addressing mode enabled
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,address=0xa1,FORCE_HW))
void main()
{
byte data;
{
int data;
I2C_START();
I2C_WRITE(0xa0);
I2C_WRITE(0x34);
I2C_WRITE(0x67);
I2C_WRITE(0x58);
I2C_STOP();
I2C_START();
I2C_WRITE(0xa1);
data=I2C_READ();
I2C_STOP();
}
printf("%lx"data);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 21, 2009 11:52 am |
|
|
Quote: |
#FUSES LP // Low power osc < 200 khz
#FUSES LVP // Low Voltage Programming on B3(PIC16) or
#FUSES PBADEN // PORTB pins are configured as analog
#FUSES XINST // Extended set extension and Indexed
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,address=0xa1,FORCE_HW))
|
You have several problems in your #fuses. Besides the oscillator fuse,
you should change LVP to NOLVP. Change XINST to NOXINST.
The PBADEN fuse can optionally to be left that way. But I think it's
preferable to configure Port B as digital unless you know that you want
it as analog pins.
In your #use i2c() statement, you have a few things that should be
changed. Don't use Fast mode initially. Prove that it works in normal
(slow) mode first. There is no address to be specified for an i2c Master.
That parameter is only used with a Slave. Initially, you should use
software i2c. You avoid any bugs with the hardware MSSP module that
way. Once you get it working, then optionally you can use hardware i2c.
Here are the correct (or recommended) settings:
Code: |
#FUSES HS
#FUSES NOLVP
#FUSES NOPBADEN
#FUSES NOXINST
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
|
One other comment. If you read the descriptions that CCS provides
to the right of the #fuses, you can see that many of them are incorrect.
For example, you're using a 20 MHz crystal. The comment for the LP
fuse says it's for less than 200 KHz operation. That should be a red flag
to you that says something's wrong. |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
just out of curiosity |
Posted: Fri Aug 21, 2009 4:01 pm |
|
|
What are you actually trying to do ?
Yes I know you want to read temp and humidity
but in pursuit of what goal?
Is this destined to be a controller of some kind ?
Or just a a reporting instrument ?
A school project or a commercial product ?
Will the sensor need to be significantly remote from the PIC board?
Are you already planning on using other important PIC features which the 4520 offers?
I ask because the radical decrease in data accuracy coming down from 24 bit ( ad7746 - ok ~~ 20 1/2 bits ) to at BEST a realistic 10 1/2 bits // 12 1/2 bits on the new part - for your captured data,
is quite a drop in performance to make to the design.
Based on that down rating , I'm wondering just how good the data really needs to be - since you already have a quite decent 10 bit converter in the PIC itself - no extra charge, and a lot of useful controller
glue components , courtesy of Microchip .
- You are using a rather powerful PIC to do a very low
demand task - as it looks so far. |
|
![](templates/subSilver/images/spacer.gif) |
senator
Joined: 31 Jul 2009 Posts: 17
|
|
Posted: Mon Aug 24, 2009 9:03 am |
|
|
I really want to thank everyone for your concern and quick response to my request. First of all, I'm working on a school project and my supervisor suggested the use of AD7746 to read temperature and humidity. I don't know how you can help because plans are CONCLUDED on getting (PURCHASING) this I.C. chip.
Then I also tried to correct the faults in my codes by adjusting it, to the corrected copy but I what I have as display on my virtual terminal is the value '00'. No matter how often I adjusted the values to be read I always have the same value. Here is the corrected version.
Code: |
#include <18F4520.h>
#device adc=8
#include <2402.C>
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //Low power osc < 200 khz
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV45 //Brownout reset at 4.5V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode enabled
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,sda=PIN_C4,scl=PIN_C3))
void main()
{
byte data;
{
int data;
I2C_START();
I2C_WRITE(0xa0);
I2C_WRITE(0x34);
I2C_WRITE(0x67);
I2C_WRITE(0x58);
I2C_STOP();
I2C_START();
I2C_WRITE(0xa1);
data=I2C_READ();
I2C_STOP();
}
printf("%lx"data);
|
Please, I would like to upload my hardware connections, how do I do that to this site? |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Aug 24, 2009 11:02 am |
|
|
w/o writing the sequence for you right off the top
why are you NOT starting with sending a 0xBF ???????????
the ALL RESET command to Ad7746 ?
never startup w/o resetting the device first - very bad practice.
SECOND
for commands that are HEX to a CHIP you must
ALWAYS ALWAYS comment WHAT you think the hex means
so somebody else can SEE what you intended instead of
trying to figure it out before seeing if it is the right thing to be doing
if you COMMENT what you intend with EACH of those
hex I2C commands , then
others would consider seeing if you did the right thing
but since it is all undocumented by you , who would bother ?
i am off for 10 days of sun and sand
but i hope this gets you oriented a bit better
best of luck |
|
![](templates/subSilver/images/spacer.gif) |
senator
Joined: 31 Jul 2009 Posts: 17
|
AD7746 code |
Posted: Thu Apr 01, 2010 3:55 am |
|
|
deleted. |
|
![](templates/subSilver/images/spacer.gif) |
dyeatman
Joined: 06 Sep 2003 Posts: 1924 Location: Norman, OK
|
|
Posted: Thu Apr 01, 2010 5:38 am |
|
|
Yes, the first thing that is deficient is that you did not use the code button so
the formatting would be retained. It would help a lot if you would go back
and edit your post to do that. It makes the code a lot more readable. Look
at the earlier posts in the thread to see how it looks. _________________ Google and Forum Search are some of your best tools!!!! |
|
![](templates/subSilver/images/spacer.gif) |
senator
Joined: 31 Jul 2009 Posts: 17
|
|
Posted: Thu Apr 01, 2010 12:11 pm |
|
|
Here is it edited. Thanks
I wrote this code for AD7746 on pic18f4550 but all its seems that it keeps giving me static values for the status, capacitance and temperature measurements.
It seems the code is not measuring.
I defined my registers before reading the output values( status, capacitance, and humidity)
I configured the hardware for single ended capacitance input.
Here is the code:Could anything be deficient in the code?
Code: |
#include <18f4550.h>
#device adc=8
#fuses HS, NOWDT
#use I2C(master,sda=PIN_B0,scl=PIN_B1)
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
void main()
{
float status, cap1,cap2,cap3,temp1,temp2,temp3,status1,status2,status3;
float result,result1;
int32 lump_value,lump_value1,value,value1;
delay_ms(30);
while (1)
{
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x0B);
delay_ms(1);
i2c_write(0x80);
delay_ms(10);
i2c_stop();
delay_ms(20);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x07);
delay_ms(1);
i2c_write(0x80);
delay_ms(10);
i2c_stop();
delay_ms(1);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x08);
delay_ms(1);
i2c_write(0xA0);
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x09);
delay_ms(1);
i2c_write(0x48);
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x0A);
delay_ms(1);
i2c_write(0x59);
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x0c);
delay_ms(1);
i2c_write(0x00);
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x00);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(70);
status = i2c_read();
status1 = i2c_read(0);
status2 = i2c_read(1);
status3 = i2c_read(2);
//i2c_write(0x80);
delay_ms(70);
i2c_stop();
printf( "status= %8.1g%%\n\r",status);
//printf( status1);
printf("status1= %8.1g%%\n\r", status1);
printf("status2= %8.1g%%\n\r", status2);
printf("status3= %8.1g%%\n\r", status3);
printf( status);
delay_ms(20);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x01);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
cap1 = i2c_read();
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x02);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
cap2 = i2c_read();
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x03);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
cap3 = i2c_read();
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x04);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
temp1 = i2c_read();
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x05);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
temp2 = i2c_read();
delay_ms(10);
i2c_stop();
delay_ms(10);
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x06);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
temp3 = i2c_read();
delay_ms(10);
i2c_stop();
lump_value=make32(cap1,cap2,cap3);
lump_value1=make32(temp1,temp2,temp3);
value=lump_value<<8;
value1=lump_value1<<8;
result=(-6+(125*(value/2E24)));//calculation
result1= (value/2048)-4096;
printf("RH=%3.1g%%\n\r",result);
printf("temp= %3.1g%%\n\r" , result1);
delay_ms(50);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 01, 2010 1:08 pm |
|
|
Quote: | status = i2c_read();
status1 = i2c_read(0);
status2 = i2c_read(1);
status3 = i2c_read(2);
|
The problem is that you are inventing a syntax that does not exist.
You are not reading the manual. Nobody wants to help you if you
don't read the CCS manual.
Here is what the manual says about the i2c_read() function.
The parameter is not the "byte number". It's ACK or No ACK.
Quote: |
I2C_read( )
Syntax: data = i2c_read();
data = i2c_read(ack);
data = i2c_read(stream, ack);
Parameters: ack -Optional, defaults to 1.
0 indicates do not ack.
1 indicates to ack.
stream - specify the stream defined in #USE I2C
|
Quote: |
i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_ms(1);
i2c_write(0x0c);
delay_ms(1);
i2c_write(0x00);
delay_ms(10);
i2c_stop(); |
Here is another reason why your code is bad. You don't know why it
fails. So you are putting delays between every line. Of course, it doesn't
help because that's not the problem.
Another reason why people don't want to look at your code is because
you are using inline code, instead of routines (functions). C programmers
expect you to use routines. You should have routines to read and write
to the A/D chip.
Quote: | i2c_start();
delay_ms(30);
i2c_write(0x90);
delay_us(10);
i2c_write(0x01);
delay_us(10);
i2c_start();
delay_ms(30);
i2c_write(0x91);
delay_ms(10);
cap1 = i2c_read();
delay_ms(10);
i2c_stop(); |
Also, it's clear that you have not looked at any i2c driver example code,
either on the forum or in the CCS drivers directory. All sample i2c code
shows the same thing. The last call to the i2c_read() function in a read
routine always has the 0 parameter, which does a NACK (no acknowledge).
If you want to write programs, and have the respect from other
programmers, you need to:
1. Read the CCS manual about functions that you are using.
2. Look at examples of code for i2c, on the forum and in the CCS directories.
3. Learn basic programming methods, such as how to write a function,
and why a function (routine) is a good idea.
4. Do all these things. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|