|
|
View previous topic :: View next topic |
Author |
Message |
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
PCA9626 with pic18f45k80 are not working |
Posted: Sat Jul 06, 2013 5:44 pm |
|
|
Hello,
i am new in forum. my code is
Code: |
#include <18f45k80.h>
#device adc=10
#device *=16
#Fuses HSH,PLLEN,NOPUT,NOIESO,NOFCMEN,NOBROWNOUT,NOWDT,NOMCLR,NOEBTRB,NOEBTR//,INTRC_IO
#use delay (clock=64M)
#use I2C(master,scl=pin_b2,sda=pin_b3,slow,force_sw)
void main ()
{
PORT_D_PULLUPS(true);
output_a(0x00); output_b(0x00); output_c(0x02); output_d(0x03); output_e(0x00);
set_tris_a(0b10000001); set_tris_b(0b00000011); set_tris_c(0b10010000); set_tris_d(0x00); set_tris_e(0x00);
//ds1307_init(); // install DS1307
output_low(pin_d0); // Led power is ON
output_low(pin_d4); // OE pin low
i2c_start();
i2c_write(0xa2);
i2c_write(0x00); // Mode 1 address
i2c_write(0xa1); // oscillator settings normal mode
i2c_stop(); // Stop
delay_us(500); // delay at least 500 us
i2c_start(); // Start
i2c_write(0xa2); // Slave Address
i2c_write(0x01); // Mode2 register address
i2c_write(0b00000100); // Outputs change on STOP,
i2c_stop();
// CHASE control
i2c_start();
i2c_write(0xa2);
i2c_write(0x1c);
i2c_write(0x00);
i2c_stop();
while(true)
{
output_high(pin_d0);
delay_ms(100);
output_low(pin_d0);
delay_ms(100);
}
} |
i am using software i2c. i2c lines pulled up with 10k resistors. i am not see any blink. please help me. i am working with this ic first time. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 07, 2013 10:53 am |
|
|
1. Does your LED (on pin D0) blink correctly, if you remove all the i2c code ?
2. What is your crystal frequency ?
3. Why are you using the CANTX and CANRX pins for your i2c ?
Quote: | #use I2C(master,scl=pin_b2,sda=pin_b3,slow,force_sw) |
I'm curious about why you did this, because normally if you choose a PIC
that has CAN bus capablility, such as the 18F45K80, you would save those
pins for use by the CAN bus.
4. The main reason for the i2c functions "hanging" is if you are missing
the pullup resistors. Check the connections. It should look like this:
Code: |
Vdd
|
<
> 4.7K
<
To PIC | To i2c slave
pin for ------------------ SDA pin
SDA
Vdd
|
<
> 4.7K
<
To PIC | To i2c slave
pin for ------------------ SCL pin
SCL |
5. Here you are setting the TRIS for your i2c pins as outputs.
They should be inputs.
Quote: | set_tris_b(0b00000011); |
|
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Sun Jul 07, 2013 2:24 pm |
|
|
thanks your reply,
1. yes blink correctly
2. my crystal frequency is 16MHz and fuse 4xpll
3. I use because there is no pins i can use for i2c. Also i use hardware spi for mmc and i don't use can bus in this circuit
4. I use 10k resistors for pullup because i have seen datasheet application
5. yes my tris function is the same with you
but I realized my circuit voltage is down 5V to 4.5V i guess the circuit has some short cuts i will check tomorrow. What do you think about it?
thanks again PCM programmer |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 07, 2013 7:33 pm |
|
|
Yes, I think correcting your power supply problem is the first thing you
should do. If possible, use a +5v voltage regulator, such as LM7805
or a similar regulator. Or, use a +5v regulated wall transformer.
But the +5v must be stable. |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Mon Jul 08, 2013 12:40 am |
|
|
i checked it and solved the problem. the circuit voltage is 5V now but there is not still blink.
what can i do some else |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 08, 2013 12:59 am |
|
|
1. Run the program in the link below. What address does it find for
the PCA9626 ? You need to modify the #include, #fuses, and #use delay
lines in that program so it will work with your PIC. But do that, and then
run it.
http://www.ccsinfo.com/forum/viewtopic.php?t=49713
2. The i2c slave address for the PCA9626 is set externally, by setting
the logic levels of pins A0-A6 on the PCA9626. What values do you have
those pins set to ?
3. Try commenting out blocks of code in your program. Example:
Comment out all this:
Code: | //output_a(0x00); output_b(0x00); output_c(0x02); output_d(0x03); output_e(0x00);
//set_tris_a(0b10000001); set_tris_b(0b00000011); set_tris_c(0b10010000); set_tris_d(0x00); set_tris_e(0x00); |
Re-compile, test, and see what happens. Does the program now blink
the LED ?
If that doesn't work, then comment out this section:
Code: |
// CHASE control
//i2c_start();
//i2c_write(0xa2);
//i2c_write(0x1c);
//i2c_write(0x00);
//i2c_stop(); |
Keep doing that until you find out what is causing the problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Jul 08, 2013 2:09 am |
|
|
I'd guess you are working at 3.3v?.
If so you need to significantly lower your I2C resistors.
The pull up provides a current to pull the line high. At 100KHz (slow), 10KR, is just about 'OK' for a slow I2C bus, with limited capacitance, and 5v supply. However for 3.3v I2c, even with only 30pF total capacitance, at 100KHz, you get a _maximum_ resistor value of 6.67KR. Typically 4K7R, is a good 'safe' value at 5v, and is acceptable at 3.3v, if you have a short bus, unless you are pushing high speed, or have an exceptional level of capacitance. However 10KR, is too high to be safe. I'm guessing the example you used was at 5v....
Then You are using address A2. So you have the binary pattern 0b 101 0001 on the select pins?. A0, A4, and A6 high, and the other pins pulled low. Remember the select pins are the high seven bits of the address.
Lower your I2C bus resistors, and run the I2C bus scanner program published by PCM programmer (in the code library). If it finds the device, you will _know_ what address it really is at. If not, then you know you have a hardware problem.
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Mon Jul 08, 2013 2:27 am |
|
|
hi,
i realized my adress is not a2. it is 2a and i use 5v voltage level.
i changed pullup resistors an i checked it with oscilloscope high and low level very stable now.
i have tried i2c scanner and now comminication is working very well.
but still no blinking rgb leds.
i think my code is wrong iam sure that now.
i2c_start();
i2c_write(0b00000110);
i2c_stop();
its software reset adress
i2c_start();
i2c_write(0x2a);
i2c_write(0x00); // Mode 1 address
i2c_write(0b01101111); // oscillator settings normal mode
i2c_stop(); // Stop
delay_ms(1); // delay at least 500 us
its configure mode1 register and set oscillator settings of ic
i2c_start(); // Start
i2c_write(0x2a); // Slave Address
i2c_write(0x01); // Mode2 register address
i2c_write(0b00100000); // Outputs change on STOP,
i2c_stop();
its configured mode 2 register and change status of led with stop command or ack bit.
thats mean this configure settings are pca9626_init()
after i have tried this
i2c_start();
ack=i2c_write(0x2a);
i2c_write(0x1d);
i2c_write(0xff);
i2c_stop();
normaly leds open now but there is nothing.
final part of my code is
#include <18f45k80.h>
#device adc=10
#device *=16
#Fuses HSH,PLLEN,NOPUT,NOIESO,NOFCMEN,NOBROWNOUT,NOWDT,NOMCLR,NOEBTRB,NOEBTR//,INTRC_IO
#use delay (clock=64M)
#use I2C(master,scl=pin_b2,sda=pin_b3,fast=1000000)
int1 ack=0;
void main ()
{
PORT_D_PULLUPS(true);
output_a(0x00); output_b(0x00); output_c(0x02); output_d(0x03); output_e(0x00);
set_tris_a(0b10000001); set_tris_b(0b00000011); set_tris_c(0b10010000); set_tris_d(0x00); set_tris_e(0x00);
//ds1307_init(); // install DS1307
output_low(pin_d0); // Led power is ON
output_low(pin_d4); // OE pin low
i2c_start();
i2c_write(0b00000110);
i2c_stop();
i2c_start();
i2c_write(0x2a);
i2c_write(0x00); // Mode 1 address
i2c_write(0b01101111); // oscillator settings normal mode
i2c_stop(); // Stop
delay_ms(1); // delay at least 500 us
i2c_start(); // Start
i2c_write(0x2a); // Slave Address
i2c_write(0x01); // Mode2 register address
i2c_write(0b00100000); // Outputs change on STOP,
i2c_stop();
while(true)
{
// CHASE control
i2c_start();
ack=i2c_write(0x2a);
i2c_write(0x1d);
i2c_write(0xff);
i2c_stop();
if(ack==1)
output_low(pin_b5);
else
output_high(pin_b5);
}
}
pin_b5 is ack check pin and its show me ic sending me ack bit |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Jul 08, 2013 4:16 am |
|
|
Ouch. Are you trying to make the MMC harder?.
Have you got the MMC working?.
Seriously, if not, re-think and work at 3.3v. It makes SD/MMC, about 50* easier.....
You have got OE pulled up?.
You need a short pause each time between I2C_STOP, and I2C_START. The chip specifies 4.7uSec for standard mode I2C between these. You have pauses in several locations, but not each time.
Your software reset is 'wrong'. You need to select the reset address, and then send 0xA5, then 0x5A, then stop. Otherwise you are not resetting.
You haven't set a group duty cycle or frequency for blinking, or enabled any individual output, so not surprised it doesn't do anything....
Code: |
//Untested, untried, etc....
//Processor and I2C setup here
#define I2CADDR 0x2A
#define MODE1 0
#define MODE2 1
#define GRPPWM 0x1A
#define GRPFREQ 0x1B
#define LEDREG 0x1D
void write_byte_to_reg(int8 reg_number, int8 val)
{
I2C_start();
I2C_write(I2CADDR);
I2C_write(reg_number);
I2C_write(val);
I2C_stop();
delay_us(5);
}
void write_block_to_regs(int8 reg_number, int8 no_vals, int8 * vals_to_write)
{
int8 ctr;
I2C_start();
I2C_write(I2CADDR);
I2C_write(reg_number);
for (ctr=0 ; ctr<no_vals ; ctr++)
{
i2c_write(vals_to_write[ctr]);
}
I2C_stop();
}
void reset_chip(void)
{
I2C_start();
I2C_write(0x6);
I2C_write(0xA5);
I2C_write(0x5A); //reset sequence
I2C_stop();
delay_us(5);
}
void main()
{
int8 init_vals[6]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
delay_us(500); //No specification in the data sheet for how quickly the chip wakes...
reset_chip();
delay_us(500); //Same comment
write_byte_to_reg(MODE1, 0b11100000);
delay_us(500); //needed for clock to start
//Now need to set the group to flash
write_byte_to_reg(GRPPWM, 128);
write_byte_to_reg(GRPFREQ, 25); //approx 1Hz half power
write_block_to_regs(LEDREG, 6, init_vals); //Initialise all LED regs to be operated by blink;
write_byte_to_reg(MODE2, 0b0010101); //enable blnking
while(TRUE)
{
}
}
|
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Mon Jul 08, 2013 4:54 am |
|
|
Thanks for your answer.
Yes i work before sd/mmc and sd card work 3.3v pic is 5V. spi communication wires have got level shifting mosfet and 4k7 pullup.
No OE pin has not got a pullup resistor.
I tried your way but there is no blink anyway but your code more sensible. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Jul 08, 2013 7:55 am |
|
|
OE _requires_ a pulldown. The LED's won't ever light without it.....
The signal needs either to connect to the processor and be driven low, or be pulled down.
Best Wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Jul 08, 2013 11:24 am |
|
|
Just as an 'add on' to this.
The point about a 'pull up', is if you are using a processor pin to control it, then the pull up ensures it is 'off' when the processor is not working. Ideally you want to let it go high as soon as power fail is detected, otherwise the driver can keep driving as the power fades away, which can cause some problems.
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Mon Jul 08, 2013 12:37 pm |
|
|
thanks Ttelmah for your answer
I already driven low with pic. That pin is not open drain but i tried pulldown and pullup but no change. I checked package and pin layout but there is not any mistake. Already i said the ic sends me ack so i have a communication with ic. I don't understand where am i making a mistake. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Jul 08, 2013 1:23 pm |
|
|
The classic thing at his point is to try a much simpler test. Set just the first, to feed off it's own PWM, and program this to a fixed level.
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Mon Jul 08, 2013 11:50 pm |
|
|
Hi,
I2C_start();
ack=I2C_write(0x2a);
I2C_write(reg_number);
I2C_write(value);
I2C_stop();
now ack bit is '0'
but
I2C_start();
I2C_write(0x2a);
ack=I2C_write(reg_number);
I2C_write(value);
I2C_stop();
ack bit is '1'
i dont understand |
|
|
|
|
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
|