robodriver
12.07.2009, 22:03
Hey Jungs,
ich habe hier ein Problem was mich seit einigen Tagen ziemlich stark verwirrt.
Vielleicht hat jemand von euch Ideen von woher ein solches Problem kommen könnte.
Folgendes:
Ich habe einen ATMega88 Fuses sind auf externen Clock gestellt und der Chip hängt an einen 8MHz Quarz Oszillator.
Der Chip fungiert als Slave am I²C Bus. Der Master ist auch ein Atmel Controller (ATMega1280, aber der ist erstmal unwichtig).
Das Programm ist momentan noch recht einfach:
int main(void)
{
init();
__RESET_LED;
_delay_ms(100);
__SET_LED;
_delay_ms(100);
__RESET_LED;
_delay_ms(100);
__SET_LED;
_delay_ms(100);
__RESET_LED;
while(1);
}
void init(void)
{
//------------------------
//Ein/Ausgänge:
//------------------------
DDRD |= _BV(0) | _BV(3) | _BV(1) | _BV(6) | _BV(7); //Motoren rechts/links und LED
DDRB |= _BV(0);
PORTD |= _BV(6); //vor2
//PORTD |= _BV(7); //zurück2
PORTD |= _BV(0); //vor1
//PORTB |= _BV(0); //zurück1
//------------------------
//Timer/Counter:
//------------------------
DDRB |= _BV(3); //PWM-Pin als Output
DDRD |= _BV(3); //PWM-Pin als Output
ASSR=0;
TCCR2A |= (1<<WGM20); //PWM-Mode
TCCR2A |= (1<<COM2A1) | (1<<COM2B1); //Compare = Set
TCCR2B |= (1<<CS20); //Prescaler 64
TCNT2=0;
OCR2A = 0; //PWM-Wert
OCR2B = 0; //PWM-Wert
//I2C Initialisieren:
i2c_init_slave(MY_I2C_ADR);
TWAMR = 255;
sei();
}
int i2c_init_slave(char address)
{
TWSR = 0;
TWDR = 0xFF;
TWCR = 0b00000100;
TWAR = (address<<1);
TWCR = 0b01000101;
return 1;
}
SIGNAL (SIG_2WIRE_SERIAL)
{
uint8_t status = 0;
uint8_t data = 0;
//PORTD &= ~(1<<PD2);
data = TWDR;
status = TWSR;
if (status_is(0xA8) || status_is(0xB8))
{
if (twi_send_data[a])
{
TWDR = twi_send_data[a];
a++;
if(a>3)
a=0;
}else{
for(a=0;a<11;a++)
twi_send_data[a]=0;
a=0;
TWDR = 0;
}
//TWDR = mydata;
}
TWCR |= 0b10000000;
if (status_is(0x80))
{
if (data == '*')
{
twi_data_received = 1;
}else{
if (twi_pointer < 10)
twi_buffer[twi_pointer++] = data;
//else
//fehler();//FEHLER!!
}
}
}
So viel zum Code, nur so, falls jemand was darin sieht...
Nun zum Problem:
Wie man sieht, müsste der Controller beim Einschalten 2x die LED blinken.
Der Master Controller Startet regelmäßig den Bus mit der Slaveadresse, sendet 2 Bytes und stopt den Bus wieder.
Mehr passiert da momentan nicht.
So und nun treten bei mir immer 2 verschiedene Möglichkeiten auf:
1) Ich starte alles und die LED blinkt 2x. Wenn der MAster den Slave aufruft, wird der Interrupt am Slave nicht aufgerufen, die Daten nicht bestätigt und somit gibt es einen Fehler auf dem Bus.
2) Ich starte alles und die LED blinkt 1x. Wenn der Master dann den Slave aufruft, dann läuft der Datentransfer ohne jegliche Probleme, ACKs kommen zurück und alles.
Unterm strich heißt das also:
Wenn die LED anfangs so blinkt (2x) wie es im Code steht, dann geht der Bus nicht.
Und wenn die LED anfangs nur einmal blinkt, was laut Code überhaupt nicht sein kann, dann geht der Bus hervorragend.
Wann welche der Möglichkeiten auftritt habe ich noch nicht heraus gefunden. Immer nach dem Brennen tritt eine dieser beiden Möglickeiten ein. Und irgendwann später mal beim brennen mal wieder die andere.
Ich habe da noch keinerlei Muster erkannt wann was kommt und auch keinerlei Ahnung was da los ist.
Weil keine der beiden Möglichkeiten nach dem Code richtig läuft...
Bin für jeden Hinweis dankbar. Egal welcher Art. Denn ich habe für dieses Verhalten keinerlei Erklärung...
PS: Die Interruptroutine läuft 1:1 auf einem anderen Chip am selben Bus fehlerfrei.
ich habe hier ein Problem was mich seit einigen Tagen ziemlich stark verwirrt.
Vielleicht hat jemand von euch Ideen von woher ein solches Problem kommen könnte.
Folgendes:
Ich habe einen ATMega88 Fuses sind auf externen Clock gestellt und der Chip hängt an einen 8MHz Quarz Oszillator.
Der Chip fungiert als Slave am I²C Bus. Der Master ist auch ein Atmel Controller (ATMega1280, aber der ist erstmal unwichtig).
Das Programm ist momentan noch recht einfach:
int main(void)
{
init();
__RESET_LED;
_delay_ms(100);
__SET_LED;
_delay_ms(100);
__RESET_LED;
_delay_ms(100);
__SET_LED;
_delay_ms(100);
__RESET_LED;
while(1);
}
void init(void)
{
//------------------------
//Ein/Ausgänge:
//------------------------
DDRD |= _BV(0) | _BV(3) | _BV(1) | _BV(6) | _BV(7); //Motoren rechts/links und LED
DDRB |= _BV(0);
PORTD |= _BV(6); //vor2
//PORTD |= _BV(7); //zurück2
PORTD |= _BV(0); //vor1
//PORTB |= _BV(0); //zurück1
//------------------------
//Timer/Counter:
//------------------------
DDRB |= _BV(3); //PWM-Pin als Output
DDRD |= _BV(3); //PWM-Pin als Output
ASSR=0;
TCCR2A |= (1<<WGM20); //PWM-Mode
TCCR2A |= (1<<COM2A1) | (1<<COM2B1); //Compare = Set
TCCR2B |= (1<<CS20); //Prescaler 64
TCNT2=0;
OCR2A = 0; //PWM-Wert
OCR2B = 0; //PWM-Wert
//I2C Initialisieren:
i2c_init_slave(MY_I2C_ADR);
TWAMR = 255;
sei();
}
int i2c_init_slave(char address)
{
TWSR = 0;
TWDR = 0xFF;
TWCR = 0b00000100;
TWAR = (address<<1);
TWCR = 0b01000101;
return 1;
}
SIGNAL (SIG_2WIRE_SERIAL)
{
uint8_t status = 0;
uint8_t data = 0;
//PORTD &= ~(1<<PD2);
data = TWDR;
status = TWSR;
if (status_is(0xA8) || status_is(0xB8))
{
if (twi_send_data[a])
{
TWDR = twi_send_data[a];
a++;
if(a>3)
a=0;
}else{
for(a=0;a<11;a++)
twi_send_data[a]=0;
a=0;
TWDR = 0;
}
//TWDR = mydata;
}
TWCR |= 0b10000000;
if (status_is(0x80))
{
if (data == '*')
{
twi_data_received = 1;
}else{
if (twi_pointer < 10)
twi_buffer[twi_pointer++] = data;
//else
//fehler();//FEHLER!!
}
}
}
So viel zum Code, nur so, falls jemand was darin sieht...
Nun zum Problem:
Wie man sieht, müsste der Controller beim Einschalten 2x die LED blinken.
Der Master Controller Startet regelmäßig den Bus mit der Slaveadresse, sendet 2 Bytes und stopt den Bus wieder.
Mehr passiert da momentan nicht.
So und nun treten bei mir immer 2 verschiedene Möglichkeiten auf:
1) Ich starte alles und die LED blinkt 2x. Wenn der MAster den Slave aufruft, wird der Interrupt am Slave nicht aufgerufen, die Daten nicht bestätigt und somit gibt es einen Fehler auf dem Bus.
2) Ich starte alles und die LED blinkt 1x. Wenn der Master dann den Slave aufruft, dann läuft der Datentransfer ohne jegliche Probleme, ACKs kommen zurück und alles.
Unterm strich heißt das also:
Wenn die LED anfangs so blinkt (2x) wie es im Code steht, dann geht der Bus nicht.
Und wenn die LED anfangs nur einmal blinkt, was laut Code überhaupt nicht sein kann, dann geht der Bus hervorragend.
Wann welche der Möglichkeiten auftritt habe ich noch nicht heraus gefunden. Immer nach dem Brennen tritt eine dieser beiden Möglickeiten ein. Und irgendwann später mal beim brennen mal wieder die andere.
Ich habe da noch keinerlei Muster erkannt wann was kommt und auch keinerlei Ahnung was da los ist.
Weil keine der beiden Möglichkeiten nach dem Code richtig läuft...
Bin für jeden Hinweis dankbar. Egal welcher Art. Denn ich habe für dieses Verhalten keinerlei Erklärung...
PS: Die Interruptroutine läuft 1:1 auf einem anderen Chip am selben Bus fehlerfrei.