Hallo Forumsgemeinde,
Ich bin ein AVR Greenhorn, dass mit C und einem ATmega8 zur Zeit am
experimentieren ist.
Mein Problem sieht zur Zeit wie folgt aus:
Ich arbeite mich in die Region der Timer vor.
Timer1 bekomme ich ohne weitere Probleme initialisiert und zum laufen.
Mein Programm überprüfe ich mit einem LCD Display.
Ich habe in meinem Programm mehrere Taster mit eingebaut. Die
Eingangspins, wo die Taster angeschlossen sind, sind auf Eingang
geschaltet mit aktivierten Pullups. Der zweite Kontakt der Taster auf
GND.
Ich frage sie dann wie folgt ab
1
if(bit_is_clear(PINC,5))
2
{
3
Tuewas;
4
}
Das Problem ist nun, dass die Taster in einem etwas größeren Programm
absolut nicht auf Tasterdruck, mehr auf Zufall reagieren.
Aus diesem Grund wollte ich die Taster über Timer laufen lassen, sodass
sie innerhalb von ca. 10-50 ms, also direkt auf Tastendruck reagieren
Wenn ich allerdings Timer 0 oder Timer 2 initialisiere, habe ich keine
Anzeige mehr auf meinem LCD Display.
1
SIGNAL(SIG_SIG_OVERFLOW2)
2
{
3
TCNT2=244;// Auf 1 ms
4
countTimer2++;
5
}
6
.
7
.
8
.
9
TCCR2|=(1<<CS22);// Prescaler von 64
10
TCNT2=244;// Vorladen
11
TIMSK|=(1<<TOIE2);// Interrupts aktivieren und damit Timer starten
12
sei();
Warum läuft dann mein LCD Display nicht mehr???
1
// LCD control cmmands
2
#define LCD_CLEAR 0x01 // Display löschen
3
#define LCD_HOME 0x02 // Home Zeiger
4
#define LCD_ON 0x0C // Zeiger auf On
5
#define LCD_OFF 0x08 // Display auf off
6
#define POS_01 0x80 // Zeile 1
7
#define POS_02 0xC0 // Zeile 2
8
// Definitionen der Ports
9
#define LCDPORT PORTD
10
#define LCDDDR DDRD
11
#define LCD_PIN_RS 0
12
#define LCD_PIN_E 3
13
#define LCD_PIN_D4 4
14
#define LCD_PIN_D5 5
15
#define LCD_PIN_D6 6
16
#define LCD_PIN_D7 7
17
18
#define COMMAND 0
19
#define DATA 1
20
21
voidtoggle_enable_pin(void)
22
{
23
sbi(LCDPORT,LCD_PIN_E);cbi(LCDPORT,LCD_PIN_E);
24
}
25
26
voidlcd_send(unsignedchartype,unsignedcharc)
27
{
28
unsignedcharsic_c;
29
30
// High nibble senden
31
sic_c=c;// c Original speichern
32
sic_c&=~0x0f;// Bit 0-3 setzen
33
if(type==DATA)sic_c|=(1<<LCD_PIN_RS);// RS auf 1 setzen
34
LCDPORT=sic_c;toggle_enable_pin();// High nibble senden
35
36
// Low nibble senden
37
sic_c=c;// c Original speichern
38
sic_c=sic_c<<4;// Nibbles austauschen
39
sic_c&=~0x0f;// Bit 0-3 setzen
40
if(type==DATA)sic_c|=(1<<LCD_PIN_RS);// RS auf 1 setze
Eine andere Möglichkeit, die ich mir überlegt habe ist, einen Pin
abzufragen und sobald eine steigende Flanke an diesem Pin erfasst wird,
dass daraufhin ein Interrupt ausgelöst wird und ich darauf dann
reagieren kann.
Ich hoffe ihr könnt mir in Sachen zweiter Timer, sodass mein LCD Display
noch läuft und das Tasterproblem ein wenig weiterhelfen.
Vielen Dank schon mal im vorraus
Die Timer startest du aber erst nach der LCD-Initialisierung ?
LCD und Taster teilen sich den gleichen Port ?
Was macht die Interrupt-Routine von Timer 0 ?
Nein, darauf habe ich nicht geachtet!!! Darf ich Timer erst nach dem LCD
Display initialisieren???
Nein, das LCD Display ist an Port D und die Taster an Port C
Die sieht wie bei Timer 2 aus, oder was meinst du??
> SIGNAL(SIG_SIG_OVERFLOW2)
Den Vektor gibt es nicht. Deswegen führt das Programm beim Auftreten des
ersten Interrupts einen (Software-)Reset aus.
1. heisst der Vektor SIG_OVERFLOW2
2. hat der Compiler dir mitgeteilt, daß er deinen Vektor nicht kennt
3. sind Warnings nicht zum ignorieren da
4. ist diese Bezeichnung obsolet. Sondern man benutzt
ISR(TIMER2_OVF_vect)
mfg.
Nee der Compiler hat nicht gemeckert, noch nicht mal ein Warning
ausgegeben....
.....ich versuche das ganze jetzt mal mit ISR und dann erstatte ich
Bericht
Mal nebenbei: Es ehrt dich ja, das du das Rad neu erfinden möchtest,
aber ist es wirklich sinnvoll, auf das gesammelte Wissen, das z.B. in
Peter Fleurys LCD Library eingebaut ist, zu verzichten und stattdessen
das alles neu zu erfinden (mit dem Potential auf alle möglichen
Seiteneffekte)?
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs
Auch die Tastenabfrage ist nach PeDas Entprellroutinen eigentlich
erschlagen:
http://www.mikrocontroller.net/articles/Entprellung
Gerade als Anfänger ist es hilfreich, anderen über die Schulter zu
schauen.
Danke schön, ich schaue es mir gleich mal an....
Naja, das Rad vielleicht nicht wieder neu erfinden, aber man sollte das
auch verstehen was man macht und das bekommt man durch nur kopieren
nicht hin .....
Das ist sehr fehlerträchtig. Wenn du dir mal das Datenblatt des HD44780
anschaust, siehst du, das die Enable Zykluszeit 1000ns ist, d.h. 1µs. Du
erwähnst nirgends den Takt deines MC, aber wenn der z.B. 8 MHz ist, dann
erzeugst du mit der o.a. Routine gerade mal einen Puls von ca. 0,125 µs.
Das kriegt das LCD natürlich nicht mit.
Sepp Mayer schrieb:> aber man sollte das> auch verstehen was man macht und das bekommt man durch nur kopieren> nicht hin
Ja, aber dann doch gleich richtig. Du kopierst ja nicht nur, du kannst
es dir ja auch anschauen, verstehen, adaptieren - vllt. sogar
verbessern. Die Routinen sind tausendfach bewährt und zumindest Peter
Fleurys Lib ist soweit ich sie schon gequält habe, einfach wasserdicht.
Ja ich betreibe ihn mit 8 MHz.....allerdings funktioniert das Ganze mit
Timer1 ohne Probleme....
....sobald ich einen anderen Timer initialisiere gibt das LCD nur
schwarz aus in der ersten Zeile
Ich habe mir deinen Code jetzt nicht ganz durchgelesen, aber vielleicht
hilft dir das trotzdem:
Ich hatte ein ähnliches Problem, bei dem ein Display nicht mehr
funktionierte, sobald ich Timer / andere Interruptquellen benutzte. Die
Lösung war dann ein atomares Ausführen des Display Codes, welche
verhindert, dass ein Interrupt die Ausgabefolge zum Display zerschiesst.
Also versuche doch einfach mal mit einem
cli();
*display-update-code
sei();