Reissdorf
21.03.2013, 12:11
Hallo zusammen,
um ehrlich zu sein, verzweifel ich an meiner PCF8574-Schaltung. Die folgende Funktion sollte hier stattfinden:
Ein, am PCF8574 angeschlossener, Schalter wird gedrückt und zieht den entsprechenden Pin auf GND
Der PCF8574 löst daraufhin ein Interrupt aus und zieht das INT-Signal auf GND
Der Mikrocontroller erkennt das INT-Signal und springt zur entsprechende ISR
In der ISR wird der PCF ausgelesen und das Ergebnis für eine LCD Anzeige umgewandelt
Das LCD Modul sollte nun die ausgelesenen 8 Bit darstellen
Die LCD-Anzeige wird auch über I2C angesprochen, sie liefert aber kein INT-Signal zurück (das kann also keine Störung verursachen)!
Ich schaffe es, dass der Interrupt ein Auslesen anstößt und etwas, dass wie Bits aussieht, ausgibt. Drücke ich Taster 2, der am P6 des PCF8574 hängt, dann sollte ein "10111111" angezeigt werden. Das habe ich jetzt dreimal getestet und einmal habe ich ein "11011001", dann ein "00111111" und schließlich ein "11111111" erhalten. Nach dem letzten Ergebnis tillte die Anzeige völlig aus und zeigte, in rasender Folge, wirre Zeichen auf dem LCD-Display.
Hier der Code und die PCF8574 Schaltung und darunter der Schaltplan. Ich hoffe sehr, dass mir irgendjemand weiterhelfen kann, denn mittlerweile habe ich den Durchblick völlig verloren :(
#ifndef F_CPU //Wenn CPU-Takt nicht bereits definiert wurde...
#define F_CPU 16000000 //...dann definiere ihn auf 16MHz
#endif
#include "i2clcd.h"
#include "i2cmaster.h"
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char adr1_w = 0x42; // Device 1 write-address
volatile unsigned char adr1_r = 0x43; // Device 1 read-address
unsigned char read_data; // Variable für Leseergebnis
volatile unsigned char s[2]; // Var. für Bitdarstellung von 'read_data'
void init_INT2(void) {
GICR &= ~(1<<INT2); // INT2 deaktivieren
MCUCSR &= ~(1<<ISC2); // Bei fallender Flanke Interrupt aktivieren
GIFR |= (1 << INTF2); // Interrupt Flag setzen (s.S 67 ATMEGA32 Datasheet)
GICR |= (1 << INT2); // INT2 aktivieren
}
void init_prog(void) {
cli(); // Interrupts deaktiviert
i2c_init(); // Starte I2C Bus
lcd_init(); // Starte I2CLCD
lcd_command(LCD_CLEAR); // Leere Display
lcd_wait_ms(30); // Warte 3ms
}
void init_IO(void){
DDRB &= ~(1 << DDB2); // PB2 = Eingang für Interrupt
PORTB |= (1 << PB2); // internen Pull-Up an PB2 aktivieren
DDRD |= (1 << DDD7); // PD7 = Ausgang => LED 4
PORTD |= (1 << PD7); // PD7 = High => LED4 an
}
int main(void) {
cli(); // Interrupts deaktiviert
init_IO();
init_INT2();
init_prog();
sei(); // Interrupts aktiviert
while(1){
lcd_printlc(2,1,(unsigned char *)s);
}}
ISR(INT2_vect){
PORTD &= ~(1<<PD7); // PD7 = Low => LED4 aus
read_data = 0; // read_data zurücksetzen
i2c_start(adr1_r); // Starte Lesezugriff
read_data = i2c_readNak(); // read_data mit Leseergebnis beschreiben
itoa(read_data,s,2); // read_data als ASCII in s schreiben
}
24878
um ehrlich zu sein, verzweifel ich an meiner PCF8574-Schaltung. Die folgende Funktion sollte hier stattfinden:
Ein, am PCF8574 angeschlossener, Schalter wird gedrückt und zieht den entsprechenden Pin auf GND
Der PCF8574 löst daraufhin ein Interrupt aus und zieht das INT-Signal auf GND
Der Mikrocontroller erkennt das INT-Signal und springt zur entsprechende ISR
In der ISR wird der PCF ausgelesen und das Ergebnis für eine LCD Anzeige umgewandelt
Das LCD Modul sollte nun die ausgelesenen 8 Bit darstellen
Die LCD-Anzeige wird auch über I2C angesprochen, sie liefert aber kein INT-Signal zurück (das kann also keine Störung verursachen)!
Ich schaffe es, dass der Interrupt ein Auslesen anstößt und etwas, dass wie Bits aussieht, ausgibt. Drücke ich Taster 2, der am P6 des PCF8574 hängt, dann sollte ein "10111111" angezeigt werden. Das habe ich jetzt dreimal getestet und einmal habe ich ein "11011001", dann ein "00111111" und schließlich ein "11111111" erhalten. Nach dem letzten Ergebnis tillte die Anzeige völlig aus und zeigte, in rasender Folge, wirre Zeichen auf dem LCD-Display.
Hier der Code und die PCF8574 Schaltung und darunter der Schaltplan. Ich hoffe sehr, dass mir irgendjemand weiterhelfen kann, denn mittlerweile habe ich den Durchblick völlig verloren :(
#ifndef F_CPU //Wenn CPU-Takt nicht bereits definiert wurde...
#define F_CPU 16000000 //...dann definiere ihn auf 16MHz
#endif
#include "i2clcd.h"
#include "i2cmaster.h"
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char adr1_w = 0x42; // Device 1 write-address
volatile unsigned char adr1_r = 0x43; // Device 1 read-address
unsigned char read_data; // Variable für Leseergebnis
volatile unsigned char s[2]; // Var. für Bitdarstellung von 'read_data'
void init_INT2(void) {
GICR &= ~(1<<INT2); // INT2 deaktivieren
MCUCSR &= ~(1<<ISC2); // Bei fallender Flanke Interrupt aktivieren
GIFR |= (1 << INTF2); // Interrupt Flag setzen (s.S 67 ATMEGA32 Datasheet)
GICR |= (1 << INT2); // INT2 aktivieren
}
void init_prog(void) {
cli(); // Interrupts deaktiviert
i2c_init(); // Starte I2C Bus
lcd_init(); // Starte I2CLCD
lcd_command(LCD_CLEAR); // Leere Display
lcd_wait_ms(30); // Warte 3ms
}
void init_IO(void){
DDRB &= ~(1 << DDB2); // PB2 = Eingang für Interrupt
PORTB |= (1 << PB2); // internen Pull-Up an PB2 aktivieren
DDRD |= (1 << DDD7); // PD7 = Ausgang => LED 4
PORTD |= (1 << PD7); // PD7 = High => LED4 an
}
int main(void) {
cli(); // Interrupts deaktiviert
init_IO();
init_INT2();
init_prog();
sei(); // Interrupts aktiviert
while(1){
lcd_printlc(2,1,(unsigned char *)s);
}}
ISR(INT2_vect){
PORTD &= ~(1<<PD7); // PD7 = Low => LED4 aus
read_data = 0; // read_data zurücksetzen
i2c_start(adr1_r); // Starte Lesezugriff
read_data = i2c_readNak(); // read_data mit Leseergebnis beschreiben
itoa(read_data,s,2); // read_data als ASCII in s schreiben
}
24878