|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Tue Jul 09, 2013 1:00 am |
|
|
What is in 'reg_number' at this point?.
Remember that in I2C, it is NACK. A _negative_ acknowledge. The data line is pulled low, to acknowledge. So the chip is acknowledging it's address, but not the register number. It'd do this if the number is not legitimate. Register numbers allowed, are 0 to 0x26.
As a comment, my write_block_to_reg function needs the following mod:
Code: |
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 | 0x80); //turn on the auto increment
for (ctr=0 ; ctr<no_vals ; ctr++)
{
i2c_write(vals_to_write[ctr]);
}
I2C_stop();
}
|
Also change the value sent to mode1, to:
Code: |
write_byte_to_reg(MODE1, 0b00000000);
|
The bit 7, is a read back of what is set in the command register, and shouldn't be set here.
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Tue Jul 09, 2013 1:26 am |
|
|
thank you very much Ttelmah
write_byte_to_reg(MODE1, 0b00000000);
i changed it and its work. i dont understand why but its work now. normaly oscilator is off this command but its works..??..
thank you again |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Tue Jul 09, 2013 2:57 am |
|
|
if somebody need this ic, ic code is here
Code: |
#define I2CADDR 0x2A
#define MODE1 0x00
#define MODE2 0x01
#define GRPPWM 0x1A
#define GRPFREQ 0x1B
#define LEDREG 0x9D
int1 ack=1;
void write_byte_to_reg(unsigned int8 reg_number,unsigned int8 val)
{
I2C_start();
I2C_write(I2CADDR);
I2C_write(reg_number);
I2C_write(val);
I2C_stop();
delay_us(10);
}
void write_block_to_regs(unsigned int8 reg_number,unsigned int8 no_vals,unsigned 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();
delay_us(10);
}
void reset_chip(void)
{
I2C_start();
I2C_write(0x06);
I2C_write(0xA5);
I2C_write(0x5a); //reset sequence
I2C_stop();
delay_us(10);
}
void main ()
{
setup_oscillator(OSC_PLL_ON|OSC_NORMAL);
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);
SETUP_TIMER_1(T1_DISABLED);
//ds1307_init(); // install DS1307
ds1307_init(); // install DS1307
int8 init_vals[6]= {0xff,0xfF,0xfF,0xfF,0xfF,0xfF};
int8 init_vals_pwm[24]= {0x0f,0x0F,0x0F,0x0F,0x0F,0x0F,0x0f,0x0F,0x0F,0x0F,0x0F,0x0F,0x0f,0x0F,0x0F,0x0F,0x0F,0x0F,0x0f,0x0F,0x0F,0x0F,0x0F,0x0F};
//delay_ms(500); //No specification in the data sheet for how quickly the chip wakes...
output_high(pin_d4); // OE pin high
delay_us(5);
output_low(pin_d4); // OE pin low
//output_low(pin_d1);
reset_chip();
delay_us(500); //Same comment
write_byte_to_reg(MODE1, 0b00000000);
delay_ms(1); //needed for clock to start
write_byte_to_reg(MODE2, 0b00000010);
write_block_to_regs(0x82, 24, init_vals_pwm);
write_block_to_regs(LEDREG, 6, init_vals);
while(true) ;
} | normaly ledreg adress is 0x1d but you want to block write so +0x80 that adress. adress is 0x9d now block write is active example
Code: |
I2C_start();
I2C_write(0x2a);
I2C_write(0x9d);
I2C_write(0xff);
I2C_write(0xf0);
I2C_write(0x0f);
.
.
.
.
I2C_write(0xf0);
I2C_write(0xbf);
I2C_stop(); |
thank you PCM programmer and Ttelmah for their solutions |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19587
|
|
Posted: Tue Jul 09, 2013 4:40 am |
|
|
0, sets the oscillator _on_. It is bit 4.
The key point is the top three bits. Only two of these are writeable (5&6). The top one is not. If these are all zero, and you then set bit seven in the register address when you write, bit 7 will read back here as '1'. Setting this bit in the register address enables the auto increment mode, which is needed for multiple register writes, but not otherwise. Hence the other mod needed to turn this on in the block write.
The point is that modes with zero in bit 7 of the register address, and anything but zero in bits 5 and 6 here are 'not supported' (the remark I refer to in the data sheet). Hence the error when writing the register number. It's rather insane, if you want to use the limited range writes, you have to ensure you change these two bits here, and then that all address write have the high bit set as well. It seems easier to leave these as zero, and just use the 'generic' multi write mode by setting the high bit in the register address when needed. A bit of rather 'thoughtless' design...
So, if you set all the bits to zero, it enables the oscillator, and ensures that single byte writes with a standard register address will then work. Then to do multi byte writes all you have to do is turn on bit 7 in the register address and perform the writes. However you lose the ability to restrict the write range for these. Just means you need to be a bit careful in selecting the address when doing multi byte writes.
Best Wishes |
|
|
eeeahmet
Joined: 06 Jul 2013 Posts: 18 Location: Turkey
|
|
Posted: Tue Jul 09, 2013 4:49 am |
|
|
Thank you very much Ttelmah
Best Regards |
|
|
|
|
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
|