Hallo!
Ich habe vier Taster an einem PCF8574AP angeschlossen (Taster nach GND), welcher wiederum an einem ATmega48 hängt (I2C). Nun nutze ich diese Funktionen (s. unten) von Mikrocontroller.net. Um die Vorgänge zu überwachen lasse ich Kurznachrichten auf einem LCD anzeigen.
Der Interruptausgang des Portexpanders löst einen Pin-Change-Interrupt aus, was auch wunderbar funktioniert:
Code:
ISR(PCINT2_vect)//PCINT20 -> Ein Taster wurde gedrückt
{
cli();
//Welche Taste?
lcd_clrscr();
lcd_puts("Vorher...");
_delay_ms(500);
uint8_t Taste = pcf8574_get_inputs(0);//Adresse = 0 (alle auf GND)
lcd_clrscr();
lcd_puts("Nachher!");
sei();
};
Das Problem ist, dass sich der Controller bei der Get-Inputs-Funktion resettet, d.h. auf dem LCD bleibt "Vorher..." stehen. Den Neustart kann ich auch mithilfe des LCD erkennen (Mitteilung am Anfang der main()-Funktion).
Mit dem Oszilloskop habe ich schon so gut es geht überprüft, dass weder die Betriebsspannung einbricht noch der Reset-Pin auf low gezogen wird...
Hier die Funktionen von Mikrocontroller.net, die ich verwende:
Code:
#include "pcf8574.h"
void pcf8574_init (void)
{
/*set bus speed*/
TWBR = 0x10;
}
unsigned char pcf8574_send_start (void)
{
/*writing a one to TWINT clears it, TWSTA=Start, TWEN=TWI-enable*/
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
/*wait, until start condition has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}
void pcf8574_send_stop (void)
{
/*writing a one to TWINT clears it, TWSTO=Stop, TWEN=TWI-enable*/
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}
unsigned char pcf8574_send_add_rw (unsigned char address, unsigned char rw)
{
/*address can be 0 .. 8; rw=0 --> write, rw=1 --> read*/
unsigned char addr_byte = 0;
/*shift address one bit left*/
addr_byte = address << 1;
/*set RW-Bit, if necessary*/
addr_byte |= rw;
/*0b0111xxx0 --> address of Expander*/ //für PCF8574AP angepasst (0b0100xxx0 --> 0b0111xxx0)
addr_byte |= 0b01110000;
/*TWDR contains byte to send*/
TWDR = addr_byte;
/*send content of TWDR*/
TWCR = (1<<TWINT) | (1<<TWEN);
/*wait, until address has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}
unsigned char pcf8574_send_byte (unsigned char byte)
{
/*TWDR contains byte to send*/
TWDR = byte;
/*send content of TWDR*/
TWCR = (1<<TWINT) | (1<<TWEN);
/*wait, until byte has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}
unsigned char pcf8574_read_byte (void)
{
/*send content of TWDR; TWEA = enable ACK*/
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
/*wait, until byte has been received --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWDR;
}
unsigned char pcf8574_get_inputs (unsigned char address)
{
pcf8574_init ();
pcf8574_send_start ();
pcf8574_send_add_rw (address, 1);
unsigned char input = pcf8574_read_byte ();
pcf8574_send_stop ();
return input;
}
void pcf8574_set_outputs (unsigned char address, unsigned char byte)
{
pcf8574_init ();
pcf8574_send_start ();
pcf8574_send_add_rw (address, 0);
pcf8574_send_byte (byte);
pcf8574_send_stop ();
}
Was könnte den Reset verursachen?
Vielen Dank im Voraus!
PS: Hier ist noch der Schaltplan:
Staubsaugerroboter2.jpg
Hits: 16
Größe: 85,0 KB
ID: 19205" class="thumbnail" style="float:CONFIG" />
Lesezeichen