Datum:
Angehängte Dateien:Ne UART mit ein paar Bytes Puffer ist doch ganz praktisch, nimmt ne ganze Menge Streß aus der Mainloop. Hier mal mit der Software-UART kombiniert, für die schnuckeligen ATtinys (Beispiel mit ATtiny44). Oder als 2.UART für nen ATmega328P. Statt dem ICP kann man auch einen externen Interrupt nehmen (ATtiny25..85). Peter
Datum:
@ Peter Ich habe den Code auf meinem ATtiny44 ausprobiert, aber leider funktioniert er nicht so gut. Der Code wird irgendwie langsamer ausgeführt als sonst. Die "delay-funktion" lässt eine LED ca. 10mal länger blinken als in einem einfachen main.c . Die Daten die ich auf der UART sehe sind dem entsprechend auch nur wirr. ICh betreibe den Controller mit den 8Mhz vom internen Osz. ( ...denke ich, denn ich habe die fuses nie geändert und avr-studio zeigt es so an.) Gleichzeitig bin auf der Suche nach einer anderen Portbelegung. Ich muss die RX und TX Leitungen auf anderen Pins haben. Auch bei deinen anderen Soft-UARTS verwendest du immer die gleichen. Wie kann ich diese Belegung ändern? Es wäre schön, wenn du mir etwas Starthilfe geben könntest. Danke
Datum:
Sabine schrieb: > Der Code wird irgendwie langsamer ausgeführt als sonst. Die > "delay-funktion" lässt eine LED ca. 10mal länger blinken als in einem > einfachen main.c . Kann es sein, dass die LED exakt 8 mal langsamer blinkt? > Die Daten die ich auf der UART sehe sind dem entsprechend auch nur wirr. > ICh betreibe den Controller mit den 8Mhz vom internen Osz. ( ...denke > ich, denn ich habe die fuses nie geändert und avr-studio zeigt es so > an.) Ich nehme mal an, dass der ATTiny nur mit 1MHz statt 8MHz läuft. Dafür ist die CKDIV-Fuse zuständig, siehe auch: http://www.engbedded.com/fusecalc/ Gruß, Frank
Datum:
Danke für den Hinweis mit dem CKDIV. Du hattest Recht im Auslieferungszustand steht er zwar auf 8MHz aber der Vorteiler ist auch gesetzt. Mein Problem ist damit so recht immer noch nicht gelöst. Wie kann es sein,das der folgende Code in einem einfachen MAIN die LED eine halbe Sekunde blinken läßt. Wenn ich die Zeilen aber in die Main aus Peters Code einfüge, blinkt sie 5 sekunden.
PORTA |= (1 << PA3); //rot einschalten _delay_ms(500); // verzögerung PORTA &= ~(1 << PA3); |
Dazu kommt noch erschwerend, dass ich doch die RX-TX auf anderen Pins brauche. Wenn du mir da auch noch einen Tip geben könntest, wäre ich dir sehr dankbar.
Datum:
Ich bins schon wieder. Denn fehler mit den unterschiedlichen Zeiten habe ich gefunden. Peter schreibt ich seiner MAIN.H:
#define XTAL 11.0592e6 #define BAUD 57600 #define F_CPU XTAL |
F_CPU wird wiederum für die "delay" verwendet ... und das sind eigentlich nun mal nur 1MHz. F_CPU hatte ich in meinen Test-Programm nicht definiert.... Die 500ms, die "delay" produzieren soll, stimmen aber auch nicht. Es sind 860ms. Kannst du mir das bitte erklären?
Datum:
Sabine schrieb: > Die 500ms, die "delay" produzieren soll, stimmen aber auch nicht. > Es sind 860ms. > Kannst du mir das bitte erklären? Nein, kann ich leider nicht. Wie hast Du denn nun XTAL resp. F_CPU im Programm eingestellt? Wenn Du das folgendermaßen änderst: #define XTAL 8.0e6 dann sollte Dein delay richtig laufen. Läuft der interne Takt nun mit 8MHz, d.h. Du hast die CKDIV-Fuse korrigiert? Und wie hast Du die 860ms gemessen? Beachte auch, dass Du eine identische F_CPU-Definition in allen Source-Modulen verwendest, am besten setzt Du F_CPU im Projekt und löscht Peters eigene Definitionen von XTAL und F_CPU. Gruß, Frank
Datum:
Sabine schrieb: > Gleichzeitig bin auf der Suche nach einer anderen Portbelegung. Ich muss > die RX und TX Leitungen auf anderen Pins haben. Auch bei deinen anderen > Soft-UARTS verwendest du immer die gleichen. Wie kann ich diese Belegung > ändern? Peter nutzt den sog. ICP-Pin des Tinys und den dazugehörenden Interrupt. Um einen anderen Pin zu verwenden, musst Du einen anderen externen Interrupt verwenden. Ich weiß jetzt aber nicht, ob der ATTiny44 weitere Interrupts auf den anderen Pins bietet, habe noch nie mit dem ATTiny44 gearbeitet bzw. mir das Datenblatt dazu angeschaut. EDIT: Habe gerade mal ins Datenblatt geschaut, es sagt: "External Interrupt Sources: Pin Change Interrupt on 12 Pins". Das heisst, Du kannst fast jeden Pin verwenden, Du musst dann aber die ISR auf den Pin Change Interrupt umstellen. Eine andere Möglichkeit, einen Soft-Uart zu implementieren, ist die Verwendung eines Timer-Interrupts und dazugehörendes Polling. Das geht aber mit Peters Code nicht - jedenfalls nicht mit dem Code aus diesem Thread. Tante Google mit folgenden Suchwörtern software uart avr timer sollte dazu noch mehr sagen können. Gruß, Frank
Datum:
Noch eine Ergänzung: Einen Soft-Uart zu implementieren ohne angeschlossenen Quarz kann in die Hose gehen. Der interne Oszillator ist nicht sehr genau und insb. auch temperaturabhängig. Bei zu großen Abweichungen der realen Taktfrequenz kann es zu Übertragungsfehlern kommen - jedenfalls bei höheren Baudraten. Bei 8MHz würde ich mich nicht trauen, mehr als 9600Bd zu verwenden - jedenfalls bei einem HW-Uart. Bei einem Soft-Uart könnten die 9600Bd auch schon zu viel sein, muss man ausprobieren. Gruß, Frank
Datum:
Sabine schrieb: >
> #define XTAL 11.0592e6 > #define BAUD 57600 > #define F_CPU XTAL > |
Wenn Du keine >=11MHz nimmst, könnten 57kB Probleme bereiten. Nimm also ne entsprechend kleinere Baudrate, z.B. 9600. > Die 500ms, die "delay" produzieren soll, stimmen aber auch nicht. > Es sind 860ms. > Kannst du mir das bitte erklären? Delay ist keine Uhr. Wenn Du genaue Zeiten brauchst, nimm nen Timer. Delay zählt einfach nur Befehle, d.h. jeder Interrupt verlängert es um seine Ausführungszeit. Peter
Datum:
@ Frank Die F_CPU habe ich als define in der main.h neu festgelegt und die definitionen von Peter habe ich entsorgt. (auskommentiert) Sollte doch gehen. (oder) Ja, die CKDIV-Fuse habe ich jetzt auch korrigiert. Die 860ms habe ich mit einem Scope gemessen. Die baudrate habe ich schon reduziert auf 4800. Tja, und das mit den Schwankungen bei dem internen Oszillatorhabe ich als harmlos eingestuft, da ich den Controller sowieso immer bei Raumtemp. betreiben will. Das mit den RX-TX-Pins ist so mein Problem, den Peter benutzt 3 Interruptroutinen:
ISR( TIM1_CAPT_vect ) // start detection ISR( TIM1_COMPB_vect ) // receive data bits ISR( TIM1_COMPA_vect ) // transmit data bits |
Jetzt ist für mich nicht so ganz klar, welcher Interrup für was zuständig ist. ... und laut Datenblatt, haben zwar einige Pins einen Interrupt, aber ich kann Sie in der Tabelle nicht finden. Da gibt es nur PCINT1 und PCINT2. Wo bekomme ich denn den passenden Vector für PCINT1 und PCINT5 her? @Peter Könntest du bitte mal kurz nennen an welchen Stellen ich drehen muss, um RX auf PA5 und TX auf PA1 zu haben. (... das in main.h ist klar, das leuchtet sogar mir ein. Aber in uart.c wird es schwieriger.) Ich denke das es für einen fortgeschrittenen Coder etwas leichter ist den Code zu lesen wie eine "Matrix". Aber dazu sehe ich mich noch nicht in der Lage. Das die "delay" durch Interrupts länger wird leuchtet mir ein. Aber Sie ist konstant 860ms, auch wenn ich nur einen Pin mit dieser Funktion kippen lasse. Könnte das schon ein Hinweis auf den sehr ungenauen internen Oszillator sein?
Datum:
So, ich habe es geschafft. Ich kann nun mit dem internen Oszilator bei 4800Bd senden. Empfangen habe ich noch nicht getestet. Leider will es mir nicht gelingen den TX-Pin umzuverlegen. In der main.h (nd auch in der uart.c) habe ich folgende zeilen ergänzt:
#define NEU_STXD SBIT( PORTA, PA1 ) // #define NEU_STXD_DDR SBIT( DDRA, PA1 ) |
und in der suart.c bei jedem:
TX_OUT = TX_HIGH; |
noch ein
PORTA |= (1 << PA1); //High |
bzw bei
TX_OUT = TX_LOW; PORTA &= ~(1 << PA1); //Low |
Ich verstehe es nicht denn der PA1 bewegt sich garnicht. Dabei sollte doch der TX nun auf beiden Pins vorhanden sein. (oder?) Es wäre schön, wenn da jemamd was zu sagen könnte.
Datum:
Hallo, hab den Softwareuart zum laufen bekommen... Verwende AVR Studio (WinAVR) + Atmega48... 16Mhz cyristal Musste nur alle interruptvectoren umbennenen... also aus TIM1_ -> TIMER1_ machen Danke für den Quellcode... kombiniert mit deinem Bootloader muss ich fast nie mehr den RS232 Stecker am STK 500 umstecken :)
Datum:
Angehängte Dateien:Hallo, ich möchte den attiny861 mit diesen Code verwenden, leider fehlt mir noch die Erfahrung eine Anpassung durch zu führen. Wer kann Helfen ? Im Zielcode sind: * OCR1A, OCR1B, bzw. die Pins PB1, PB3 belegt und geben ein Audio PWM Signal aus. * Eine SD Karte ist über PB0 (CS), PA0 (DataIn), PA1 (DataOut) und PA2 (Clk) angeschlossen. * Der attiny861 läuft mit dem internen 8MHz Takt. * PB4 - PB6 und PA3, PA4 - PA7 können für den "Software UART" verwendet werden.
Datum:
Hallo. Erstmal danke für den super SoftUART. Hab ihn für nen ATmega32 modifiziert und bei 16MHz vom internen Oszi und 57600 Baud laufen die ersten Versuche ohne Probleme. Jetzt habe ich aber doch noch eine Schwierigkeit. Ich schaffe es nicht mit uputchar() ein einzelnes Zeichen zu senden. uputs("Hallo Peter \n\r") wie in der Test main.c läuft. Ich schaue mir den output via TeraTerm an. Vielleicht kann mir ja jemand einen Tip geben. Gruß Sebastian
Datum:
Von Sabine: >Das die "delay" durch Interrupts länger wird leuchtet mir ein. Aber Sie >ist konstant 860ms, auch wenn ich nur einen Pin mit dieser Funktion >kippen lasse. >Könnte das schon ein Hinweis auf den sehr ungenauen internen Oszillator >sein? Wenn das delay ohne die Interrupt-Funktionen im Hintergrund korrekt läuft, wird das Problem nicht vom Oszillator verursacht. Auch wenn je nach Situation verschieden große Teile des Interrupt-Codes ausgeführt werden, so vermute ich dass die Prologe und Epiloge der Interruptroutinen so lang sind, dass sich verschieden lange Codeabschnitte innerhalb der Routinen zeitlich gar nicht bemerkbar machen. //OT: Ich bin eh kein Freund der mitgelieferten Delay-Funktion Wenn ich die Chance habe, nutze ich meine eigene und greife dafür auf einen der Timer zurück. (In den meisten Fällen ist es sogar möglich auf einen bereits genutzten Timer aufzusatteln ;) Auf diese Weise ist es sogar möglich nicht-blockierende Delays zu nutzen, also während der Wartezeit mit etwas anderem weiterzumachen! //!OT EDIT: hahahaaa, man sollte mal aufs Datum gucken...
Datum:
Hy zusammen, Ich bin ein anfänger in sachen coden. Ich versuche gerade den code auf den Attiny13 umzuschreiben, der erfolg hält sich aber in grenzen, bekomme fehler meldungen die ich nicht verstehe, es geht um DDRA und PORTA => ../MAIN.C:21: error: 'DDRA' was not declared in this scope => ../MAIN.C:23: error: 'PORTA' was not declared in this scope Wie bekomme ich die felher weg und könnt ihr mir vieleicht erklären wo her die PORTS kommen, denn der attiny45 hat doch ur PB0-PB5. und wenn ich die DDRA und PORTA auskommentiere bekomme ich 5 meldung =>../SUART.C:105: error: 'PINA' was not declared in this scope damit ihr wiesst wie ich vorgegangen bin, habe den codes geladen compeliert (48errors), und der code ist für timer1 geschrieben habe alles auf timer0 geändert und die register angepasst. aus #define STXD SBIT( PORTA, PA6 ) // = OC1A #define STXD_DDR SBIT( DDRA, PA6 ) #define SRXD_PIN SBIT( PINA, PA7 ) // = ICP habe ich gemacht #define STXD SBIT( PORTB, PB4 ) // = OC1A #define STXD_DDR SBIT( DDRB, PB4 ) #define SRXD_PIN SBIT( PINB, PB5 ) // = ICP komme dann auf 11 warnung, laufen tuts trozdem nicht :( hat das einer schon mal von euch gemacht den code für attiny13 geändert? mfg Lucky
Datum:
Hallo der tiny13 hat kein Input Capture Pin und auch kein OC1A ! also so einfach ist das leider nicht.
Datum:
aso, aber ei OC1A, kann ich denn den nicht nehmen? das es nicht leicht wierd habe ich leider auch schon gemerkt :( kennt ihr eine alternative für den attiny13 daten an den pc zu schiecken?
Datum:
Lucky schrieb: > Ich bin ein anfänger in sachen coden. > Ich versuche gerade den code auf den Attiny13 umzuschreiben, der erfolg > hält sich aber in grenzen, bekomme fehler meldungen die ich nicht > verstehe, es geht um DDRA und PORTA Es beißt sich etwas, wenn man wenig Ahnung von C hat und dann gleich Beispiele auf den kleinst möglichen MC portieren will. Versuch erstmal, das Beispiel auf dem genannten Typ laufen zu lassen oder wenigsten auf einem mit ICP. Also immer einen Schritt nach dem anderen machen. Wenn man beide Beine gleichzeitig hebt, fällt man um. Peter
Datum:
Angehängte Dateien:Hallo, erst mal danke an Peter für die kleine Lib ! Ich habe sie mir für den atMegax8 angepasst und konnte erfolgreich einen Datenstrom mit 57600 Baud 8,n,1 versenden. Die angehängten Quellen habe einige Defines um die Sende- von der Empfangsroutine auch getrennt nutzen zu können. Zu meiner Anwendung auf der Hardware Usart0 empfange ich einen Datenstrom, denn ich nach Datenanalyse umformatiert mit der Software Uart ausgebe. Beide Libs könnte ihr in dem Anhang finden, viel Erfolg.
Datum:
Fred Granna schrieb im Beitrag #2025107: > Code Rudi schrieb im Beitrag #2353127: > Wie ist bei dir eigentlich der Stand? Tja, seit nem halben jahr läuft hier eine Bastellösung: Atmel-Arduino mit einem externen UART (per i2c). Telegramme lesen und anmelden am System (registriert sich als Servicekey an der Heizung) laufen. Will aber grad weg davon. Der Uart macht nur ärger. Habe mir heute einen Atmel mit 4 Uarts besorgt und spiele grad mit deinem c-code rum. Leider ist dort nur der Empfangsteil drin und nicht der Sender. Stehe da grad komplett auf dem schlauch wie ich daten in den Bus pumpen soll...
Datum:
Hallo ICh möchte das gerne auf einem ATTiny2313 zum laufen bringen Nachdem ich nun alle TIMSK1 durch TIMSK ersetzt habe (und sonstige auch) lässt sich das teil nun kompilieren. Habe uach die Ports umgelegt auf #define STXD SBIT( PORTB, PB3 ) // = OC1A #define STXD_DDR SBIT( DDRB, PB3 ) #define SRXD_PIN SBIT( PIND, PD6 ) // = ICP Also sollte dann von OC1A und ICP wieder gleich sein. Allerdings habe ich das problem, das er mir hängen bleibt TIMSK = 1<<ICIE1^1<<OCIE1A; // enable tx and wait for start zumindest blinkt mir meine LED nicht mehr, wenn ich diese Zeile im suart_init drinnen lasse, sobald ich die auskommentiere, dann blinkt meine led wieder ... an was kann es noch liegen? Hat wer einen code für den 2313?
Datum:
Könnte mir vorstellen, dass du hiermit:
TIMSK = 1<<ICIE1^1<<OCIE1A; // enable tx and wait for start |
bereits getätigte Einstellungen im TIMSK-Register platt machst. Versuche es mal mit:
TIMSK |= 1<<ICIE1^1<<OCIE1A; |
Die gleiche Problematik dann auch nachher beim Manipulieren des TIMSK in den ISR's! //Niffko