so, jetzt probiere ich mich mit komplizierterem, nämlich erst dem LCD - ich benutze keinen Timer für die warteschleife. Ich rechne es hier vor. Ich muss ja senden, 0x03, 0x03, 0x03, 0x30. Das dürfte ein geringeres Problem sein, auch als Nibble.
Dann muss ich erst am Anfang 15ms warten, dann 4,1 ms, dann 100 mikrosekunden
Ich mache das so. Ich mache einfach zunächst mal eine Warteschleife, das dürfte kein Problem sein. Einfach eine generelle Warteschleife.
ich mache einfach eine generelle Warteschleife und rechne, die anzahl der Takte zusammen. Ich nehme bewusst kein Interrupt. Ich nehme die Warteschleife von vorher
´ sleep: push r16 push r17 ldi r16, 0x00 sleep_loop1: ldi r17, 0x00 sleep_loop2: inc r17 cpi r17, 0xff brne sleep_loop2 inc r16 cpi r16, 0xff brne sleep_loop1 pop r17 pop r16 ret Fangen wir an: rcall sleep ;;;;;;;3 ... sleep: push r16 ;;;;;2 push r17 ;;;;;2 ldi r16, 0x00 ;;;;;1 sleep_loop1: ldi r17, 0x00 ;;;;;1 sleep_loop2: inc r17 ;;;;;1 cpi r17, 0xff ;;;;;1 brne sleep_loop2 ;;;;; bei nicht sprung 1, sonst 2, normal 2: inc r16 ;;;;;1 cpi r16, 0xff ;;;;;1 brne sleep_loop1 ;;;;; bei nicht sprung 1, sonst 2, normal 2: pop r17 ;;; 2 pop r16 ;;; 2 ret ;;; 4 Das sind zun"achst mal nicht wiederholung: rcall sleep ;;;;;;;3 ... sleep: push r16 ;;;;;2 push r17 ;;;;;2 ldi r16, 0x00 ;;;;;1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; sleep_loop1: ldi r17, 0x00 ;;;;;1 sleep_loop2: inc r17 ;;;;;1 cpi r17, 0xff ;;;;;1 brne sleep_loop2 ;;;;; bei nicht sprung 1, sonst 2, normal 2: inc r16 ;;;;;1 cpi r16, 0xff ;;;;;1 brne sleep_loop1 ;;;;; bei nicht sprung 1, sonst 2, normal 2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pop r17 ;;; 2 pop r16 ;;; 2 ret ;;; 4Das sind zunächst mal nicht wiederholung: 8+8 = 16
wenn die innere schleife n mal wiederholt wird:
(1+1+2)*ndann mit der äusseren
((1+1+2)*n*+1)*m+(1+1+2)*mSo und jetzt kann man ausrechnen, ein Befehl ist 1/4.000.000 MHz. aber ich gucke genau nach
3.686 MHzUnd jetzt, das sind
2,71296798698e-07sund jetzt
((2,71296798698e-07+2,71296798698e-07+2*2,71296798698e-07)*n*+1*2,71296798698e-07)*m+(1*2,71296798698e-07+1*2,71296798698e-07+2*2,71296798698e-07)*m=4,1/0,0041das probiere ich mal mit xmaxima irgendwie zu lösen oder so
Zum Beispiel
(%i3) ((2.71296798698e-07+2.71296798698e-07+2*2.71296798698e-07)*n*+1*2.71296798698e-07)*m+(1*2.71296798698e-07+1*2.71296798698e-07+2*2.71296798698e-07)*m=0.0041; (%o3) 2.944078119351326E-13 m n + 1.085187194792E-6 m = 0.0041 (%i4)
Da steht jetzt keine Lösung, das Ergebnis überrascht mich. Ich habe eine bessere Idee. Ich setze für m für das innere einfach mal 256 ein und dann rechne ich das neu aus.
Anstatt
2.71296798698e-07zu schreiben, nehme ich
(float)1/(float)3686000
Und schreibe den Ausdruck in C hin
Entschuldigung nicht für m sondern n
das hat nicht funktioniert, aber ich mache es sauberer
//((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))*m+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*m; #include <stdio.h> #define n 255 int main (void) { printf ("%f\n", (float)((float)4.1/(float)1000)/((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000)))); }So, das sieht schon besser aus
//((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))*m+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*m; #include <stdio.h> int main (void) { float t = 4.1/(float)(1000); float n = (float)255; float x; printf ("%f\n", (float)((float)4.1/(float)1000)/((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000)))); x = ((1*t+1*t+2*t)*n*+1*t)+(1*t+1*t+2*t); printf ("%f\n", x); }Da kommt raus
david@work:~$ ./a.out 3774.813721 0.033546 david@work:~$Das heisst, indem falle wurde m = 1 gesetzt und das bedeutet, alleine mit der inneren schleife, für m = 1, dauert es bei n=256 etwa, 0.034s
Das entspricht der erfahrung. Rechnen wir mal aus
0.034s*256 = 8swir können den Test machen, am Controller und die Zeit stoppen
das kann nicht stimmen, weil der macht ja jetzt schon weniger als eine s.
Ach gucken sie mal: ich habe t falsch gesetzt
float t = 4.1/(float)(1000);Das stimmt natürlich nicht.
das kann auch nicht sein
david@work:~$ ./a.out 3774.813721 0.000001 david@work:~$ich weiss, wo der Fehler war, syntaxfehler, da stand +*
//((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))*m+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*m;C-Code
#include <stdio.h> int main (void) { float t = (float)1.0/(float)3683000; float n = (float)255; float x; printf ("%f\n", (float)((float)4.1/(float)1000)/((((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000))*n*+(float)((float)1/(float)3683000))+((float)((float)1/(float)3683000)+(float)((float)1/(float)3683000)+(float)((float)2/(float)3683000)))); x = ((1.0*t+1.0*t+2.0*t)*n+1.0*t)+(1.0*t+1.0*t+2.0*t); printf ("%f\n", x); x = (((4.0*t)*n+5.0*t))*n; printf ("%f\n", x); }Also jetzt kommt raus
david@work:~$ ./a.out 3774.813721 0.000278 0.070968 david@work:~$Das könnte gerade so sein. ich mache eine Schleife drum rum, um das bisher, mit dem 12 fachen. Das müsste, 1s ergeben, dann kann ich messen. Erster Versuch
.include "m8def.inc" ldi r16, HIGH (RAMEND) out SPH, r16 ldi r16, LOW (RAMEND) out SPL, r16 ldi r16, 0xff out DDRB, r16 rcall lcd_init ldi r16, 'a' rcall lcd_chout ldi r16, 'b' rcall lcd_chout ldi r16, 'e' rcall lcd_chout ldi r16, 'r' rcall lcd_chout ldi r16, ' ' rcall lcd_chout ldi r16, 'h' rcall lcd_chout ldi r16, 'a' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'o' rcall lcd_chout end: rjmp end lcd_chout: push r17 push r16 mov r17, r16 swap r16 andi r16, 0b00001111 sbr r16, 1<<4 ; wichtig RS=0 befehl, rs=1, daten, ja, aber hier daten out PORTB, r16 rcall lcd_enable andi r17, 0b00001111 sbr r17, 1<<4 out PORTB, r17 rcall lcd_enable pop r16 pop r17 ret lcd_init: push r16 rcall sleep_15ms ldi r16, 0x03 out PORTB, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x03 out PORTB, r16 rcall lcd_enable rcall sleep_100mus ldi r16, 0x03 out PORTB, r16 rcall lcd_enable ldi r16, 0x02 out PORTB, r16 rcall lcd_enable pop r16 ret lcd_enable: sbi PORTB, 5 nop nop nop cbi PORTB, 5 ret sleep_15ms: push r16 push r17 ldi r16, 0x00 sleep_15ms_loop1: ldi r17, 0x00 sleep_15ms_loop2: inc r17 cpi r17, 90 brne sleep_15ms_loop2 inc r16 cpi r16, 0xC9 brne sleep_15ms_loop1 pop r17 pop r16 ret sleep_4_1ms: push r16 push r17 ldi r16, 0x00 sleep_4_1ms_loop1: ldi r17, 0x00 sleep_4_1ms_loop2: inc r17 cpi r17,32 brne sleep_4_1ms_loop2 inc r16 cpi r16, 0xC9 brne sleep_4_1ms_loop1 pop r17 pop r16 ret sleep_100mus: push r16 ldi r17, 0 sleep_100mus_loop2: inc r17 cpi r17, 67 brne sleep_100mus_loop2 pop r16 retZweiter versuch
.include "m8def.inc" ldi r16, HIGH (RAMEND) out SPH, r16 ldi r16, LOW (RAMEND) out SPL, r16 ldi r16, 0xff out DDRB, r16 rcall lcd_init ldi r16, 'a' rcall lcd_chout ldi r16, 'b' rcall lcd_chout ldi r16, 'e' rcall lcd_chout ldi r16, 'r' rcall lcd_chout ldi r16, ' ' rcall lcd_chout ldi r16, 'h' rcall lcd_chout ldi r16, 'a' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'o' rcall lcd_chout end: rjmp end lcd_chout: push r17 mov r17, r16 swap r16 andi r16, 0b00001111 sbr r16, 1<<4 ; wichtig RS=0 befehl, rs=1, daten, ja, aber hier daten out PORTB, r16 rcall lcd_enable andi r17, 0b00001111 sbr r17, 1<<4 out PORTB, r17 rcall lcd_enable rcall sleep_50mus pop r17 ret lcd_cmdout: push r17 mov r17, r16 swap r16 andi r16, 0b00001111 out PORTB, r16 rcall lcd_enable andi r17, 0b00001111 out PORTB, r17 rcall lcd_enable rcall sleep_50mus pop r17 ret lcd_init: push r16 ldi r16, 50 powerupwait: rcall sleep_4_1ms dec r16 brne powerupwait ldi r16, 0x03 out PORTB, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x03 out PORTB, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x03 out PORTB, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x02 out PORTB, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0b00101000 rcall lcd_cmdout ldi r16, 0b00001100 rcall lcd_cmdout ldi r16, 0b00000110 rcall lcd_cmdout pop r16 ret lcd_enable: sbi PORTB, 5 nop nop nop cbi PORTB, 5 ret sleep_50mus: ldi r16, $42 sleep_100mus_loop1:dec r16 brne sleep_100mus_loop1 ret ret sleep_4_1ms: push r16 push r17 ldi r16, $21 WGLOOP0: ldi r17, $C9 WGLOOP1: dec r17 brne WGLOOP1 dec r16 brne WGLOOP0 ret pop r17 pop r16 ret sleep_100mus: push r16 ldi r17, 0 sleep_100mus_loop2: inc r17 cpi r17, 67 brne sleep_100mus_loop2 pop r16 retDritter Versuch
.include "m8def.inc" ldi r16, HIGH (RAMEND) out SPH, r16 ldi r16, LOW (RAMEND) out SPL, r16 ldi r16, 0xff out DDRD, r16 rcall lcd_init ldi r16, 'a' rcall lcd_chout ldi r16, 'b' rcall lcd_chout ldi r16, 'e' rcall lcd_chout ldi r16, 'r' rcall lcd_chout ldi r16, ' ' rcall lcd_chout ldi r16, 'h' rcall lcd_chout ldi r16, 'a' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'l' rcall lcd_chout ldi r16, 'o' rcall lcd_chout end: rjmp end lcd_chout: push r17 mov r17, r16 swap r16 andi r16, 0b00001111 sbr r16, 1<<4 ; wichtig RS=0 befehl, rs=1, daten, ja, aber hier daten out PORTD, r16 rcall lcd_enable andi r17, 0b00001111 sbr r17, 1<<4 out PORTD, r17 rcall lcd_enable rcall sleep_50mus pop r17 ret lcd_cmdout: push r17 mov r17, r16 swap r16 andi r16, 0b00001111 out PORTD, r16 rcall lcd_enable andi r17, 0b00001111 out PORTD, r17 rcall lcd_enable rcall sleep_50mus pop r17 ret lcd_init: push r16 ldi r16, 50 powerupwait: rcall sleep_4_1ms dec r16 brne powerupwait ldi r16, 0x03 out PORTD, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x03 out PORTD, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x03 out PORTD, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0x02 out PORTD, r16 rcall lcd_enable rcall sleep_4_1ms ldi r16, 0b00101000 rcall lcd_cmdout ldi r16, 0b00001100 rcall lcd_cmdout ldi r16, 0b00000110 rcall lcd_cmdout pop r16 ret lcd_enable: sbi PORTD, 5 nop nop nop cbi PORTD, 5 ret sleep_50mus: ldi r16, $42 sleep_100mus_loop1:dec r16 brne sleep_100mus_loop1 ret ret sleep_4_1ms: push r16 push r17 ldi r16, $21 WGLOOP0: ldi r17, $C9 WGLOOP1: dec r17 brne WGLOOP1 dec r16 brne WGLOOP0 pop r17 pop r16 ret sleep_100mus: push r16 ldi r17, 0 sleep_100mus_loop2: inc r17 cpi r17, 67 brne sleep_100mus_loop2 pop r16 ret
jetzt müssten wir die Formel noch mal machen
das stimmt nicht
x = (((((4.0*t)*n+5.0*t))*n)+5.0*t)*5.0; printf ("%f\n", x); david@work:~$ ./a.out 3774.813721 0.000278 0.354847 david@work:~$
das sind mindest 1.5s
https://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
gut, laut dem artikel liege ich schon mal richtig, sie rechnen, aber takt für die verzweigung, ich 3
Der Code benötigt eine Warteschleife, die mindestens 50 µs dauert. Die beiden Befehle innerhalb der Schleife benötigen 3 Takte: 1 Takt für den dec und der brne benötigt 2 Takte, wenn die Bedingung zutrifft, der Branch also genommen wird. Bei 4 MHz werden also
4000000 / 3 * 50 / 1000000 ~= 67
Die Formel die sie so rum angeben, finde ich besser. Ich mache die Rechnung noch mal und versuche auf 1s zu kommen.
4.000.000 => 1s
ich brauche als 4.000.000 Befehle
Die innere schleife
4 Takte
Also ((4*255)+5)*255+1s
Das 5 bei der äusseren kommt zustande, durch das ldi, was vor der inneren steht
also, gut ich möchte ja jetzt die übung machen, ich nehme für die Warteschleife deren werte, für die Wiederholungen.
OK, jetzt mache ich das so - ich nehme die Warteschleife, ich brauche 3. Die entsprechenden schleifewerte führe ich nachher ein, also durchläufe und mache den Rest.
da war auch ein fehler in dem für das Display - i2c - hat nichts geholfen, ein falsches bit
jetzt mit deren sleep tut es was nur die zeichen stimmen noch nicht.
ha, ha, ha, ha, ich habe den fehler gefunden, er war ganz dumm Ich habe dann ja angefangen die zählschleifen zu übernehmen, weil das nicht so toll war was ich gemacht hatte damit und dabei habe ich die Register gesichert auf dem Stack und hab dann das Return ausgeführt. Da war's bei mir auch. Allerdings hab ich ja den Teil vom Code einfach übernommen mit der Zählschleife, damit es stimmt und dabei ist es Return beim Kopieren Wieder mit reingekommen und dahinter war Push und Pop und damit war da einfach ein Fehler auf dem Stapel, weil weil da eben das nicht mitgenommen wurde. Ich zeige jetzt alle Codes, die ich habe.
https://www.ituenix.de/html/vid/IMG_4277.mov
https://www.ituenix.de/html/vid/IMG_4278.mov