Hallo Leute Ich programmiere in Basic und habe einen 90S2313 -10 MHz Nun mein Problem als eingang habe ich ein Low Signal das 100 ms lang ist und nun schaltet der Ausgang oft und oft auch wieder nicht !! Also absolut unzuverlässig . Als Quarz habe ich 8 MHz. Sind denn 100 ms zu wenig ?? nicht oder !! Wo liegt mein fehler hier mein Listing. $regfile = "2313def.dat" $crystal = 7372800 Ddrb = 255 : Portb = 0 Dim A As Byte Dim B As Byte Do Debounce Pind.0 , 0 , Kanal1 , Sub Loop Kanal1: For A = 1 To 1 Portb.0 = 1 Wait 5 Portb.0 = 0 Waitms 150 Next Return
hi! >For A = 1 To 1 > Portb.0 = 1 > Wait 5 > Portb.0 = 0 > Waitms 150 >Next wieso 1 to 1?? entweder führt der uc die befehle erst gar nich aus, weil a zu beginn schon 1 ist, und ja bei 1 enden soll, oder de uc führt die befehle einmal aus, dann kannst du for...next aber gleich weglassen. Nik
Hi Chris: Nur so eine Idee von mir, Versuch´s mal mit dem Int0 oder Int1. zb: $regfile="2313def.dat" $crystal=xxxxusw ddrb=255:portb=0 config int0 oder Int1=rising oder falling on int1 kanal1 enable int1 enable Interrupts do loop kanal1: 'hier steht das Prog.. usw return Wie schon gesagt,nur so eine Idee ;-)
Hallo ThomasB Danke erstmal werde ich morgen gleich testen . Ich geb dann bescheid ob es geht. Hallo Nik Bamert Danke stimmt ist ein umweg geht aber trotzdem auch so den ursprünglich lautet das listing so >For A = 1 To 3 > Portb.0 = 1 > Wait 5 > Portb.0 = 0 > Waitms 150 >Next hab es dann nur schnell zu eins gemacht weil eben die 100 ms als impuls nicht jedesmal funktionieren. Soll mal ein entschäumer für mein Seewasser Aquarium werden. der impuls geht leider nicht länger da es ein durchflußmengenmesser ist. Danke bis Morgen
Hallo Chris, so als BASCOM-Laie frage ich mich, warum Du bei einem 8 MHz Quarz das hier schreibst: $crystal = 7372800 Ich hätte jetzt $crystal = 8000000 erwartet, aber wie gesagt, ich habe keine Ahnung von BASCOM. Gruß, Frank
Das kann garnicht gehen. Du wartest ja 3 * (5 + 150)ms = 465ms. Dann kannst Du doch nicht erwarten, das zwischendurch alle 100ms ein Port abgefragt wird. Warten heißt immer Nichtstun, also CPU-Zeit vergeuden ! Eine Abhilfe gegen das Warten habe ich hier beschrieben: http://www.mikrocontroller.net/forum/read-4-49709.html Ist aber in C. Peter
Mit dem Warten = CPU-Zeit vergeuden hast Du natürlich recht. In diesem speziellen Fall wäre aber noch wichtig zu erfahren, wie lang die Zeit zwischen den Eingangsimpulsen ist. Wenn die Zeit im Unterprogramm kürzer ist, sollte es trotzdem funktionieren. Allerdings vermute ich, daß Deine Rechnung noch überaus positiv ausgefallen ist, weil es einmal "Wait" (Einheit vermutlich Sekunden?) und einmal "Waitms" heißt. Das wären dann bei drei Durchläufen schon 15.450 ms ... Gruß, Frank
Hallo Danke erstmal für die viele Hilfe . Also Thomas leider hats auch so nicht geklappt habe alles durchprobiert. Hallo Peter Dannegger mit c kann ich leider so gut wie nichts anfangen (bin ich zu blöd). Habe leider nur Basic kentnisse ! bin aber schon am überlegen ob ich nicht wirklich c lernen sollte. Aber warten tut er doch nur nachdem der schaltbefehl ausgeführt wurde also müsste es doch auch in basic eine möglichkeit geben das man einen eingangsport unter 100 ms abfragen kann . Oder ??? Viele Grüsse Christian
@Chris, Wenn das Problem schon vor den 15,45s auftritt, dann liegts wohl nicht daran, sondern am "debounce" Was aber nun in der Blackbox "debounce" passiert, das wissen nur die Bascom-Götter. Das ist auch der Hauptgrund, warum ich mit Bascom nicht warm werde. Man schiebt nur "schwarze Kästchen" zusammen ohne zu wissen was darin passiert und welche Seiteneffekte auftreten (z.B. Programmverzögerung). Größere Programme kann man aber so nicht aufbauen. Aus dem gleichen Grund benutze ich auch nicht Pavels Codevision. Da sind z.B. alle 1-Wire-Funktionen direkt im Compiler vermanscht. Es ist aber unmöglich 100% sichere und für jeden denkbaren Fall optimale Bibliotheken zu erstellen. Deshalb verwende ich grundsätzlich nur Bibliotheken, die als Sourcetext vorliegen, damit ich eine Fehlersuche und -Korrektur bzw. Anpassung und Laufzeitabschätzung selber machen kann. Peter
Hallo Peter Danke ich glaube auch das es schon beim Befehl debounce fehlen muß, bin aber jetzt auch der meinung wenn man listings erstellt die schnelle abarbeitung brauchen mit Basic (Bascom AVR) nicht sehr weit kommen wird. Kannst Du mir einen Tip geben wie ich c am besten lernen kann ?? (welches Buch oder so) Danke Peter An alle BASCOM AVR Profis ! Hat denn von den Bascom AVR Profis unter euch noch niemand so ein problem gehabt ?? Oder bin ich da mit meinem listing auf dem falschen weg ?? Gruß Christian
Hay Chris Hab mich jetzt auch damit beschäftigt, aber im Bascom scheint das wirklich nicht so zu funktionieren. Ich kann Dir da nur assembler ans herz legen.( Nicht C ) Gruß Gerhard
Hi Chris, mit dem wait Befehl darf man das nicht machen!!!! Der AVR kann in dieser Zeit sonst nichts erledgen. (kein Multitasking !) Dazu musst du einen Timer verwenden. 1/10s das sind sogar für Bascom Welten. Was soll denn nun genau geschehen wenn das Eingangssignal kommt? Aus deinem Programm kann ich lesen daß dann ein Ausgangs-pin 5s lang High Pegel führen soll. Wenn das so richtig ist , würde ich das so machen: 1. In der Do Loop Schleife den Eingang abfragen , oder falls noch frei Int0 od. Int1 dazu verwenden. 2. Beim Eingangs-Low-Signal dann den Ausgang setzen ,einen Timer starten und bei jedem Timerüberlauf eine Variable hochzählen und abfragen, bis die 5s erreicht sind. Dann den Ausgang rücksetzen, u. Variable auf 0 setzen. Versuch es mal. Ich kann nur sagen dass ich bisher mit Bascom alles geschafft habe was ich mir vorgenommen hab. Sind mal wirklich zeitkritische Sachen zu Programmieren so sind diese Programmteile halt in Assembler zu schreiben. Assemblercode ist innerhalb Bascom ja möglich. Gruss Gerhard
Hallo Gerhard Das hört sich gut an, könntest Du mir da mal ein beispiel posten. Hier nochmal was passieren soll. So soll das fertige Programm mal aussehen ich hatte bisher nur einen eingang genommen zum testen. Pind0 ist eingang für low signal 100ms Pind1 ist eingang für low signal 100ms Pind2 ist eingang für low signal 100ms WENN PIND0 oder PIND1 oder PIND2 low signal bekommt soll Pinb0 ist ausgang high soll 300ms high werden. Pinb1 ist ausgang high soll 300ms high werden 300ms low wieder 300ms high und dann low. Pinb2 ist ausgang high soll 300ms high werden 300ms low wieder 300ms high und dann wieder 300ms low wieder 300ms high und dann low das heißt Pinb0 gibt einen high impuls von 300 ms aus pinb1 gibt zwei high impulse von 300 ms aus pinb3 gibt drei high impulse von 300 ms aus im beispiel habe ich die 5 sec. nur genommen um besser sehen zu können ob der ausgang schaltet. Vielen Dank im voraus Chris
Hallo Chris, versuchs mal hiermit: $Crystal = 8000000 Config portd = Input Config portb = output Portd = 00000111 dim a as byte do if pind.0 = 0 or pind.1 = 0 or pind.2 = 0 then waitms 99 if pind.0 = 0 or pind.1 = 0 or pind.2 = 0 then gosub impulse end if end if loop impulse: set pinb.0 set pinb.1 set pinb.2 waitms 300 reset pinb.0 reset pinb.2 reset pinb.3 waitms 300 set pinb.2 set pinb.3 waitms 300 reset pinb.2 reset pinb.3 waitms 300 set pinb.3 waitms 300 reset pinb.3 return Hoffe, das klappt. Sven A.
Hay Sven Danke das könnte so klappen. Ich werde es nach dem essen gleich mal probieren. Hast mich aber falsch verstanden wenn Pind0 ist eingang soll nur Pinb0 einen high impuls ausgeben. Pind1 ist eingang soll nur Pinb1 einen high impuls ausgeben. Pind2 ist eingang soll nur Pinb2 einen high impuls ausgeben. aber zum test werde ich es dann gleich probieren ich gebe Dir dann bescheid. Danke Gruß Chris
Hallo Chris, achso.... na dann $Crystal = 8000000 Config portd = Input Config portb = output Portd = 00000111 dim a as byte do if pind.0 = 0 or pind.1 = 0 or pind.2 = 0 then waitms 99 if pind.0 = 0 then gosub impuls1 if pind.1 = 0 then Gosub Impuls2 If pind.2 = 0 then Gosub Impuls3 end if end if loop impuls1: set portb.0 waitms 300 reset portb.0 Return Impuls2: a = 0 for a = 0 to 1 set portb.1 Waitms 300 reset portb.1 waitms 300 next a return impuls3: a = 0 for a = 1 to 2 set portb.3 waitms 300 reset portb.2 waitms 300 return sooo, hatte auch ausversehen set Pinb.. usw geschrieben, das Funktioniert natürlich nicht, aber so sollte das jetzt klappen. Gruß Sven A.
Hallo Chris Ich wollte einfach nicht glauben daß der Bascom debounce Befehl nicht geht und ich hatte bei den Listings der Kollegen Fehlermeldungen. Der beigefügte Code macht glaube ich das was Du möchtest. Der Debounce Befehl funktioniet tadellos und erlaubt noch die entsprechende Routine anzuspringen. Habe keinen 2313 an der Hand daher den 90S8515 genommen und ihn auf das STK500 gesteckt. Viel Spaß Michael $regfile = "8515DEF.DAT" Config Portd = Input 'Hier sind die Tasten angeschlossen Config Portb = Output 'hier sind LEDs angeschlossen Config Debounce = 1 Do Debounce Pind.0 , 0 , Erster , Sub Debounce Pind.1 , 0 , Zweiter , Sub Debounce Pind.2 , 0 , Dritter , Sub Loop Erster: Set Portb.0 Waitms 300 Reset Portb.0 Return Zweiter: Set Portb.1 Waitms 300 Reset Portb.1 Waitms 300 Set Portb.1 Waitms 300 Reset Portb.1 Return Dritter: Set Portb.2 Waitms 300 Reset Portb.2 Waitms 300 Set Portb.2 Waitms 300 Reset Portb.2 Waitms 300 Set Portb.2 Waitms 300 Reset Portb.2 Return End 'end program
Man muß bei einer solchen Art Programmierstil aber immer berücksichtigen, daß Warten auch wirklich absolutes Nichtstun bedeutet ! D.h. solange die 1,5s "Dritter" ablaufen, kann nichts anderes gemacht werden. Dann werden sämtliche anderen Tastendrücke ignoriert und auch "Dritter" läuft nicht nochmal los, wenn man innerhalb der 1,5s nochmal gedrückt hat. Peter
Hallo Peter Natürlich hast Du recht und ich würde es so für mich selbst nicht programmieren da der Prozessor für sonst nichts mehr genutzt werden kann. Ich wollte eigentlich nur wissen ob der "debounce Befehl einen "bug" hat was aber nicht der Fall ist. Ich würde einen der Timer verwenden und diesen beispielsweise immer wieder für 1 msec zählen lassen sozusagen als Uhr. Paralell dazu würde ich den drei Eingängen je eine Variable zuweisen und diese dann immer wenn der Timer seinen Überlauf ereicht (interruptgesteuert) Inkrementieren bzw Dekrementieren. Damit könnten alle drei Eingänge unabhängig voneinander funktionieren und die gesamte Prozessorauslastung wäre vermutlich unterhalb eines Prozents. Das zu Schreiben und zu Testen dauert aber mehr als 10 Minuten und ich bin mit eigenen Projekten gut ausgelastet. Ok? Gruß Michael
Hallo Michael, hast recht, hab natürlich 2 schreibfehler drin und einen Befehl noch vergessen:: $crystal = 8000000 Config portd = Input Config portb = output Portd = 00000111 dim a as byte do if pind.0 = 0 or pind.1 = 0 or pind.2 = 0 then waitms 99 if pind.0 = 0 then gosub impuls1 if pind.1 = 0 then Gosub Impuls2 If pind.2 = 0 then Gosub Impuls3 end if Loop '************************************************ impuls1: set portb.0 waitms 300 reset portb.0 Return '************************************************ Impuls2: a = 0 for a = 0 to 1 set portb.1 Waitms 300 reset portb.1 waitms 300 next a return '************************************************ impuls3: a = 0 for a = 1 to 2 set portb.3 waitms 300 reset portb.2 Waitms 300 Next A return aber so sollte das jetzt gehen, bei deinem Programm müßte im übrigen Config debounce = 100 stehen, für die 100ms wartezeit, ich benutze den debounce befehl aber nur , wenn ich taster angeschlossen habe. Chris benutzt glaube ich einen Durchflußmengen Messer, deshalb. Für mich würde ich das auch anders Programmieren , aber es sollte ja auch nur ein Anstoß sein, klar, viele Wege führen nach Rom ;-)) Sven A.
@Michael, "die gesamte Prozessorauslastung wäre vermutlich unterhalb eines Prozents" stimmt, d.h. der 90S2313 ist definitiv nicht zu langsam, sogar ein 32kHz Quarz müßte reichen. "Das zu Schreiben und zu Testen dauert aber mehr als 10 Minuten" Unter Nutzung meines Schedulers habe ich nicht mehr als 10min gebraucht. Nachfolgend der Code (leider in C), falls es doch erwünscht ist, daß alle 3 Tasten unabhängig voneinander funktionieren sollen. Die Scheduler-, Getkey- und Timerroutinen aus der Codesammlung müssen noch dazugelinkt werden. Peter #include "main.h" char count0, count1, count2; void light0_toggle( void ){ LED_OUTPUT ^= 1<<LED0; // LED toggle if( --count0 ) // count down timeradd( light0_toggle, SECONDS( 0.3 )); // toggle time } void light1_toggle( void ){ LED_OUTPUT ^= 1<<LED1; if( --count1 ) timeradd( light1_toggle, SECONDS( 0.3 )); } void light2_toggle( void ){ LED_OUTPUT ^= 1<<LED2; if( --count2 ) timeradd( light2_toggle, SECONDS( 0.3 )); } int main( void ) { TCCR0 = 1<<CS02; //divide by 256 * 256 TIMSK = 1<<TOIE0; //enable timer interrupt DDRB = 0xFF; // enable outputs LED_OUTPUT = 0xFF; // all LEDs off timerinit(); sei(); for(;;){ // main loop if( f_timer_tick ){ f_timer_tick = 0; timertick(); // run scheduler } if( get_key_press( 1<<LED0 ) && count0 == 0 ){ count0 = 2; light0_toggle(); } if( get_key_press( 1<<LED1 ) && count1 == 0 ){ count1 = 4; light1_toggle(); } if( get_key_press( 1<<LED2 ) && count2 == 0){ count2 = 6; light2_toggle(); } } }
Hallo vielen dank für die Super Hilfe. Hallo Peter danke so funktioniert es 100% und auch wenn während einer ausführung ein schaltbefehl kommt funktioniert es . Danke ich werde doch mal versuchen c zu lernen. Danke auch Sven und Michael auch Eure listings funktionieren einwanfrei, solange während der ausführung eines schaltbefehls kein neuer kommt. Aber ich habe wieder etwas dazugelernt. Danke für Euere Hilfe Chris
Hallo Chris, schön, das wir dir helfen konnten, brauchst aber deshalb nicht gleich c zu lernen,das geht mit bascom natürlich auch, stichwort auch, einen Timer benutzen. Gruß Sven
Hallo Sven Meinst Du wirklich das, das im Bascom das auch gehen würde ?? Ich habe bestimmt 100 möglichkeiten probiert habs aber nicht geschafft. Denn immer wenn ein befehl ausgeführt wurde, wurde der eingang übersehen. Wenn Du aber noch eine Idee hast gib mir bescheid hab nähmlich die Test schaltung noch vor mir liegen. Absolut perfektiert hab mir sogar mit einem 555 einen 100ms impulsgeber gebaut usw.... Bin also weiter zum Testen bereit. Gruß Chris
@Sven, "brauchst aber deshalb nicht gleich c zu lernen" Hui, böses Foul :-) Ich denke mal, daß so eine Enscheidung auf keinen Fall schlecht sein kann. Bei kleinen Programmen mag man ja mit Assembler oder Bascom noch den Überblick behalten. Aber ATMega128 Programme habe ich bisher nur ausschließlich in C gesehen (MP3, FAT32, Ethernet usw.) Spätestens ab ATMega16 braucht man einfach die Leistungsfähigkeit und Strukturierbarkeit von C, sonst programmiert man sich nen Wolf. @Chris, klingt so, als hättest Du mein Programm ausprobiert. Hast Du den schon den WINAVR installiert und es damit compiliert ? Peter
Hallo Peter ja ich hab den WinAvr installiert, habs aber nicht geschafft den surce zu compilieren. Ein bekannter 600 km entfernt hats mir dann compiliert und den fertigen hex per e-mail geschikt. Den hab ich dann eingespielt und Top es geht. Danke nochmal Aber was mache ich da falsch im WinAVR mein bekannter kennt sich damit leider auch nicht aus er benutzt den kostenplichtigen ICC AVR . Ich habe es nicht geschafft im WinAVR Gruß Chris
Hallo Chris, klar, müßte mit Bascom Klappen. einfach den timer0 nehmen, dann springt das programm automatisch in die Timer ISR, und da fragst du dann halt deine Eingänge ab. So könntest du zum Beispiel dann ein Flag setzten, wenn in einer Befehlsausführung dann ein anderer Eingang angesprochen werden sollte. Allerdings würde ich dann auch noch eine Variable in der TimerISR hochzählen, und die dann in der Befehlsausführung nehmen anstatt waitms ..... Vielleicht kommst du ja damit weiter Gruß Sven A.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.