Hallo allemaal,
Ik probeer een display aan te sturen van adafruit, het gaat om de 8*8 led matrix met een I2C backpack (HT16k33, datasheet :https://cdn-shop.adafruit.com/datasheets/ht16K33v110.pdf).
Nu wilt de I2C communicatie tussen de atmega328 en het led matrix niet werken. Ik stuur het adres van de module (0x70) over de bus maar krijg vervolgens geen ACK terug.
Hier de code:
I2C class:
#include "I2C.h"
#include <avr/io.h>
void I2C::start(){
//Set speed (100 kHZ)
TWSR = 0x00;
TWBR = 0x48;
//Set TWI pins as input, and enable pullups
DDRC &= ~(1 << DDC5); // SCL, Clear the PC5 pin, PC5 is now an input
PORTC |= (1 << PORTC5); // SCL, turn On the Pull-up PC5 is now an input with pull-up enabled
DDRC &= ~(1 << DDC4); // SDA
PORTC |= (1 << PORTC4); // SDA
//Enable I2C and ACKs
TWCR = (1<<TWEN) | (1 << TWEA);
}
void I2C::sendStart(){
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while ((TWCR & (1<<TWINT)) == 0);
}
void I2C::sendStop(){
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void I2C::writeByte(uint8_t aByte){
TWDR = aByte;
TWCR = (1 << TWINT) | (1 << TWEN);
while ((TWCR & (1<<TWINT)) == 0);
}
uint8_t I2C::readAck(){
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while ((TWCR & (1<<TWINT)) == 0);
return TWDR;
}
uint8_t I2C::read(){
TWCR = (1<<TWINT)|(1<<TWEN);
while ((TWCR & (1<<TWINT)) == 0);
return TWDR;
}
uint8_t I2C::status(){
uint8_t status = 0;
status = TWSR & 0xF8;
return status;
}
en de code voor het testen:
connection.start();
connection.sendStart();
connection.writeByte(I2C_Address);
uint8_t status = connection.status();
connection.sendStop();
return status;
De status die ik terugkrijg is 0x20, dit betekend dat de byte is verzonden maar dat geen ACK is ontvangen, iemand enig idee hoe dit komt?
ps. ik gebruik de interne pull-ups met een verlaagde data-rate 100kHz, dit doet arduino ook en daarop werkt het display wel.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
D'r is een library die "Wire" heet. Dat is een i2c library. Waarom gebruik je die niet?
P.S. De interne pullups zijn te zwak om I2C te laten werken. Neem een 4k7 pullup (10x kleiner dan de interne pullups).
[Bericht gewijzigd door rew op (41%)]
@rew, ik las in de datasheet dat de het led-matrix bord over pullups beschikt, dus ik heb de interne pullups uitgezet maar nog steeds zonder resultaat. Ik gebruik geen wire library omdat ik geen Arduino librarys wil gebruiken.
KGE
Golden Member
Klopt je I2C adres wel ? Volgens de datasheet is het address:
1 1 1 0 A2 A1 A0 RW
Ik weet niet precies hoe je routine het adres overpiept maar dan zou het volgens mij 0xE0 moeten zijn. En dan alleen wanneer A2 A1 en A0 op de juiste manier aangesloten zijn.
Ik gebruik een adres van 0x70.
De A getallen zijn nul dus dat geeft de volgende binaire waarde:
1 1 1 0 0 0 0 RW
64 + 32 + 16 = 112, dit geeft een hex waarde van 0x70.
De MSB staat links in het voorbeeld.
Ja hij werkt!, dankjewel allebei !!
Toch vreemd dat ik in alle Arduino voorbeelden het adres van 0x70 zie...
Arduino gebruikt inderdaad 7bit adressering. Arduino lib voegt daar zelf nog de RW bit aan toe.
Schuift dus eigenlijk de 7 bits 1 plekje naar links + RW bit.
Maar omdat je nu zelf direct naar het TWDR register schrijft moet dat een compleet 8bits adres in zetten.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Je mag het van mij op de moeilijke manier doen, maar als het niet werkt, en er is een makkelijke manier, dan lijkt het me handig om dat te proberen, om te zien of de hardware zo in orde is.
Tuurlijk zie je in "alle arduino voorbeelden" 0x70. De library schuift de bitjes 1 naar links omdat sommige mensen vinden dat 0x70 als adres 0xe0 voor write, 0xe1 voor read op de bus wordt. Dat is het nadeel van het onderste bitje voor read/write gebruiken.