Atmegan ja AD5121 digipotikan I2C yhteys tuottaa ongelmia C:llä
Visualmicrolla homma toimii, käyttäein arduinon kirjastoa… Eli raudassa ei ole vikaa.
I2C väylässä ei ole vastuksia vaan sisäiset ylösvedot.
Arduinon koodi:
Wire.beginTransmission(0x2F); // Address #47
Wire.write(0x10); // Instruction byte
Wire.write(val); // Potentiometer value
Wire.endTransmission();
C koodissa olen käyttänyt osoitetta 0x20 koska digipotikan oikealla (0x2F) osoitteella oskiloskoopissa ei näy mitään… Johtuu varmaan siitä että kellojakson viimeinen bitti on aina 1.
Eli kertokaas mikä koodissa mättää…
C koodi:[code]
/* Crystal 20 MHz */
#define F_CPU 20000000L
/* I2C clock in Hz */
#define SCL_CLOCK 222000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
/*************************************************************************
Initialization of the I2C bus interface. Need to be called only once
************************************************************************/
void i2c_init(void)
{
/ initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 /
TWSR = 0; / no prescaler /
TWBR = ((F_CPU/SCL_CLOCK)-16)/2; / must be > 10 for stable operation /
}/ i2c_init */
/*************************************************************************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
*************************************************************************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
return 0;
}/* i2c_start */
/*************************************************************************
Terminates the data transfer and releases the I2C bus
************************************************************************/
void i2c_stop(void)
{
/ send stop condition */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
}/* i2c_stop */
/*************************************************************************
Send one byte to I2C device
Input: byte to be transfered
Return: 0 write successful
1 write failed
*************************************************************************/
unsigned char i2c_write( unsigned char data )
{
uint8_t twst;
// send data to the previously addressed device
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits
twst = TW_STATUS & 0xF8;
if( twst != TW_MT_DATA_ACK) return 1;
return 0;
}/* i2c_write */
int main(void)
{
DDRC = 0xff; // use all pins on port C for output
DDRD = 0xff; // use all pins on port D for output
PORTD |= (1 << PD5); // led on
PORTC |= (1 << PC4) | (1 << PC5); // pull-up
_delay_ms(1000);
for(;
{
i2c_init(); // init I2C interface
i2c_start(0x20); // set device address (oikea 0x2F)
i2c_write(0x10); // set device control byte
i2c_write(0xFF); // set pot value
i2c_stop();
_delay_ms(10);
}
}
[/code]