mefiX
24.09.2007, 01:49
Hallo Zusammen,
ich bastle an einem Füllstandsmesser mit einem Atmega8, einem 16x2 LCD und dem SRF02-Ultraschallmodul.
Ich poste hier, weil nicht genau klar ist, ob es sich um ein Hardware- oder Sofwtare-Problem handelt.
Die Kommunikation zwischen Controller und PonyProg klappte schon perfekt, ich habe die CPU bereits mehrmals ausgelesen und beschrieben.
Die I2C-Kommunikation klappte auch schon perfekt, ich hatte schon die Entfernung auf dem LCD-Display.
Softwareseitig benutze ich die Bibliotheken von Peter Fleury (http://jump.to/fleury) für das LCD und I2C.
Ich habe jetzt schon 3 Atmegas geschrottet (denke ich zumindest), die jeweils zuletzt mit folgendem Code geflasht wurden:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "delay.h"
#include "lcd.h"
#include "i2cmaster.h"
#define SRF02_ADDRESS 0xE0
#define HEIGHT 400
#define RADIUS 100
/* SRF02 - Get Distance in cm. */
unsigned int read_cm(unsigned char address)
{
unsigned char lowbyte,highbyte;
unsigned int distance;
i2c_start_wait(address+I2C_WRITE);
while (i2c_write(0));
while (i2c_write(81));
i2c_stop();
i2c_start_wait(address+I2C_WRITE);
while (i2c_write(2));
i2c_stop();
delayms(65);
i2c_start_wait(address+I2C_READ);
highbyte = i2c_readAck();
lowbyte = i2c_readNak();
distance = (highbyte*256)+lowbyte;
i2c_stop();
if(distance > 150)
{
PORTD = 0x00;
}
return distance;
}
int main(void)
{
char buf[16];
unsigned dist;
double fill_percent;
i2c_init();
DDRD &=~ (1 << PD2); /* Pin PD2 input */
PORTD |= (1 << PD2); /* Pin PD2 pull-up enabled */
DDRB |= (1 << PB0); /* enable B0 as output (Toggle-LED!) */
/* initialize display, cursor off */
lcd_init(LCD_DISP_ON);
for (;;) {
//PORTB ^= (1<<PB0);
// Start Distance Measurement
PORTB &= ~(1 << PB0);
dist = read_cm(SRF02_ADDRESS);
PORTB |= (1 << PB0);
/* clear display and home cursor */
lcd_clrscr();
fill_percent = 100 - ((double) dist / HEIGHT * 100);
sprintf(buf, "Proz: %d", (int)fill_percent);
lcd_puts("Fuellstand:\n");
lcd_puts(buf);
delayms(3000);
}
}
Die Funktion read_cm liest dabei zyklisch die Distanz vom SRF02-Modul.
Aktuell bootet der Controller nicht mehr, aber ich habe den Effekt, dass mit externem 4MHz Quarz ODER Quarzoszillator der Chip nach Einschalten der Spannung für kurze Zeit arbeitet, dann wieder einfriert (LED blinkt dann schneller, weil vorher 1MHz per _F_CPU eingestellt war!).
Ich habe auch schon versucht, alle I2C-Komponenten aus der Schaltung zu lassen, das half leider auch nichts.
Kann man einen Programmiermodus durch manuelle Beschaltung erzwingen, sodass die CPU erst garnicht bootet, ich meine dabei den Modus, den PonyProg benutzt um die CPU zu flashen?
Bei der Beschaltung habe ich mich genaustens an die Tutorials hier im Wiki gehalten.
Das LCD betreibe ich im 4-Bit-Mode (DB0-3 auf GND; DB4-7 an Pins D4-7; RS an Pin D0, RW an D2, E an D1), die Ports und Pins habe ich in der lcd.h entsprechend eingetragen (funktionierte ja auch schon!).
Für den I2C-Bus habe ich die Hardware-Implementierung von Peter Fleury benutzt (i2cmaster.S). SDA und SCL habe ich mit einem Pullup-Widerstand von 4,7kOhm versehen. Zunächste dachte ich, den Wert des SRF02 alle 3 Sekunden abzufragen sei zu oft, aber ich denke daran liegt es eher nicht!?
Wo liegt mein Fehler?
Ich würde mich sehr über Hinweise freuen.
MFG,
mefiX
ich bastle an einem Füllstandsmesser mit einem Atmega8, einem 16x2 LCD und dem SRF02-Ultraschallmodul.
Ich poste hier, weil nicht genau klar ist, ob es sich um ein Hardware- oder Sofwtare-Problem handelt.
Die Kommunikation zwischen Controller und PonyProg klappte schon perfekt, ich habe die CPU bereits mehrmals ausgelesen und beschrieben.
Die I2C-Kommunikation klappte auch schon perfekt, ich hatte schon die Entfernung auf dem LCD-Display.
Softwareseitig benutze ich die Bibliotheken von Peter Fleury (http://jump.to/fleury) für das LCD und I2C.
Ich habe jetzt schon 3 Atmegas geschrottet (denke ich zumindest), die jeweils zuletzt mit folgendem Code geflasht wurden:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "delay.h"
#include "lcd.h"
#include "i2cmaster.h"
#define SRF02_ADDRESS 0xE0
#define HEIGHT 400
#define RADIUS 100
/* SRF02 - Get Distance in cm. */
unsigned int read_cm(unsigned char address)
{
unsigned char lowbyte,highbyte;
unsigned int distance;
i2c_start_wait(address+I2C_WRITE);
while (i2c_write(0));
while (i2c_write(81));
i2c_stop();
i2c_start_wait(address+I2C_WRITE);
while (i2c_write(2));
i2c_stop();
delayms(65);
i2c_start_wait(address+I2C_READ);
highbyte = i2c_readAck();
lowbyte = i2c_readNak();
distance = (highbyte*256)+lowbyte;
i2c_stop();
if(distance > 150)
{
PORTD = 0x00;
}
return distance;
}
int main(void)
{
char buf[16];
unsigned dist;
double fill_percent;
i2c_init();
DDRD &=~ (1 << PD2); /* Pin PD2 input */
PORTD |= (1 << PD2); /* Pin PD2 pull-up enabled */
DDRB |= (1 << PB0); /* enable B0 as output (Toggle-LED!) */
/* initialize display, cursor off */
lcd_init(LCD_DISP_ON);
for (;;) {
//PORTB ^= (1<<PB0);
// Start Distance Measurement
PORTB &= ~(1 << PB0);
dist = read_cm(SRF02_ADDRESS);
PORTB |= (1 << PB0);
/* clear display and home cursor */
lcd_clrscr();
fill_percent = 100 - ((double) dist / HEIGHT * 100);
sprintf(buf, "Proz: %d", (int)fill_percent);
lcd_puts("Fuellstand:\n");
lcd_puts(buf);
delayms(3000);
}
}
Die Funktion read_cm liest dabei zyklisch die Distanz vom SRF02-Modul.
Aktuell bootet der Controller nicht mehr, aber ich habe den Effekt, dass mit externem 4MHz Quarz ODER Quarzoszillator der Chip nach Einschalten der Spannung für kurze Zeit arbeitet, dann wieder einfriert (LED blinkt dann schneller, weil vorher 1MHz per _F_CPU eingestellt war!).
Ich habe auch schon versucht, alle I2C-Komponenten aus der Schaltung zu lassen, das half leider auch nichts.
Kann man einen Programmiermodus durch manuelle Beschaltung erzwingen, sodass die CPU erst garnicht bootet, ich meine dabei den Modus, den PonyProg benutzt um die CPU zu flashen?
Bei der Beschaltung habe ich mich genaustens an die Tutorials hier im Wiki gehalten.
Das LCD betreibe ich im 4-Bit-Mode (DB0-3 auf GND; DB4-7 an Pins D4-7; RS an Pin D0, RW an D2, E an D1), die Ports und Pins habe ich in der lcd.h entsprechend eingetragen (funktionierte ja auch schon!).
Für den I2C-Bus habe ich die Hardware-Implementierung von Peter Fleury benutzt (i2cmaster.S). SDA und SCL habe ich mit einem Pullup-Widerstand von 4,7kOhm versehen. Zunächste dachte ich, den Wert des SRF02 alle 3 Sekunden abzufragen sei zu oft, aber ich denke daran liegt es eher nicht!?
Wo liegt mein Fehler?
Ich würde mich sehr über Hinweise freuen.
MFG,
mefiX