Es gibt hier schon einige Implementierungen von Frequenzzählern, aber
ich habe noch keine reine Software-Implementierung eines reziproken
Zählers gesehen. Also habe ich mich selber daran gemacht :-)
Das ganze ist natürlich nur für eng begrenzte Anwendungsbereiche
sinnvoll.
Zu finden unter http://www.mshopf.de/proj/avr/freq_meter.html
Läuft auf einem ATtiny2313 mit einem Frequenzbereich von 0Hz..10MHz (bei
20MHz Takt), Auflösung bis 1e-6Hz bei maximal 10ppm
Wiederholungsgenauigkeit (relativer Fehler, absoluter Fehler hängt nur
vom Quarz ab).
Ein reziproker Frequenzzähler zählt sowohl die Zyklen des Systemtakts,
als auch die der 1-0-Übergänge des Eingangssignals. Der Zählerstart
erfolgt an einem 1-0-Übergang, und endet nach einer minimalen
Samplingzeit (500ms hier) wieder an einem 1-0-Übergang. Da das ganze in
Software realisiert wird, kann ein Interrupt zu genau dem falschen
Zeitpunkt die Genauigkeit reduzieren - das README erklärt, wie ich auf
die 10ppm komme. Die Berechnung ist nicht trivial, da könnten also auch
noch Fehler enthalten sein.
Nach dem Zählen hat man zwei Zahlen: n_CLK (Taktzahl bei einer
Taktfrequenz f_CPU) und n_EVT (Anzahl an 1-0-Übergängen). Die Frequenz
ergibt sich dann als:
f = n_EVT * f_CPU / n_CLK
Das ganze muss in Fixpoint-Arithmetik gerechnet werden - was mal eben
locker den Bereich einer 32-Bit Zahl sprengt. Die libgcc-Routinen für
64 bit Zahlen sind leider viel zu groß für einen ATtiny, deshalb habe
ich noch ein paar Spezialroutinen in Assembler geschrieben.
Zu finden unter http://www.mshopf.de/proj/avr/uint64_ops.html
* Bit Shifts (Ersparnis: ca. 200bytes vs. libgcc)
* Multiplikation 64bit x 32bit -> 64bit (Ersparnis über 200bytes in
Vergleich zu C, viele KB zu libgcc)
* Division 64bit / 32bit -> 64bit (Ersparnis über 150bytes in Vergleich
zu C, viele KB zu libgcc)
Der Code muss sich leider auf die Registerkonvention von
Funktionsaufrufen verlassen, weil gcc's asm() noch nicht mit
64bit-Registern klar kommt.
Hallo Matthias,
das finde ich ein klasse Projekt !
Wirst Du auch noch Frequenzteiler einbauen?
Z.B.
- MB506 2,4GHz Prescaler
- MB510 2,7GHz Prescaler
- U891BS 1,3 GHz 1: 64
- U813BS 1,1 GHz 1: 64/128/256
- TBB512AG 1:64/ 1:65
Man könnte den Teilungsfaktor über eine Spannungsbereich 0 - 5V an
einem ADC Port nach dem Reset einlesen.
z.B.: die Faktoren 1, 2, 4, 8, 10, 16, 32, 64, 100, 128, 144, 256, 272
Die Spannungsbereich wären dann U_bereich = 5V / (N+1) 'breit'.
Mit N=13 dann U_bereich = 0,3571V, das entspricht +73dec bei 10 Bit ADC
Auflösung.
Faktor 1: 0 - 73 ADC-Wert
Faktor 2: 74 - 147
Faktor 4: 148 - 221
usw.
Hier noch ein Beispiel:
http://www.liebl-net.dtdns.net/hard/frequ_counter/frequ_counter.php
Uwe
Bis jetzt habe ich noch nicht an Frequenzteiler gedacht, weil ich das
Projekt vor allem als Basis für andere verwenden will (z.B.
kapazitativen Füllstandsmelder etc.).
Sollte sehr einfach sein, einen Teiler anzuflanschen - die Auto-Range
Funktion wird dann noch etwas Arbeit vertragen. ;-)
Durch das Messverfahren sind auch gar nicht mehrere Teilungsfaktoren
nötig, einer (z.B. 256) reicht völlig - solange die Frequenz nicht unter
ca. 10Hz fällt und damit das Sampling verlangsamt :-P
Man braucht dann noch einen Switch der schnell genug ist um 10MHz
Signale durchzulassen - HCT sollte das sein. Es sei denn, Dir fällt ein
Teiler ein, den man auf Durchzug stellen kann.
Theoretisch(!) könnte man die Unterscheidung auch in Software machen
(die Funktionalität der beiden Counter vertauschen indem man das
ungeteilte Signal an T0/INT0 und das geteilte Signal an T1/INT1
anschliesst und nur eine Kombination auswertet), aber das würde die
Interrupt-Händler doch deutlich verkomplizieren. Hm, vielleicht doch
machbar. Mal gucken. Ich wollte die eh' noch in Assembler schreiben, um
die Wiederholgenauigkeit noch weiter hochzudrehen :-)
Hallo,
ein klasse Modul, schön zu sehen, dass man es auch mit einer reinen
Softwarelösung in sehr brauchbarer Genauigkeit hinbekommt.
Wegen der Geschichte mit einem Vorteiler würde ich gerne meine Idee
beisteuern. Ich bin gerade dabei einen Frequenzzähler nach gleichem
Messprinzip aufzubauen, allerdings habe ich die reine Softwarelösung
wegen der angesprochenen IRQ Problematik für mich verworfen. Bei meinem
Zähler wird die Synchronisation zwischen der Messzeit und dem
Eingangssignal mit TTL gemacht. Danach kommt ein "Vorzähler", der nach
der Messung ausgelesen wird. Dadurch kann man ohne Umschaltung und mit
nur einer SW Routine den gesammten Bereich von 0,1 HZ bis ca. 100MHz
(bisher nur 66MHz ausprobiert) messen. Ich bekomme mit dieser Schaltung
sehr stabile Ergebnisse, z.B. 6 Stellen Stabil bei 0,1 s Messzeit über
den ganzen Messbereich.
Habs leider nur als pdf dabei.
Grüße
Ales
Klar, wenn man eh' zusätzliche Hardware wie Teiler braucht kann man auch
noch die zwei Logikchips hinzufügen. Ich wollte halt alles vermeiden
soweit möglich, und für meine Anwendungszwecke sind 10MHz meistens
ausreichend |-)
Das mit "auslesbaren Teiler" ist auch 'ne nette Idee :-)
Für meinen Fall nur übertrieben, weil die Quarze eh' genügend Drift
haben (auch wenn ich aus den Datenblättern bzgl. Kurzzeitstabilität und
Jitter noch nicht schlau geworden bin).
Noch ein Hinweis: Mir ist gerade aufgefallen, dass die Berechnung der
Wiederholgenauigkeit noch einen entscheidenden Faktor vermisst - 10ppm
sind bei der momentanen Implementierung zu optimistisch (wenn auch die
Fehler nur sporadisch wg. Interrupts auftauchen).
Ich muss das noch anpassen, und dann die Interrupt-Handler in Assembler
schreiben (und weitere Interrupts auch dort erlauben - in dem Fall ist
das möglich).
So, Berechnung gefixed - es hat sich herausgestellt, dass ich sogar zu
pessimistisch war, der Worst Case konnte so gar nicht eintreten
(Nebenbedingungen konnten nicht erfüllt werden).
Fehler war schon immer < 8ppm.
Außerdem habe ich jetzt noch die Timer Overflow Interrupts in Assembler
geschrieben und kann daher Interrupts gleich wieder erlauben. Das
reduziert die potentiell fehldetektierte Phase, und der maximale
relative Fehler ist jetzt bei 2.5ppm :-)
Hallo Matthias,
so jetzt geht auch mein Accout wieder.
Ich habe hier noch einen ATMega32 Board mit etwas anders beschalteten
LCD-Display Pins.
Und so habe ich mich dran gemacht die Quellen an zu passen.
Ich hänge mal ein diff der beiden Quellen an und hoffe man kann den Code
noch korrigieren.
Danke.
Das Prinzip hat Peter Dannegger schon 2005 vorgeschlagen:
"Man mißt einfach die Perioden über eine gewisse Zeiteinheit und hat
somit immer die gewünschte Auflösung völlig unabhängig von der
Frequenz.
Ich starte die Messung mit einer 1-0-Flanke des Eingangssignals, dann
zähle ich die Perioden über eine Mindestzeit (z.B. 0,5s) und dann
stoppe ich mit der nächsten 1-0-Flanke. Nun habe ich die Periodenanzahl
und die Anzahl der CPU-Zyklen über diese Periodenanzahl:
f_X = f_CPU-Zyklus * Periodenzahl / Zyklenzahl
Und fertig ist die Eingangsfrequenz."
Siehe Beitrag "Frequenzzähler eigenbau"
@Jupp:
Ja, das Messprinzip ist uralt - Mitte letztes Jahrhundert würde ich
vermuten. Ich habe keine gute Erklärung im Forum auf die Schnelle
gefunden, danke für die Referenz!
@Uwe:
Die ersten paar Deiner Änderungen sind ja Konfigurationsänderungen, also
lokal für Dich. Die Änderungen für den ATmega muss ich mir nochmal
genauer angucken, danke schon mal! Ich hatte ja schon vermutet, dass
ATmega (noch) nicht geht.
P.S. Nächstes mal den diff bitte mit -up erstellen - das erleichtert die
Kontext-Suche ungemein und unified diff ist einfacher zu lesen.
Ausserdem ist es nie zu spät für Fixes :-)
BTW - wenn jemand eine bessere Idee hat als nach AVR_ATtiny2313 und
AVR_ATtiny2313A zu überprüfen (z.B. Familie?), immer her mit der
Information.
@Uwe:
Ich habe Deinen Patch als Basis genommen, das Teil fuer ATmega8 und
ATmega48 kompatibel zu machen. War zwar eigentlich gar nicht schwer,
aber...
Da bei den ATmegas ja nicht 7 pins an einem Port frei sind, habe ich die
LCD-Routinen noch aufgebohrt, um zwei verschiedene Ports für Daten- und
Kontroll-Pins benutzen zu können. Natürlich habe ich die Änderung erst
gemacht nachdem ich die Schaltung für den ATmega geändert habe.
Dabei habe ich es dann geschafft, einen Pin des ATmega8 bei Stecken auf
das Steckbrett umzubiegen - das Debugging hat dann Stunden gekostet
:-/
Hallo Matthias,
vielen Dank !
Ich habe gerade noch andere Projekte ab zu schließen und werde dann
sofort durchstarten, erst mal mit dem ATmega32 Board, dann später mit
einer ATmega8x-20 Lösung.
Hallo Matthias,
hier ein Schaltplan für den ATmega88-20PU mit den neuen Anschlüssen für
ein LCD-Display.
LCD R/#W braucht man i.a. gar nicht.
Verwendet Du die Steuerleitung ?
Ich lasse sie häufig einfach weg, wenn ich nur das LCD-Display
beschreiben will.
Das Busy-Flag des HD44780 Kontrollers werte ich nicht aus, sondern
arbeite mit Wartezeiten.
Die LCD-Routinen sind lose auf Dick Streefland's Routinen basiert - und
er wartet auf das BUSY flag. Theoretisch haben die den Vorteil, dass
sie weniger Zeit brauchen. Praktisch sollte es egal sein.
Ich hatte auch schon mal nur Timeout-basierte Routinen, vielleicht
benutze ich die auch mal wieder. Könnten auch weniger Platz benötigen.
Ich mache es gern so das das LCD 1:1 im RAM liegt. Das Display wird dann
in einer ISR aktualisiert. Einfach den RAM Wert +30h auf das Display
augeben.
Sind bei 4x16 alle 4ms ein Zeichen bei 4 Aktualisierungen/Sekunde.
Sofern man genügend RAM hat.
Hallo Matthias,
ich habe jetzt meine Schaltung auf eine Platine gelötet und mit einem
ATmega48-20 mit 20Mhz SMD Quarz bestückt.
Entgegen meinem Schaltplan ist ein AVR ISP-10 Pol Stecker montiert, da
mein usbasp auch damit ausgestattet ist.
Zur LED; die ist doch nun an Port B Pin 0 an zuschließen ?
1
// main.c
2
#define LED_PORT PORTB
3
#define LED_DDR DDRB
4
#define LED_BITS (1<<0)
Ich verwende ein LCD-Display mit 2x 16 Zeichen.
Was muss denn in
1
// main.c
2
#define LCD_LINES 2 // 1 or 2 lines
3
#define LCD_COLS 16 // 10col display (2*5) - only required for wrap
stehen?
Mit diesen Angaben sehe ich viele blinkende Zeichen in der zweiten Zeile
?!
In der ersten Zeile steht an Pos 15 [0,..15] auch ein "?" - komisch.
Mit offenen Eingang zählt er schön die 50. Hz Schwingungen...
Ich sehe immer in der zweiten Zeile:
1
Hz_s0.19305____O
"_" sind Leerzeichen und unter dem "O" seht der blinke Kursor.
Soll das so sein ?
Hallo Matthias,
ich habe noch einige kleine Änderungen am code vorgenommen, so dass nun
meine Anzeige nicht mehr spinnt!
Mit 20MHz Takt ist wohl das LCD-Display aus dem tritt gekommen.
Mehr siehe Anlage.
Stephan Henning schrieb:> Ich mache es gern so das das LCD 1:1 im RAM liegt. Das Display wird dann> in einer ISR aktualisiert. Einfach den RAM Wert +30h auf das Display> augeben.
Klar. Nur sind die Interrupts in diesem Fall schon gut belegt :-)
> Zur LED; die ist doch nun an Port B Pin 0 an zuschließen ?
Wo Du willst. B0 war bei mir noch frei :-)
Die LED ist eh' nur fuers Debugging.
> Ich verwende ein LCD-Display mit 2x 16 Zeichen.
In dem Fall kannst Du Dir überlegen, ob Du nicht Hz noch an die Zahl in
der 1. Zeile angehängt haben willst, und die 2. Zeile für was anderes
aufhebst.
> Mit 20MHz Takt ist wohl das LCD-Display aus dem tritt gekommen.
Ich hatte es befürchtet :-(
Zu meiner Schande muss ich gestehen, dass ich 20MHz mangels Quarz nie
getestet habe. Die Zeiten in den LCD-Routinen werden wohl noch nicht
alle eingehalten. Kann auch an parasitären Kapazitäten liegen.
> ich habe noch einige kleine Änderungen am code vorgenommen,> mehr in der Anlage.
Zumindest die Protokolländerung ist definitiv falsch. Tipp: schau Dir
das 0x32 mal an, wenn Du annimmst, dass das Interface im 8bit Modus
initialisiert ist. -> 0x30, 0x20 -> Interface ist jetzt(!) im 4bit
Modus.
Das setzen in den 8bit Modus (0x30) mehrmals davor ist nötig, weil sonst
die Synchronisation nicht funktioniert (low- und hi-nibble können nicht
unterschieden werden).
Im Übrigen ist das die Standard-Initialisierungssequenz, und steht so
sogar im Datenblatt.
Ich verstehe nicht, warum Deine Sequenz überhaupt funktioniert. Die
sollte entsprechen:
write4 0x3 -> Interpretiert im 8bit-Mode: 0x30 -> Switch in 8bit
write 0x28 -> 0x2 Interpretiert im 8-bit-Mode: 0x20 -> Switch in 4bit
0x8 Interpretiert im 4-bit-Mode als Hi Nibble
-> off by one Nibble.
Und davon erholt sich das Protokoll auch nicht mehr. Warum es trotzdem
geht? Keinen blassen Schimmer...
Das 1. lcd_clear() sollte nicht nötig sein, laut Datenblatt wird beim
init das RAM gelöscht. Kannst Du das mit Deinem Display verifizieren?
Kann natürlich sein, dass sich verschiedene Kontroller verschieden
verhalten...
Hallo Matthias,
Das ist ja auch kein Glaubenskrieg mit der LCD-Initialisierung.
Ich verwende dieses Schema, siehe Seite 46.
Mir ist das aufgefallen, als ich ein 1x16 Zeichen Display angeschlossen
hatte und dies - nach Anpassung der Firmware - doch im Modus 2 zeiliges
Display initialisiert wurde.
Dafür habe ich dann in der Funktion
1
voidlcd_init(void)
die Zeile
1
lcd_write(0x32);// Switch to 4-bit mode
ausgemacht.
Mein LCD-Display hat den HD44780 von Hitachi drauf !
Auch kann die Zeile
1
/* Init LCD */
2
lcd_init();
entfernt werden.
Steht schon in der Funktion
1
voidlcd_init(void)
.
Vielleicht übernimmst Du die wichtigsten Änderungen in die nächste
Version?
Uwe S. schrieb:> Das ist ja auch kein Glaubenskrieg mit der LCD-Initialisierung.> Ich verwende dieses Schema, siehe Seite 46.
Tja, genau das machst Du ja leider nicht, siehe mein Kommentar oben :-)
Auf Seite 46 steht:
wait 15ms, 4bit 0x3, wait 4.1ms, 4bit 0x3, wait 100us, 4bit 0x3, 4bit
0x2,
- Ab jetzt busy flag checken
2x4 bit 0x28, alle weiteren Befehle 2x4bit von nun an.
0x28 nur bei 2-zeiligen Displays. Bei einzeiligen 0x20.
Das macht genau
1
_delay_ms (15.0);
2
lcd_write4 (3);
3
_delay_ms (4.1);
4
lcd_write4 (3);
5
_delay_ms (0.1);
6
lcd_write (0x32); // Switch to 4-bit mode
7
lcd_write (0x20 + // Function set: 4-bit mode + #lines
8
(LCD_LINES-1)*0x08);
das lcd_write(0x32) macht lcd_write4(0x3), lcd_write4(0x2),
wait-for-busy.
> Mir ist das aufgefallen, als ich ein 1x16 Zeichen Display angeschlossen> hatte und dies - nach Anpassung der Firmware - doch im Modus 2 zeiliges> Display initialisiert wurde.
Na kein Wunder, wenn Du LCD_LINES nicht auf 1 setzt ;-)
Oder hast Du das mit Anpassung gemeint?
Das einzige, was mir einfällt wenn das bei Dir immer noch nicht gehen
sollte: Probiere:
1
lcd_write4 (0x3);
2
_delay_ms (0.1);
3
lcd_write4 (0x2);
4
_delay_ms (0.1);
statt dem lcd_write (0x32);
Das verhindert die Busy-Flag-Abfrage für diesen einen Befehl.
> Mein LCD-Display hat den HD44780 von Hitachi drauf !
Standard. Ich wage nur zu bezweifeln, dass er wirklich von Hitachi ist
- da gibt es sooo viele Nachbauten :-)
> Auch kann die Zeile
1
/* Init LCD */
2
lcd_init();
> entfernt werden.> Steht schon in der Funktion
1
voidlcd_init(void)
.
?!? Das eine ist die Definition, das andere der Aufruf...
> Vielleicht übernimmst Du die wichtigsten Änderungen in die nächste> Version?
Die Zeiten in lcd_{read,write}4 überprüfe ich auf alle Fälle nochmal!
Deine Änderungen sind schon mal ein guter Start, aber ich befürchte,
dass andere Timings auch nicht eingehalten werden und nur zufällig gehen
:-]
Hallo Matthias,
ich habe den Code Version 1.2 noch ein wenig erweitert.
Wie schon in einer E-Mail berichtet, gehen meine Bestrebungen in
Richtung Amateurfunk, deshalb ist die Skalierung der Anzeige in "kHz",
"MHz" und "GHz" durch die Definition der folgender Konstanten möglich:
1
#define FREQ_KHZ
2
// #define FREQ_MHZ
3
// #define FREQ_GHZ
Werden die Defines nicht gesetzt, so wird wieder "Hz" angezeigt und
gerechnet.
Die benötigten Definitionen und Strings sind in
Seinerzeit gab es nur AT90S2313 mit 10MHz, sodass darauf basierend
folgende Schaltung entstand:
http://www.mino-elektronik.de/fmeter/fmeter.htm
Meines Erachtens war (und ist) es sinnvoller, einen externen Vorteiler
automatisch hinzuzuschalten, der nichts kostet und gleich zig MHz
verarbeiten kann.
Heute kann man bequem einen ATmega168-20 nehmen und braucht sich um
Speicherplatz keinen Kopf zu machen.
Für einfache Anwendungen reicht auch das Beispielprogramm:
http://www.mino-elektronik.de/fmeter/fm_software.htm
Viel Spatz!
Hallo,
ich habe für meine Anwendung eine erweiterte Schaltung entwickelt und
eben so die Basissoftware von Matthias angepasst und erweitert.
Es gibt 2 Kanäle, K1 misst bis 39 Mhz, K2 bis 2.700Mhz.
Ein 1:4 Vorteiler 74HC74 und eine Kanalumschaltung mit
Signalaufbereitung 74HC132 sitzt vor dem ATmega48.
Der 74HC74 sorgt, mit seiner 1:4 (Vor-)Teilung, für ein sauberes 50%:50%
Signal am ATmega48 20Mhz, daraus ergibt sich dann auch die maximale
Messfrequenz von K1.
Die maximale Messfrequenz von 2.700Mhz werden mit deinem MB510, 1:128
Teiler erreicht und er verkraftet mit einem 3dB Pad +13dBm Pegel am
Eingang. Von den 2.700Mhz liegen am ATmega48 nach Teilung nur 2.700Mhz/
512 = 5,2734MHz an!
Software Funktionen
* Das Anzeigenformat kann mit dem 2-pol Dip-Schalter zwischen Hz, kHz,
MHz und GHz gewählt werden.
* Die Kanalumschaltung erfolgt mit einem Taster.
* Die Voreinstellung der Teilungsfaktoren mit zwei der drei 10kR
Trimmer.
* Der dritte Trimmer ist für die Anzeige von Mode
("FAX","FSK","LSB","USB","CW ","FM ","AM ") vorgesehen.
Ihr seht in den Bildern die nicht kalibrierte Messungen bis 200 MHz und
der Eingangspegel beträgt dabei zwischen +6dBm und 0dBm.
Einige der HF-Bauteile sind SMD1206 und auf der Platinenunterseite zu
finden.
.
Uwe S. schrieb:> Ich verwende dieses Schema, siehe Seite 46.
Da ist leider ein Fehler drinn.
Vor dem letzten Kasten mit den 5 Instruktionen muß auch nochmal 100µs
gewartet werden, damit der Befehl ausgeführt wird.
Peter
Matthias Hopf schrieb:> Stephan Henning schrieb:>> Ich mache es gern so das das LCD 1:1 im RAM liegt. Das Display wird dann>> in einer ISR aktualisiert. Einfach den RAM Wert +30h auf das Display>> augeben.>> Klar. Nur sind die Interrupts in diesem Fall schon gut belegt :-)
klar, aber dafür gibts ja ein Interrupt Prioritätenregister.
Wenn man eins hat. :-)
Noch immer leider EBUSY. :-/
Wenn Du einen tarball mit Deinem Source hier einstellen willst, nur zu!
Deine Patches sind nicht verloren, nur muss ich nur mal wieder einen
Timeslot fuers Hardware- und Softwarebasteln finden, und da sieht's bis
zum Jahresende schlecht aus :-(
Hallo allerseits,
beim kompilieren der oben genannten main.c erscheint jedesmal die
Warnung: internal compiler error: in start_function, at c-decl.c:6035
Kann mir jemand helfen?
Danke schon mal im voraus.
Besucher schrieb:> Warnung: internal compiler error: in start_function, at c-decl.c:6035>> Kann mir jemand helfen?
Mit diesen Angeben: Nein.
Geraten: wirf das Attribut von main() raus.
Falls das nicht hilft: übersetzte zusätzlich mit den Compiler-Schaltern
-v -save-temps -g3
und poste hier das main.i sowie die Kommandozeilen-Ausgabe vom avr-gcc.
Hallo Johan,
hier die main():
extern int main (void)
{
uint8_t i;
char buf[16];
enum {FREQ_ID_HZ=0, FREQ_ID_KHZ, FREQ_ID_MHZ, FREQ_ID_GHZ};
const char *a_freq_text[] = {" Hz","kHz","MHz","GHz"};// 20100825
-us
const char *c_freq_text = a_freq_text[FREQ_ID_HZ];
usw.
Übrigens die komplette Datei ist unter 'freq_meter-20100825.zip' von Uwe
S. zu finden
Gruß
Hallo Bingo,
ich habe nicht ganz verstanden was du mit
>Probiere die "avr-gcc -v" kommando
meinst. Ich kompiliere mit 'Programmer's Notepad' v2.0.7.667-devel
mfg
Hallo Gast, ein Name wäre schön.
es geht uns um die gcc-avr version, so heisst der AVR "C" Compiler und
mit dem Aufruf "avr-gcc -v" erhält man eine Versionsnummer.
Ich habe auch unter ubuntu "gcc-Version 4.3.4 (GCC)"
Unter welchem BS arbeitest Du, ich denke mit dem Hinweis "Programmer's
Notepad" ist es ein Win*OS ?
.
Hallo Michael D.,
ich antworte lieber hier, wo es hingehört.
Ja ich habe nach einem Jahr das gesamte Programm umgestellt, teilweise
neu geschrieben und die LCD-Routine gegen die von Peter Fleury
getauscht.
Title : HD44780U LCD library
Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
File: $Id: lcd.c,v 1.14.2.1 2006/01/29 12:16:41 peter Exp $
Danach hatte ich keinerlei Probleme mehr !
Nun bedient die Firmware 2 Eingangskanäle; über einen Taste, kann man
den Kanal wechseln - kurz Drücken - und die Anzeige zwischen Hz, kHz,
MHz und GHz umschalten - lang Drücken -.
Es gibt getrennte Prescaler E {1,64,128,256} für jeden Kanal, die über
Jumper gesetzt werden.
Und über die serielle Schnittstelle mit 19200 Baud,8,N,1 werden alle
Messwerte ausgegeben und lassen sich auch die Kanäle "1","2" und die
Einheiten mit "h","k","m","g" umschalten.
In der zweiten Zeile wird noch die Spannung an ADC0 (0-5V), über 64
Werte gemittelt, als Bargraph aus gegeben.
Das war's so weit.
.
Hallo Uwe,
danke dass Du Dich noch um das Projekt kuemmerst :-)
Ich habe den Job gewechselt, und jetzt leider erst mal noch weniger
Zeit als bisher fuer solche Sachen :-/
Die LCD-Routinen von Peter Fleury werde ich mir auf jeden Fall mal
ansehen - es wurmt mich immer noch, dass ich nicht verstehe, warum meine
Funktionen bei Dir nicht funktioniert haben...
Danke nochmal!
Hallo Matthias,
Du hast ja meine Quellen, damit sollte es einfach sein, einen Vergleich
zwischen beiden Libs zu machen.
Gerade stelle ich einen - für mich - endgültigen Schaltplan zusammen und
dann geht's an das Platine layouten.
Matthias Hopf schrieb:> Die libgcc-Routinen für> 64 bit Zahlen sind leider viel zu groß für einen ATtiny, deshalb habe> ich noch ein paar Spezialroutinen in Assembler geschrieben.
Da könnte das hier helfen:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=113673
Ich habs bei AVRFreaks reingestellt, weil man da noch editieren kann bei
Fehlern oder Erweiterungen.
Peter
Hallo Peter,
nochmals danke für den 64-Bit Code, denn nun weiter verbessert hast ?!
Ich habe die 64-Bit Lib in mein Projekt eingefügt und die alten Aufrufe
durch zwei Macro ersetzt.
Damit bleibt das Programm das selbe und ein Vergleich ist einfach
möglich.
Da ich im Augenblick den atMega48 mit 4k im Frequenzzähler benutze, war
der Flash-Speicher mit aktivierter uart0 lib (PeDa) nicht mehr
ausreichend.
Nach deaktivieren konnte ich den Code testen.
Hier noch der Speicherbedarf:
Hallo Peter,
das dachte ich auch am Anfang, aber das wird wirklich beides mal als
Konstante berechnet und verwendet.
Mein Workaround habe ich deshalb wieder gelöscht..
Auszug aus main.lst
Uwe S. schrieb:> Hier noch der Speicherbedarf:// 64-Bit/ 32-Bit M. Hopf original> Size after:> text data bss dec hex filename> 3514 8 84 3606 e16 main.elf>> // 64-Bit von PeDa> Size after:> text data bss dec hex filename> 3868 8 84 3960 f78 main.elf
D.h mit meiner Lib sind es 354 Byte mehr.
Meine Lib ist aber nur 208 Byte groß. Bist Du sicher, daß Du die andere
auch rausgenommen hast?.
Die Vermutung mit float lag daran, daß >3kB ja schon recht viel ist.
Hast Du vielleicht das komplette Programm zum Compilieren verfügbar?
Peter
Hallo,
ich bin auf dieses Projekt gestossen, weil ich mir "eben schnell" mit
einfachen Mitteln einen Frequenzzähler aufbauen wollte.
Jetzt bin ich dabei den Code mit dem Atmel Studio 6.2 zu bearbeiten.
Dabei bin ich in der main.c der Version 1.2 auf die folgende Dinge am
Ende vom Assembler-Abschnitt getroffen, die ich nicht verstehe :
1
::"M"((uint16_t)(MIN_SAMPLE_TIME*F_CPU/65536.0)),
2
"I"(_SFR_IO_ADDR(EIMSK)),
3
"M"(1<<INT0),
4
"I"(_SFR_IO_ADDR(EIFR)));
Könnte mir vielleicht mal jemand erklären was obiges bewirkt ? Ich
könnte mir vorstellen das die Daten aus "M" in die Register "I" EIMSK
und EIFR geschrieben werden sollen ??
Das problem ist, _SFR_IO_ADDR scheint das Atmel Studio nicht (mehr?) zu
kennen. Vielleicht kann man dafür was anders angeben ?
Im voraus schon mal Danke