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.

CAN - Pic18f4520 - CNA (PCF8591 - I2C )

Status
Not open for further replies.

servntes

Newbie level 6
Joined
Apr 12, 2010
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,395
Hi,

I want to inject a signal between (0V to 5V) on PORTA, 0 ==> AN0, using a potentiometer, and convert this value by an ADC, analog digital convertision

and the result obtained, I want to get it from an analog output, by using a circuit 8-bit Digital to Analog Converter (PCF 8591) through the I2C bus.

I already made the program of DAC and ADC, and I have compiled without error, but its not working in simulation.

I tested the ADC and it works very well, but the DAC not work! I vary the potentiometer for 0V to 5V, but the output is always the result to 0V

Please if anyone can help me in this problem !!

Here is my code, I simulated (no error when compiling):


#include <p18f45k20.h>
#include <stdio.h>
#include <math.h>

#define SCL_PIN PORTCbits.RC3
#define SDA_PIN PORTCbits.RC4

#define SCL_DIR TRISCbits.TRISC3
#define SDA_DIR TRISCbits.TRISC4

void main (void);
void DelayMs(unsigned int);
void Pcf_8591_d2a(unsigned char);
void i2c_init(void);
void i2c_start(void);
void i2c_wr(unsigned char);
void i2c_ack(void);
void i2c_stop(void);
void i2c_high_scl(void);
void i2c_low_scl(void);
void i2c_high_sda(void);
void i2c_low_sda(void);

#pragma code

/*************************
* Variables Definition
*************************/
unsigned char Ys;
/*********************
* principal Fonction
********************/
void main()
{
TRISD=0;

ADCON1=0x00;
ADCON0=0x01;
ADCON2=0x00;

while(1)
{
ADCON0bits.GO = 1; // launch of analog to digital conversion

while (ADCON0bits.GO)
{
//pas de opcode; //wait closure conversion, where GO = 0
}

Ys = ADRESH; //result of the analog to digital conversion,

Pcf_8591_d2a(Ys); //launch of the digital to analog conversion

}
}
/*******************************************
* PCF 8591 //// digital to analog conversion
*******************************************/
void Pcf_8591_d2a(unsigned char dat)
{
int iConfig=0x40; // Configuration of DAC PCF8591; bit6=1(Enable analog output)
int cPCF8591_w=0x90; // Adresse of PCF85910
i2c_init(); // Acknowledge
i2c_start(); // Signal Start
i2c_wr(cPCF8591_w); // Adresse of slave (PCF8591)
i2c_ack(); // Acknowledge
i2c_wr(iConfig); // enable DAC
i2c_ack(); // Acknowledge
i2c_wr(dat); // Data Digital to analog
i2c_ack(); // Acknowledge
i2c_stop(); // Signal Stop
}
/***********************
* Initialisatin Bus I2C
***********************/
void i2c_init(void)
{
SSPSTAT=0x80;
SSPCON1=0x28;
SSPCON2=0x01;
}
/*******************
* Start Condition
******************/
void i2c_start(void)
{
i2c_low_scl();
i2c_high_sda();
i2c_high_scl();
i2c_low_sda();
i2c_low_scl();
}
/*******************
* Stop Condition
*****************/
void i2c_stop(void)
{
i2c_low_scl();
i2c_low_sda();
i2c_high_scl();
i2c_high_sda();
}
/*****************
* Write PCF8591
*****************/
void i2c_wr(unsigned char data)
{
unsigned char n;
for(n=0; n<8; n++)
{
if(data&0x80)
{
i2c_high_sda();
}
else
{
i2c_low_sda();
}
i2c_high_scl();
i2c_low_scl();
data <<=1;
}
i2c_high_sda();
}


/******************************
* Acknowledge
******************************/
void i2c_ack(void)
{
i2c_high_sda();
i2c_high_scl();
i2c_low_scl();
}

/******************************
* Low and High of SCL/SDA
******************************/
void i2c_high_sda(void)
{
SDA_DIR = 1;
DelayMs(1);
}

void i2c_low_sda(void)
{
SDA_PIN = 0;
SDA_DIR = 0;
DelayMs(1);
}

void i2c_high_scl(void)
{
SCL_DIR = 1;
DelayMs(1);
}

void i2c_low_scl(void)
{
SCL_PIN = 0;
SCL_DIR = 0;
DelayMs(1);
}
 

Kurenai_ryu

Advanced Member level 2
Joined
Jun 10, 2006
Messages
671
Helped
159
Reputation
316
Reaction score
99
Trophy points
1,308
Location
Bolivia
Activity points
5,911
well... i don't know why did you try to initialize the MSSP registers for I2C mode, but tries to bit.banging the data.... both methods can't work at the same time...

the best way is to use the MSSP for the I2c Comm... i'll check it in the next minutes... [also I'm working on the keypad input so just wait...]

Added after 40 minutes:

ok, so far this goes like this...
remember! the value you must send to the pCF must be a 8-bit value... so don't forget to re-scale your value (Ys?) before sending...
i used ADRESH directly because I couldn't determine where was the error... there are many TRISC-PORTC instructions by there that interfered with the I2C MSSP communication...
at least it's done by now...



I got lost with your U1,U0 errors values and formulas! could you send some links or theory about what you are planning to do? but maybe this is just enough so you could continue your work...
 

servntes

Newbie level 6
Joined
Apr 12, 2010
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,395
Thank you very much Kurenai_ryu,

U1, U0 and error are parameters for the PI controller (Proportional, Integral)

PI Controller (proportional-integral controller) is a feedback controller which drives the plant to be controlled with a weighted sum of the error (difference between the output and desired set-point) and the integral of that value. It is a special case of the common PID controller in which the derivative (D) of the error is not used.

So: In this image I want to explain what I'm looking to do.

**broken link removed**

The digital control law is:
 U(k) = U(k-1) + ([E (K)-E(K-1)] x kp) + (E(K) x ki)

U(k) present value
E(k) present value of error

U(k-1) previous value
E(k-1) previous value of error

E= Error, Input of PI controller
U=Output of PI controller

for example:

For k = 0, U (0) = (E(0) x kp) + (E(0) x ki)
For k = 1, U (1) = U (0) + ([E(1)-E(0)] x kp) + (E(1) x ki)
Etc ...

Example.

For k = 1, U(1) =U(0) + ([E(1)-E(0)] x kp) + (E(1) x ki)

U (1) = present value
U (0) = previous value

E(1) = present error
E(0) = previous error

Error = Input - Output
you get it in the picture


U(k) and U(k-1) int types are 16 bit

++++++++++++++++++++++++++++++++++++++++++++++++++ ++
So the project I'm achieving is to measure the output of our system and compare it with the input and the result is the error that is injected into the PI controller and calculates we'll have U (0). And we inject our system to adjust the system, and at each sampling step is done the same way, until the system becomes stable.
++++++++++++++++++++++++++++++++++++++++++++++++++ ++


At the programming level:

The PCF8591 will give us about AC analog output value of U(0)
to convert a PCF8591 8-bit, I test the high weight of U(0) ==> MSB
If there is a bit on the MSB, which equals 1
So: var = 0xFF

If there is not any MSB bit which equals 1 ==> MSB==0;
So: var = (char) U(0), that is to say, we will convert LSB (8 bits)

This value which is converted to digital from analog is injected into our system,
System (first order or second order)

And the output of our system we will get a voltage that is injected through the PIC18F PIN AN0 analog

And we calculate:
Error0 = Co - Ys or error0 = Input - Output

Then M = error0 - error1

Prop. = Kp x M;

Integ= Ki x Error;

U0 = U1 + + Prop + Integ;

And will proceed like this N times, until the system is stable.

*********************************************************

The ISIS file you gave me, on the winrar, it does not open
It appears a message at the opening, he told me that I must have the latest version of ISIS to open the file.

So what types of ISIS that you used ???
So what types of ISIS that you used ???[/b]
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top