Forum: Mikrocontroller und Digitale Elektronik Viele Fragen und ein kleiner Blog


von Holger P. (Gast)


Lesenswert?

Vorhin hat mir der Bekannte meines Vaters das AVR USB-Lab vorbei 
gebracht. Also ich gleich mal den Quarz eingelötet und die Firmware 
aufgespielt. Soweit echt klasse. AVR Studio 4 Installiert und SP1-SP3 
installiert.

So und jetzt?

OK lege ich mal los. Da ich kein Entwicklungsboard habe und auch keins 
möchte sondern mir selber eins aufbauen will, dachte ich mir nimmst du 
mal den Bausatz RFID-Reader von Pollin müsste ja gehen man hat drei 
Taster und zwei LED’s und da ich kein Display benutze einen Port auf der 
Steckerleiste. Eine RS232 ist auch drauf so müsste ich damit doch die 
ersten Schritte machen können. Verbaut wurde dort ein AT-Tiny 2313.

Schritt eins: AVR Studio aufrufen und die Software von dem AT-Tiny 
sichern. Dachte es hat wohl geklappt. Nachdem ich den Tiny gelöscht habe 
und ihn wieder bespielt habe ging aber nix mehr. Original Software von 
Pollin geladen und versucht sie aufzuspielen. Lange Rede, nicht immer 
klappt das ganze. Hin und wieder bekomme ich eine Meldung dass wohl die 
ISP-Frequenz nicht stimmt. Kleiner ¼ von 8MHz habe ich eingestellt und 
beim lesen von der Signatur bekomme ich hin und wieder einen Fehler, 
doch 50/50 klappt alles. Schon komisch aber das soll erst mal das 
Problem nicht sein. Nach X Anläufen klappt es ja und der Reader lebt 
wieder.

Nun jetzt möchte ich versuchen erst mal eine LED blinken zu lassen. Die 
LED’s hängen an DB6 und DB7 über 220 Ohm an +5Volt. Sind somit an 
derselben Leitung wie der ISP-SCK bzw. ISP-MISO, aus diesem Grund soll 
man die Jumper wohl auch entfernen wenn man am Board etwas via. ISP 
aufspielt. Um den RFID Decoder U2270B erstmal auszuschalten müsste ich 
PD2 am Anfang wohl auf LOW schalten und dann mit meinem geblinke 
loslegen.

Jetzt möchte ich hier kein fertigen Code haben, sondern mich ja selber 
erst mal in Assembler des AVR reinarbeiten aber ein schups wäre schon 
brauchbar.

das einzige was ich nun in AVR-Studio geschrieben habe ist

.Include 2313def.inc

Weiter müsste ich wohl:

PD2 auf LOW
Loop:
PB6 auf High
PB7 auf Low
Warteschleife
PB6 auf Low
PB7 auf High
Warteschleife
Zu Loop springen

Ich möchte das ganze in Assembler schreiben und mir dieses auch 
aneignen. Assembler des 8051 ist mir nicht gerade fremd und so sollte 
der Einstieg doch gehen. Das Programm sollte nachher auf Taster 
reagieren die RS232 dazu mit Ausgabe. Die LED’s nachher über RS232 
steuern u.s.w. einfach nur mal ein rein kommen.

Kann man eigentlich etwas machen damit man die LED’s von PB6 und PB7 
nicht immer mittels Jumper abkoppeln muss um danach eine ISP Verbindung 
her zu stellen.

Fragen über Fragen aber ist der erste Schritt getan kann ich schon recht 
gut weiter arbeiten. Wollte das hier dann auch kontinuierlich aufzeigen 
was sich tut, hilft mit Sicherheit auch anderen. Auch wollte ich mich 
dann Schritt für Schritt von dem Board trennen und eine eigenes Board 
aufbauen, um so auch zu wissen was ich da mache.

Und jetzt bin ich gespannt welch eine Resonanz ich auf diesen Post 
bekomme.

von Captain S. (captainsubtext)


Lesenswert?

Ich schubse dich dann mal zum AVR-Tutorial. SCHUBS! ;)

von Holger P. (Gast)


Lesenswert?

Schon mal klasse und danke.

Ich muss dem µC am Anfang erst mal sagen wie er die Ports zu behandeln 
hat. Ob diese als Ausgang oder als Eingang geschalten sind. Das kann ich 
sogar für jedes Bit machen ist doch prima.

In meinem Fall bei dem AT-Tiny 2313 also PortB und PortD.

Soweit so gut aber warum hat der nur PD0-PD6. Was mache ich mit PD7?

PD0=RX der RS232 =Eingang =0
PD1=TX der RS232 =Ausgang =1
PD2=Disable U2270B=Ausgang=1
PD3=Daten vom U2270B=Eingang=0
PD4-PD6=Taster=Eingang=0
PD7=?????????

0b?0000110

Bei PortB ist es klar, alle auf Ausgang 0b11111111 Sperre ich mich dann 
auch nicht aus, im Bezug auf den ISP?

Da man DDRB und DDRD nicht direkt beschreiben kann nimmt man sich ein 
Register r16-r31 zuhilfe.

Und der AT-Tiny 2313 benötigt tn2313def.inc und nicht 2313def.inc

Und schon bin ich bei den ersten Zeilen wieder am fragen Was mache ich 
mit PortD.7 (PD7)
1
.include "tn2313def.inc " 
2
3
ldi  r16,  0b11111111
4
out  DDRB,  r16
5
ldi  r16,  0b?0000110
6
out  DDRB,  r16

von Captain S. (captainsubtext)


Lesenswert?

Holger P. schrieb:
> Schon mal klasse und danke.
>
> Ich muss dem µC am Anfang erst mal sagen wie er die Ports zu behandeln
> hat. Ob diese als Ausgang oder als Eingang geschalten sind. Das kann ich
> sogar für jedes Bit machen ist doch prima.
>
> In meinem Fall bei dem AT-Tiny 2313 also PortB und PortD.
>
> Soweit so gut aber warum hat der nur PD0-PD6. Was mache ich mit PD7?
PD7 ist nicht vorhanden. Es sollte egal sein, was Du dort 
hineinschreibst. zur Sicherheit würde ich PD7 als Eingang definieren.

> Bei PortB ist es klar, alle auf Ausgang 0b11111111 Sperre ich mich dann
> auch nicht aus, im Bezug auf den ISP?
Nein, du sperrst dich so nicht aus: Programmiert wird der Chip im 
Reset-Zustand, dort sind alle Pins standardmäßig Eingänge.

> Da man DDRB und DDRD nicht direkt beschreiben kann nimmt man sich ein
> Register r16-r31 zuhilfe.
>
> Und der AT-Tiny 2313 benötigt tn2313def.inc und nicht 2313def.inc
>
> Und schon bin ich bei den ersten Zeilen wieder am fragen Was mache ich
> mit PortD.7 (PD7)
>
>
1
> .include "tn2313def.inc "
2
> 
3
> ldi  r16,  0b11111111
4
> out  DDRB,  r16
5
> ldi  r16,  0b?0000110
6
> out  DDRB,  r16
7
>

Ab hier musst Du allein weiterforschen, Assembler ist nicht meine 
Sprache. Viel Erfolg ;)

von Holger P. (Gast)


Lesenswert?

Noch mal danke...

Also
1
.include "tn2313def.inc " 
2
3
ldi  r16,  0b11111111
4
out  DDRB,  r16
5
ldi  r16,  0b00000110
6
out  DDRD,  r16

So nun versuche ich mal ein wenig und werde natürlich berichten.

von Holger P. (Gast)


Lesenswert?

So der Tagesabschluss ist gemacht und den ersten Schritt habe ich auch 
geschafft. Programmer USB-Lap Läuft AVR-Studio ist installier und LED’s 
blinken munter hin und her. Es kann los gehen grins

Wobei ich noch eine Frage habe, weiß jemand wie ich an PB7 (SCK) und PB6 
(MISO) eine LED anschließen kann so das ich sie beim Programm 
überspielen nicht mit einen Jumper kappen muss. Wie anfangs gesagt 
liegen die momentan mit 220Ohm gegen Masse.

Ach ja mein erstes Assemblerprogramm und der erste Schritt in die ATMEL 
Geschichte sieht nun so aus:
1
.INCLUDE "tn2313def.inc"
2
3
  ldi  r16, 0b11111111
4
  out  DDRB, r16
5
  ldi  r16, 0b00000110
6
  out DDRD, r16
7
8
  cbi  PortD,2
9
  
10
Loop:
11
12
  cbi  PortB,7
13
  sbi  PortB,6
14
15
  rcall Warte
16
17
  cbi  PortB,6
18
  sbi  PortB,7
19
    
20
  rcall Warte 
21
22
  rjmp Loop
23
24
25
Warte:
26
  ldi r16, $10
27
S0:
28
  ldi r17, $ff
29
S1: 
30
  ldi r18, $ff 
31
S2: 
32
  dec r18
33
  cpi r18, 0 
34
  brne S2
35
  dec r17
36
  cpi r17, 0 
37
  brne S1
38
  dec r16
39
  cpi r16, 0
40
  brne S0
41
  ret

von Holger P. (Gast)


Lesenswert?

Langes versuchen und tüfteln hat mich zu folgender Schleife bewegt:
1
; ============================= 
2
;    Delay 
3
;    500ms:
4
; ----------------------------- 
5
Delay500ms:
6
         ldi  Dummy1, $24
7
S1:      ldi  Dummy2, $BC
8
S2:      ldi  Dummy3, $C4
9
S3:      dec  Dummy3
10
         brne S3
11
         dec  Dummy2
12
         brne S2
13
         dec  Dummy1
14
         brne S1
15
         ret

Zum einem komme ich auf 500000.38µs was aber mal nebensächlich sein 
sollte.

Jetzt habe ich beim rum stöbern etwas von Macros gelesen, so könnte ich 
das ganze doch Ihrgendwie variabel gestallten. Also habe ich folgendes 
erst mal umgesetzt.

1
; ============================= 
2
;    Delay 
3
;    $24,$BC,$C4 = 500ms:
4
; ----------------------------- 
5
.macro  Delay
6
         ldi  Dummy1, @0
7
S1:      ldi  Dummy2, @1
8
S2:      ldi  Dummy3, @2
9
S3:      dec  Dummy3
10
         brne S3
11
         dec  Dummy2
12
         brne S2
13
         dec  Dummy1
14
         brne S1
15
.endmacro

Der aufruf mit
1
    Delay $24,$BC,$C4

klappt auch es kommen zwar nun 499999.50µs raus aber wie getippt erst 
mal OK.

Jetzt meine Frage wie kann ich das umgestallten das ich
1
    Delay 500000

aufrufe?

In F_CPU habe ich meine 8000000 deklariert und 500000 ist das 16 fache 
von 8000000 da muss doch was zu machen sein. Ich muss ja bei 8000000Hz 
4000000 Cycle verbraten

von Holger P. (Gast)


Lesenswert?

Ich hoffe ja das hier der eine oder ander mal liest. Wollte nun nicht 
bei jeder Frage einen neuen Thread erstellen.

Habe wieder eine Frage :-)

Ist das so richtig das ein Interrupt ausgelöst wird beim eintreffen 
eines Zeichen auf der RS232?

1
.org 0x000          ; kommt ganz an den Anfang des Speichers
2
    rjmp RESET      ; Interruptvektoren überspringen
3
                    ; und zum Hauptprogramm
4
    
5
    reti          ; IRQ0 Handler
6
    reti          ; IRQ1 Handler
7
    reti          ; Timer/Counter2 Compare Match 
8
    reti          ; Timer/Counter2 Overflow 
9
    reti          ; Timer1 Capture Handler
10
    reti          ; Timer1 CompareA Handler
11
    reti          ; Timer1 CompareB Handler
12
    reti          ; Timer1 Overflow Handler
13
    reti          ; Timer0 Overflow Handler
14
    reti          ; SPI Transfer Complete Handler
15
    rjmp InRS232 ; USART RX Complete Handler
16
    reti          ; UDR Empty Handler
17
    reti          ; USART TX Complete Handler
18
    reti          ; ADC Conversion Complete Interrupthandler
19
    reti          ; EEPROM Ready Handler
20
    reti          ; Analog Comparator Handler
21
    reti          ; Two-wire Serial Interface Handler
22
    reti          ; Store Program Memory Ready Handler
23
24
RESET:      ; hier beginnt das Hauptprogramm  
25
26
    ; Stackpointer initialisieren
27
    ldi Dummy1, low(RAMEND) ;stack 
28
    out SPL, Dummy1 
29
30
    ; Ports initialisieren
31
    ldi  Dummy1, 0b11111111
32
    out  DDRB, Dummy1
33
    ldi  Dummy1, 0b00000110
34
    out DDRD, Dummy1
35
36
    ; Baudrate einstellen
37
    ldi     Dummy1, HIGH(UBRR_VAL)
38
    out     UBRRH, Dummy1
39
    ldi     Dummy1, LOW(UBRR_VAL)
40
    out     UBRRL, Dummy1
41
 
42
    ; Frame-Format: 8 Bit 
43
    ldi Dummy1, (1<<UCSZ1) | (1<<UCSZ0) ; 8 Bit Daten kein Paraty, 1 Stopbit
44
    out UCSRC, Dummy1 
45
46
    ldi Dummy1, (1<<TXEN) | (1<<RXCIE) | (1<<RXEN) ; TX aktivieren Interrupt bei Empfang RX (Empfang) aktivieren
47
    out UCSRB, Dummy1
48
  
49
    sei
50
51
Endlos:
52
    rjmp Endlos
53
54
InRS232:
55
    push Zeichen      ; Zeichen sichern (auf Stack legen)
56
    in   Zeichen,UDR  ; Empfangenes Zeichen holen Interrupt löschen
57
    pop  Zeichen      ; Zeichen wiederherstellen
58
    sbi  PortB,6      ; Setzt PortB Bit 6 (LED an)
59
    sbi  PortB,7      ; Setzt PortB Bit 7 (LED an)
60
    reti              ; Zurück aus dem Interrupt

Wenn ja... warum geht PortB,6 und PortB,7 wohl nicht an?

von Holger P. (Gast)


Lesenswert?

OK eventuell lesen hier ja andere mit und ich kann ihnen durch meine 
erkentnisse weiterhelfen.

Der ATtiny2313 hat andere IRQ-Vektoren
1
.org 0x000          ; kommt ganz an den Anfang des Speichers
2
    rjmp RESET      ; Interruptvektoren überspringen
3
                    ; und zum Hauptprogramm
4
    
5
    reti          ; IRQ0 Handler
6
    reti          ; IRQ1 Handler
7
    reti          ; Timer/Counter1 Capture Event
8
    reti          ; Timer/Counter1 Compare Match A
9
    reti          ; Timer/Counter1 Overflow
10
    reti          ; Timer/Counter0 Overflow
11
    rjmp InRS232  ; USART0, Rx Complete
12
    reti          ; USART0 Data Register Empty
13
    reti          ; USART0, Tx Complete
14
    reti          ; Analog Comparator
15
    reti          ; Pin Change Interrupt
16
    reti          ; Timer/Counter1 Compare Match B
17
    reti          ; Timer/Counter0 Compare Match A
18
    reti          ; Timer/Counter0 Compare Match B
19
    reti          ; USI Start Condition
20
    reti          ; USI Overflow
21
    reti          ; EEPROM Ready
22
    reti          ; Watchdog Timer Overflow

Also diese Frage ist geklärt.

von spess53 (Gast)


Lesenswert?

Hi

> reti          ; IRQ0 Handler
>     reti          ; IRQ1 Handler
>     reti          ; Timer/Counter2 Compare Match
>     reti          ; Timer/Counter2 Overflow
>     reti          ; Timer1 Capture Handler
>     reti          ; Timer1 CompareA Handler
>     reti          ; Timer1 CompareB Handler
>     reti          ; Timer1 Overflow Handler
>     reti          ; Timer0 Overflow Handler
>     reti          ; SPI Transfer Complete Handler
>     rjmp InRS232 ; USART RX Complete Handler
>     reti          ; UDR Empty Handler
>     reti          ; USART TX Complete Handler
>     reti          ; ADC Conversion Complete Interrupthandler
>     reti          ; EEPROM Ready Handler
>     reti          ; Analog Comparator Handler
>     reti          ; Two-wire Serial Interface Handler
>     reti          ; Store Program Memory Ready Handler

Wo hast du denn die IV-Tabelle her. Die passt nicht zu ATTiny2313.
1
                   rjmp RESET              ; Reset
2
                   rjmp EXT_INT0           ; IRQ0 Request
3
                   rjmp EXT_INT1           ; IRQ1 Request
4
                   rjmp TIMER1_CAPT        ; Timer1 Capture
5
                   rjmp TIMER1_COMPA       ; Timer1 CompareA
6
                   rjmp TIMER1_OVF         ; Timer1 Overflow
7
                   rjmp TIMER0_OVF         ; Timer0 Overflow
8
                   rjmp USART_RXC          ; USART, Rx Complete
9
                   rjmp USART_UDRE         ; USART Data Register Empty
10
                   rjmp USART_TXC          ; USART, Tx Complete
11
                   rjmp ANA_COMP           ; Analog Comparator
12
                   rjmp PC_INT             ;
13
                   rjmp TIMER1_COMPB       ;
14
                   rjmp TIMER0_COMPA       ;
15
                   rjmp TIMER0_COMPB       ;
16
                   rjmp USI_START          ; USI Start Condition
17
                   rjmp USI_OVERFLOW       ; USI Overflow
18
                   rjmp EEPROM_Ready       ;
19
                   rjmp WDT_OVERFLOW       ; Watchdog Timer Overflow

MfG Spess

von Holger P. (Gast)


Lesenswert?

spess53 schrieb:
>
> Wo hast du denn die IV-Tabelle her. Die passt nicht zu ATTiny2313.
>
>
> MfG Spess

Jo hättest du mir das mal getippt bevor ich es selber hier aufgezeigt 
habe hättest du mir schon geholfen ;-)

von spess53 (Gast)


Lesenswert?

Hi

>Jo hättest du mir das mal getippt bevor ich es selber hier aufgezeigt
>habe hättest du mir schon geholfen ;-)

Leider habe ich ca. 5 Minuten gebraucht, um deinen Fehler zu finden und 
die Antwort zu schreiben. Entschuldige.

MfG Spess

von Holger P. (Gast)


Lesenswert?

So warst du wesendlich schneller als ich... ich brauchte fast eine 
Stunde

von spess53 (Gast)


Lesenswert?

Hi

Solche einfache Programme oder Routinen kann man auch in Simulator 
testen. In dem Fall bis zur Endlosschleife laufen lassen. Im I/O-View im 
Register UART->UCSRA RXC anklicken und schon hüpft das Programm in die 
Interruptroutine. Noch etwas: In Interruptroutinen immer SREG sichern.
1
xyz:          push r16
2
              in r16,SREG
3
              push r16
4
              ....
5
6
              pop r16
7
              out SREG,r16
8
              pop r16
9
              reti

MfG Spess

von Bernd V. (volker88)


Angehängte Dateien:

Lesenswert?

Hallo an alle,

Ich habe ein Problem, unswar komme ich nicht weiter mit der Aufgabe.
Könnte vielleicht einer von Ihnen so lieb sein und den Lösungsansatz wie
ich das in dem Programm oder bzw erklären wie ich da vorgehen muss. Ich
habe wirklich keine Ahnung. Ich studiere in Frankfurt Informations
Nachrichtentechnik und habe nun keine Ahnung uns wurde auch keine
Informationen darüber gegeben. Freue mich schon auf Leute  die mir
bestimmt bei dieser Sache behilflich sein können.

von Holger P. (Gast)


Lesenswert?

Jetzt wird es ernst.

Erstmal danke für die Hilfe die ich bis jetzt bekommen habe. Geht ja 
schon recht gut vorran bei mir. Ob das alles soweit ok ist werde ich zum 
Schluss mal befragen. Stehe aber gerade vor einer Frage, und zwar

Ich möchte eine Zeichenkette die ich im SRAM liegen habe mit 
verschiedenen anderen Zeichenketten vergleichen

Also aller

IF Empfang=’Kanal 1=an’ then Tralllalal

Muss ich nun wirklich Zeichen für Zeichen vergleiche
1
ldi   xl,low(RS232Buffer)
2
ldi   xh,high(RS232Buffer)
3
ld Dummy,x+
4
cpi Dummy,’K’
5
brne Weiter1
6
rjmp Fehler
7
Weiter1:
8
ld Dummy,x+
9
cpi Dummy,’a’
10
brne Weiter2
11
rjmp Fehler
12
Weiter2:
13
ld Dummy,x+
14
cpi Dummy,’n’
15
brne Weiter3
16
rjmp Fehler
17
u.s.w

Ich wollte das aber mit nicht nur ein Kommando machen… das wird ja ellen 
lang :-(
Suche keinen fertige Code sondern wieder nur ein schupser

Ich wollte das hier ( alles nur ein test um in die Geschichte rein zu 
kommen ) einsetzen
1
    ; Zeichen von der RS232 empfangen und auswerten;
2
InRS232:
3
    push  Dummy1
4
    in    Dummy1,SREG
5
    push  Dummy1
6
7
    in    EZeichen,udr                  ; Empfangenes Zeichen holen Interrupt löschen
8
    cpi   EZeichen,13                   ; Wurde Enter gesendet?
9
    brne  Speichern                     ; Kein Enter Zeichen in SRAM Speichern
10
  
11
  
12
  
13
Hier wollte ich vergleichen  
14
  
15
  
16
    ; Meldung Syntax error ausgeben.
17
    ldi     zl,low(SError*2);            ; Z Pointer laden
18
    ldi     zh,high(SError*2);
19
    rcall   serout_string                 ; Ausgabe des Strings RS232 Routine
20
    
21
    ldi Dummy1,0                         ; Zeiger wieder vorne
22
    sts RS232Zeiger,Dummy1  
23
    rjmp  Ende_InRS232
24
25
Speichern:
26
    ldi   xl,low(RS232Buffer-1)         ; X Pointer laden
27
    ldi   xh,high(RS232Buffer-1)        ;
28
    
29
    lds   Dummy1,RS232Zeiger            ; den RS232-Zeiger aus dem Speicher holen
30
    inc   Dummy1                        ; Zeiger um eins weiterschieben
31
    cpi   Dummy1,21                     ; Auf Speichergrenze von 20 Byte testen 
32
    brne  SOK                           ; Noch keine 20 Byte 
33
    ldi   Dummy1,1                       ; 20 Byte überschritten wieder bei 1 anfangen  
34
SOK:
35
    sts   RS232Zeiger,Dummy1
36
ZeigerStellen:
37
    adiw  xl:xh,1                       ; Zeiger erhöhen
38
    dec   Dummy1
39
    brne  ZeigerStellen
40
    st    x,EZeichen                    ; Zeichen ins SRAM
41
Ende_InRS232:
42
    pop   Dummy1
43
    out   SREG,Dummy1
44
    pop   Dummy1
45
    reti              ; Zurück aus dem Interrupt

von Holger P. (Gast)


Lesenswert?

OK OK man sollte erst überlegen und dann fragen :-)

Es geht ich habe es folgenderweise gelöst:
1
    ; Kommandos vergleichen
2
    ldi   zl,low(K_Gelb_an*2);    ; Z Pointer laden
3
    ldi   zh,high(K_Gelb_an*2)    ;  
4
  
5
    ldi   xl,low(RS232Buffer)     ; X Pointer laden
6
    ldi   xh,high(RS232Buffer)    ;
7
  
8
KV1:
9
    lpm                           ; nächstes Byte aus dem Flash laden
10
    adiw  zl:zh,1                 ; Zeiger erhöhen
11
    and   r0,r0                   ; = Null? 
12
    brne  KV1W                    ; Weiter vergleichen da noch nicht Null
13
    rjmp  V1OK                    ; Vergleich fertig und somit OK 
14
KV1W:    
15
    ld    Dummy1,x                ; Zeichen aus SRAM holen
16
    adiw  xl:xh,1                 ; Zeiger erhöhen
17
    cp    r0,Dummy1
18
    brne  KO2
19
    rjmp  KV1
20
  
21
V1OK:
22
    ; Meldung LED gelb auf RS232 ausgeben.
23
    ldi     zl,low(LEDGelb_an*2)          ; Z Pointer laden
24
    ldi     zh,high(LEDGelb_an*2)         ;
25
    rcall   serout_string                 ; Ausgabe des Strings RS232 Routine
26
    sbi    PortB,7                         ; Setzt PortB Bit 7 (LED an)
27
    rjmp  KFertig
28
29
KO2:
30
31
    ; Meldung Syntax error ausgeben.
32
    ldi     zl,low(SError*2);            ; Z Pointer laden
33
    ldi     zh,high(SError*2);
34
    rcall   serout_string                ; Ausgabe des Strings RS232 Routine
35
36
    ; Speicher wieder löschen und zeiger auf 0 setzen
37
KFertig:
38
    ldi xl,low(RS232Buffer);            ; Z Pointer laden
39
    ldi xh,high(RS232Buffer);
40
    ldi Dummy2,20    
41
    ldi Dummy1,0
42
    sts RS232Zeiger,Dummy1               
43
BuClear:
44
    st  x+,Dummy1
45
    dec Dummy2
46
    brne BuClear
47
    rjmp  Ende_InRS232

von Holger P. (Gast)


Lesenswert?

Damit das ganze einwenig übersichtlicher wird habe ich mal ein Macro 
gemacht.
1
; ============================= 
2
;    RS232StrComp
3
;    prüfen @0 mit RS232Buffer
4
; ----------------------------- 
5
.macro RS232StrComp
6
    ldi   zl,low(@0*2);    ; Z Pointer laden
7
    ldi   zh,high(@0*2)    ;  
8
  
9
    ldi   xl,low(RS232Buffer)     ; X Pointer laden
10
    ldi   xh,high(RS232Buffer)    ;
11
  
12
KV:
13
    lpm                           ; nächstes Byte aus dem Flash laden
14
    adiw  zl:zh,1                 ; Zeiger erhöhen
15
    and   r0,r0                   ; = Null? 
16
    brne  KVW                     ; Weiter vergleichen da noch nicht Null
17
    rjmp  KVOK                    ; Vergleich fertig und somit OK 
18
KVW:    
19
    ld    Dummy1,x                ; Zeichen aus SRAM holen
20
    adiw  xl:xh,1                 ; Zeiger erhöhen
21
    cp    r0,Dummy1
22
    brne  KVNOK
23
    rjmp  KV
24
KVOK:
25
   ldi Dummy1 ,1
26
   rjmp KEnde 
27
KVNOK:
28
   ldi Dummy1 ,0
29
Kende:
30
.endmacro

aufrufen und auswerten tu ich es so:
1
    ; Kommandos vergleichen
2
    RS232StrComp K_Gelb_aus ; prüfen auf gelb=0
3
    cpi   Dummy1,1
4
    brne  SERR
5
    
6
    ;vergleich war ok 
7
    rjmp  KFertig
8
9
SERR:
10
   ;vergleich war nicht OK
11
   ; Meldung Syntax error ausgeben.
12
    ldi     zl,low(SError*2);            ; Z Pointer laden
13
    ldi     zh,high(SError*2);
14
    rcall   serout_string                ; Ausgabe des Strings RS232 Routine
15
    
16
    ; Speicher wieder löschen und zeiger auf 0 setzen
17
KFertig:
18
    ldi xl,low(RS232Buffer);            ; Z Pointer laden
19
    ldi xh,high(RS232Buffer);
20
    ldi Dummy2,20    
21
    ldi Dummy1,0
22
    sts RS232Zeiger,Dummy1               
23
BuClear:
24
    st  x+,Dummy1
25
    dec Dummy2
26
    brne BuClear
27
    rjmp  Ende_InRS232

von spess53 (Gast)


Lesenswert?

Hi

>Damit das ganze einwenig übersichtlicher wird habe ich mal ein Macro
>gemacht.

Dir ist aber bewusst, das jeder Macroaufruf den kompletten Code 
erzeugt?

Für identische Programmteile benutzt man Unterprogramme:
Deinen Code habe ich mal etwas komprimiert.
1
KV:     push r16
2
        push r17
3
XXX:    lpm   r16,Z+                  ; nächstes Byte aus dem Flash laden
4
        tst r16                       ; = Null? 
5
        breq  Kende                   ; Vergleich fertig und somit OK 
6
KVW:    ld    r17,X+                  ; Zeichen aus SRAM holen
7
        cp    r16,r17
8
        brne  Kende
9
        rjmp  XXX
10
Kende:  pop r17
11
        pop r16
12
        ret

Und mit dem Unterprogramm machst du dann ein Macro:
1
.macro RS232StrComp
2
    ldi   zl,low(@0*2);    ; Z Pointer laden
3
    ldi   zh,high(@0*2)    ;  
4
  
5
    ldi   xl,low(RS232Buffer)     ; X Pointer laden
6
    ldi   xh,high(RS232Buffer)    ;
7
  
8
    call KV
9
.endmacro

Das:

>    RS232StrComp K_Gelb_aus ; prüfen auf gelb=0
>    cpi   Dummy1,1
>    brne  SERR
>
>    ;vergleich war ok
>    rjmp  KFertig

reduziert sich zu
1
    RS232StrComp K_Gelb_aus ; prüfen auf gelb=0
2
    brne  SERR
3
    rjmp  KFertig ;vergleich war ok

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Nachtrag: Erstetze das 'call KV' im Macro durch 'rcall KV'. Dein ATTiny 
kennt kein 'call'.

MfG Spess

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

@spess53: Erst mal Danke. Ich merke da gibt es noch viel zu lernen.

So es ist viel Zeit vergangen und ich musste auch für die Schule einiges 
machen. Aber nun bin ich dabei mir erst einmal ein Entwicklungsboard zu 
bauen.

Es ist mir klar dass es fertige gibt, denke dass wenn man eins selber 
macht es auch versteht.

So habe ich mal angefangen ein Schaltplan zu zeichnen. Schon allein das 
mit Eagle zu machen war schon echt ein schweres erlernen.

Nun meine Frage, könnte da mal jemand drüber schauen ob das so gehen 
könnte. Ich möchte die Quarzbeschaltung ausschalten können und auch 
eventuell die Resetleitung als Port benutzen können deswegen JP1-JP3. 
Das die Schaltung noch lange nicht fertig ist, ist mir klar aber ich 
möchte eventuelle Fehler schon am Anfang vermeiden.

von oldmax (Gast)


Lesenswert?

Hi
Nun, ein Board slber bauen, dazu  würd ich dir einen anderen Weg 
vorschlagen. Du hast doch das Pollin Board, warum nimmst du nicht ein 
Steckbrett, schaffst eine Verbindung vom Pollin Board zum Steckbrett und 
übst mit "gesteckten" Versuchen. Irgendwann erkennst du, du brauchst ein 
Controller-Universalmodul. Ein kleines Platinchen, welches einfach nur 
einen Controller am Leben erhält. Dann kommt der nächste Schritt: eine 
universelle IO mit Relais und so'n Zeug. Der Controller kann dann auch 
schon mal etwas größer ausfallen.... Irgendwann hast du auch mal 
verstanden, wie serieller Datentransfer geht und du kannst mit Hilfe von 
OpenEye, das hab ich hier irgendwo mal reingestellt, dir den Zustand der 
Variablen im Controller zur Laufzeit ansehen. Meine Schaltungen werden 
alle mit dieser Schnittstelle ausgerüstet, so kann ich mir ansehen, ob 
die Bits nach meinen Wünschen reagieren. Fehlersuche wird dann etwas 
leichter. Alles was du dazu brauchst steht in den Tutorials. Die Zeit, 
die du mit einem Selbstbauboard verbrätst, meine ich, kannst du 
sinnvoller nutzen.
Gruß oldmax

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:

> Nun meine Frage, könnte da mal jemand drüber schauen ob das so gehen
> könnte.

Ist ja noch nicht viel zu sehen. Ausser Netzteil und ISP Anschluss ist 
ja nichts da?

Ein gut gemeinter Rat:
Konzentrier dich bei deinem ersten Board auf nur 1 Prozessor. Du wirst 
sonst enorme Schwierigkeiten mit dem Routing bekommen.
1 Prozessor auf einem Board so zu routen, dass du alle Portanschlüsse 
sauber auf Stiftleisten rausgeführt kriegst, ist schon Arbeit genug.

Lieber 4 Universalboards für 4 verschiedene Prozessoren mit immer 
denselben Stiftleisten um dort Universal-I/O Boards anzuschliessen, als 
alles auf einem Board.
Für jeden Port eine 10-polige Stiftleiste, 8-Datenbits + Vcc + GND. Das 
ganze als 2*5 Pins in einem Wannenstecker und du bist für Erweiterungen 
und Erweiterungsboards mit Peripherie gerüstet.

> eventuell die Resetleitung als Port benutzen können

das ist keine so gute Idee.
Das Problem: Wenn du Reset nicht als Portpin benutzen kannst, büsst du 
kaum Funktionalität ein (die kleinen Tinys mal ausgenommen). Wenn du dir 
aber Reset wegfused, dann hast du dich mit dem ISP Programmer 
ausgesperrt. Und da kann dir dann auch dein USB-AVRLab nicht mehr 
helfen. Also lieber gar nicht erst in Versuchung bringen.

Und immer drann denken: Jeder Jumper der gesteckt werden muss, ist ein 
potentieller Kandidat, dass man auf ihn vergisst.

> deswegen JP1-JP3.
> Das die Schaltung noch lange nicht fertig ist, ist mir klar aber ich

Schau bitte ins Platinen-Forum. Da gibt es jede Menge Threads, in denen 
Leute um Durchsicht ihrer ersten µC-Schaltung bitten. Dort findest du 
jede Menge Standardprobleme und Dinge, die es zu beachten gilt (auch 
wenn dort manchmal IMHO ein wenig übertrieben wird)


> möchte eventuelle Fehler schon am Anfang vermeiden.

von Holger P. (Gast)


Lesenswert?

OK so werde ich versuchen ein Board für jeden Prozessor zu bauen. Als 
erstes nehme ich mir mal den Mega8 vor.

Danke für die Tipps.. echt klasse Forum.

Resetleitung ohne Jumper.. OK leuchtet mir ein.
Wie sieht das mit dem Quarz aus? Da ich wohl hin und wieder mal versuche 
mit dem Internen Oszilator machen möchte wäre das doch OK oder?

Auch die Idee alles andere auf extra Platinen zu bauen und nur Platinen 
zu machen die das nötigste beinhalten ist wohl keine schlechte Idee.

So werde ich den Schaltplan erst mal umgestalten.

Aber das mit dem Quarz ist so OK?

Ach ja das Pollin-Board möchte ich nicht mehr nehmen muss laufend den 
U2270B abschalten und habe einige Leitungen nicht weil sie auf den Chip 
gehen.

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:

> Wie sieht das mit dem Quarz aus? Da ich wohl hin und wieder mal versuche
> mit dem Internen Oszilator machen möchte wäre das doch OK oder?

Mega8 ist ein Sonderfall. Ohne Quarz kann man die Pins als Portpins 
benutzen.
Beim Mega16 sind die Quarzanschlüsse sowieso extra. Der Quarz stört auch 
nicht, wenn der interne Oszi läuft.

> Auch die Idee alles andere auf extra Platinen zu bauen und nur Platinen
> zu machen die das nötigste beinhalten ist wohl keine schlechte Idee.

Ich hab meine so aufgebaut

* Platine mit Mega16 drauf, dazu noch MAX232 den ich an die Rx/Tx Pins
  Jumpern kann und RS232 Buchse drauf.
  Alle Ports sind auf Wannenstecker rausgeführt.
  Dazu noch ein 7805
  Mehr ist da nicht auf der µC Platine drauf (Hühnerfutter natürlich)

* I/O Board mit 8 LED drauf. Ebenfalls Wannenstecker als Eingang,
  der aber wieder auf einen Ausgang geführt wird, sodass ich diese
  Platine zwischen µC und eine andere Peripherieplatine schalten kann
  und dann mit den LEDs die Steuersignale zu dieser Peripherie sehe

  Von dieser Platine gibt es 2 Bestückungs-Varianten
  einmal nur 8 Led, einmal sind da auch noch 8 Taster mit drauf, für
  Eingabezwecke.

* I/O Board mit Relais

* I/O Board mit einem LCD

* I/O Board mit Potis (jedes Poti einzeln per Jumper auf seine Leitung
  schaltbar)

* weitere Standard-Module werden folgen
  (7-Seg, etc)

* Spezialflachbandkabel, mit dem ich vom µC-Modul auf ein Steckbrett
  gehen kann, für alles was mehr an Aufbau braucht.


Das ganze ist ein recht universeller Baukasten, bei dem die einzelnen 
'Module' mit Flachbandkabeln mit 10-poligen Buchsen an beiden Enden 
verbunden werden können. Und das beste: Ich kann jede I/O Platine an 
jeden Port anstecken, je nachdem wie er mir am besten passt und welche 
Spezialpins frei bleiben müssen.

von Holger P. (Gast)


Lesenswert?

Das hört sich nicht schlecht an. Das werde ich so auch mal versuchen. 
Werde hier berichten.

Kann immer nur wieder sagen Klasse Forum/User DANKE

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

So der Schaltplan ist soweit fertig. Mir ist nur unklar was mache ich 
mit AVCC, AREF und AGND? Eine feste Beschaltung könnte mich doch im 
Nachhinein behindern oder. Um die Flexibilität zu bewaren müsste ich 
diese auch raus legen? Kann mir da jemand helfen? Ansonsten dürfte das 
so alles gehen glaube ich.

Ach ja im ersten Schaltplan hatte ich doch echt Plus und Minus nach dem 
Gleichrichter vertauscht, das hätte schön geknallt.

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> So der Schaltplan ist soweit fertig. Mir ist nur unklar was mache ich
> mit AVCC, AREF und AGND? Eine feste Beschaltung könnte mich doch im
> Nachhinein behindern oder.

AVcc    an Vcc
AGND    an GND

AREF  über einen 100nf Kondensator an GND führen.
      Wenns unbedingt sein muss einen Jumper rein, mit dem man diese
      Verbdinung auftrennen kann


Zwischen Vcc + GND  gehört ein 100nF Kondensator und zwar dicht ans µC 
Gehäuse
Zwischen  AVcc + AGND gehört ein 100nF Kondensator und zwar dicht ans µC 
Gehäuse

von Holger P. (Gast)


Lesenswert?

Habe ich nun rein gemacht. Auch dem MAX232 habe ich einen Spendiert. So 
na wie es geht an den µC ist leicht gesagt. Ich habe von meinem Vater 
einen Sockel bekommen, so einen zum auf und zu machen. der ist 23mmx50mm 
und so ist es mir nicht so einfach möglich na an den µC zu gehen.

Aref über einen Jumper werde ich noch mache.

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

So bevor ich nun versuche das zu machen was Eagle nicht alles schafft, 
die Frage aller Fragen. Alles soweit OK? Geht das mit den LED's beim 
MAX232 wollte sehen was da so passiert. Auch die Resetleitung wollte ich 
im Blick haben. Nun ran ans geschehen.

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

Ach ja ich habe das so auf der Platiene aufgeteilt.

von Karl H. (kbuchegg)


Lesenswert?

Geh mit dem Quarz näher an den µC.
Es gibt 2 Dinge, bei denen du die Verbindungsleitungen kurz halten 
willst:
Blockkondensatoren an den IC
Quarzleitungen.


den 7805 würde ich hinlegen. Je weniger Bauteile in die Höhe stehen, 
desto weniger leicht reißt man im Eifer des Gefechts eines runter.
Und einen 7805 aus Versehen 5 mal umgeknickt - irgendwann brechen die 
Beinchen ab.

Reset Taste von vorne. Find ich nicht so praktisch. Die Platine liegt 
vor dir auf den Tisch. Um das Teil zu resetten (kommt selten vor) mit 
dem Finger von oben drauf und reset. Von vorne ist das Gefummel, bis man 
an den Tasterstummel ran kommt.

von Karl H. (kbuchegg)


Lesenswert?

OK. Ist Geschmackssache. 2200µF ist schon reichlich.
Faustregel: Pro Ampere - 1000µF
Dein µC zieht allein vielleicht so 20 bis 50mA. Soll auf den I/O 
Platinen noch was dazu kommen, sinds im Maximum geschätzte 500mA, aber 
das ist dann schon reichlich.

1000µF würden es auch tun.

von Karl H. (kbuchegg)


Lesenswert?

> So bevor ich nun versuche das zu machen was Eagle nicht alles schafft,

Du hast hoffentlich nicht vor, den Autorouter drüber zu lassen :-)

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

Zitat: den 7805 würde ich hinlegen. Je weniger Bauteile in die Höhe 
stehen,
desto weniger leicht reißt man im Eifer des Gefechts eines runter.
Und einen 7805 aus Versehen 5 mal umgeknickt - irgendwann brechen die
Beinchen ab.

********

Ich habe ein Kühlkörber daran deswegen auch der Abstand zwischen ELKO 
und 7805 deswegen glaube ich auch nicht das ich Ihn umbiegen kann der 
ist mit einer 2mm Schraube fest.

********

Zitat: Von vorne ist das Gefummel, bis man
an den Tasterstummel ran kommt.

********

Genau deswegen habe ich ihn gestellt. Soll ja nicht aus versehen 
passieren.

********

Zitat: Platinen noch was dazu kommen, sinds im Maximum geschätzte 500mA, 
aber
das ist dann schon reichlich.

********

Nun ich habe dein Tipp beherzigt und wollte alle externen Zusatzplatinen 
versorgen. Deswegen auch auf jedem 10Pol Stecker Plus und Minus.


********

Zitat: Du hast hoffentlich nicht vor, den Autorouter drüber zu lassen 
:-)

********

Doch sieht gar nicht so schlecht aus. Bin gerade dabei Brücken zu 
verlegen.

Ach ja Danke für deine Antworten echt klasse.

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:

> Ich habe ein Kühlkörber daran deswegen auch der Abstand zwischen ELKO
> und 7805 deswegen glaube ich auch nicht das ich Ihn umbiegen kann der
> ist mit einer 2mm Schraube fest.

Am Kühlkörper.
Aber der Kühlkörper selber ist auch wieder nicht an der Platine 
festgemacht


Man kann einen 7805 auch mit Kühlkörper auf der Platine liegend 
festschrauben.
Aber eigentlich braucht man den Kühlkörper nicht. Falls wirklich mal der 
Fall auftreten sollte, dass der 7805 warm wird, dann fungiert die 
Platine als Kühlkörper.


> Genau deswegen habe ich ihn gestellt. Soll ja nicht aus versehen
> passieren.

Ist mir ehrlich noch nie aus Versehen passiert :-)
Aber in der Zeit als ich noch mit Bootloader gearbeitet habe, war ich 
froh den Reset Taster mit einer Hand und ohne Festhalten der Platine 
bedienen zu können.


> Nun ich habe dein Tipp beherzigt und wollte alle externen Zusatzplatinen
> versorgen. Deswegen auch auf jedem 10Pol Stecker Plus und Minus.

10pol Stecker ist schon ok.
Aber Strom! Was willst du denn anhängen, was soviel Strom braucht und 
nicht über eine eigene Stromversorgung gespeist wird?

>
> Doch, sieht gar nicht so schlecht aus.

Da bin ich neugierig, was der Auto wieder alles verbrochen hat :-)

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

Was für ein Akt.

Das Wochenende ist nun um und mein Board steht und geht :-)

Nun sagen wir so,

Die Spannungsversorgung läuft.
Der Oszillator geht.
Port B – Port C gehen als Ausgang.

Und nun bin ich am Testen der RS232. Bekomme aber kein Zeichen raus. Ob 
es an meiner Hardware liegt. Ich glaube nicht. Ich komme wohl aus der 
Schleife nicht raus.
1
serout:
2
    ldi  Dummy1,UCSR0A
3
    sbrs  Dummy1,UDRE0            ; Warten bis UDR für das nächste Byte bereit ist
4
    rjmp  serout


Aber warum nicht. Beim Tiny2313 hat es doch geklappt.

Wer hilft mir mal wieder?

Der komplette Quelltext sieht so aus:
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1 = r16
4
5
.equ F_CPU = 8000000                            ; Systemtakt in Hz
6
.equ BAUD  = 38400                              ; Baudrate
7
8
; Berechnungen
9
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
10
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
11
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
12
 
13
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
14
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
15
.endif 
16
17
.org 0x000     ; kommt ganz an den Anfang des Speichers
18
  rjmp RESET ; Interruptvektoren überspringen und zum Hauptprogramm
19
20
reti ; $001 External Interrupt Request 0
21
reti ; $002 External Interrupt Request 1
22
reti ; $003 Pin Change Interrupt Request 0
23
reti ; $004 Pin Change Interrupt Request 0
24
reti ; $005 Pin Change Interrupt Request 1
25
reti ; $006 Watchdog Time-out Interrupt
26
reti ; $007 Timer/Counter2 Compare Match A
27
reti ; $008 Timer/Counter2 Compare Match A
28
reti ; $009 Timer/Counter2 Overflow
29
reti ; $00A Timer/Counter1 Capture Event
30
reti ; $00B Timer/Counter1 Compare Match A
31
reti ; $00C Timer/Counter1 Compare Match B
32
reti ; $00D Timer/Counter1 Overflow
33
reti ; $00E TimerCounter0 Compare Match A
34
reti ; $00F TimerCounter0 Compare Match B
35
reti ; $010 Timer/Couner0 Overflow
36
reti ; $011 SPI Serial Transfer Complete
37
reti ; $012 USART Rx Complete
38
reti ; $013 USART, Data Register Empty
39
reti ; $014 USART Tx Complete
40
reti ; $015 ADC Conversion Complete
41
reti ; $016 EEPROM Ready
42
reti ; $017 Analog Comparator
43
reti ; $018 Two-wire Serial Interface
44
reti ; $019 Store Program Memory Read
45
46
RESET: ; Hier beginnt das Hauptprogramm 
47
48
49
; Stackpointer initialisieren
50
ldi Dummy1, high(RAMEND) 
51
out SPH,Dummy1           
52
ldi Dummy1, low(RAMEND)
53
out SPL,Dummy1
54
55
; Ports initialisieren
56
ldi  Dummy1, 0b11111111
57
out DDRB,Dummy1 ; Port-B Ausgang
58
out DDRC,Dummy1 ; Port-C Ausgang
59
ldi  Dummy1, 0b11111110
60
out DDRD,Dummy1 ; Port-D Ausgang PD0=Eingang RXD
61
62
; Baudrate einstellen
63
ldi Dummy1, HIGH(UBRR_VAL)
64
sts UBRR0H, Dummy1
65
ldi Dummy1, LOW(UBRR_VAL)
66
sts UBRR0L, Dummy1
67
68
; RS232 Frame-Format: 8 Bit 
69
ldi Dummy1, (1<<USBS0)|(3<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
70
sts UCSR0C, Dummy1 
71
72
ldi Dummy1, 1<<TXEN0; TX aktivieren 
73
sts UCSR0B, Dummy1
74
75
; Alle Port's auf Low
76
ldi Dummy1,0b00000000
77
out PortB,Dummy1 ; Port B alles auf Low
78
out PortC,Dummy1 ; Port C alles auf Low
79
out PortD,Dummy1 ; Port D alles auf Low
80
81
; Meldung auf RS232 ausgeben.
82
ldi     zl,low(FString*2);            ; Z Pointer laden
83
ldi     zh,high(FString*2);
84
rcall   serout_string                        ; Ausgabe des Strings RS232 Routine
85
86
ldi Dummy1,0b01010101
87
out PortC,Dummy1 ; Musster raus OK.
88
89
The_End:
90
    rjmp The_End
91
92
93
; Ausgabe eines Strings aus dem Flash
94
serout_string:
95
    lpm                             ; nächstes Byte aus dem Flash laden
96
    adiw    zl:zh,1                 ; Zeiger erhöhen
97
  and     r0,r0                   ; = Null? 
98
  brne    serout                  ; wenn nein, -> raus damit
99
  ret                             ; Zurück wo du her gekommen bist 
100
serout:
101
    ldi      Dummy1,UCSR0A
102
    sbrs    Dummy1,UDRE0            ; Warten bis UDR für das nächste Byte bereit ist
103
    rjmp    serout                     
104
    sts     UDR0, R0                ; Zeichen ausgeben
105
    rjmp    serout_string           ; nächstes Zeichen bearbeiten
106
107
FString: .db "******* Hallo kleine Welt *******",13,10,0

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:

> Das Wochenende ist nun um und mein Board steht und geht :-)

Gratulation


> Und nun bin ich am Testen der RS232. Bekomme aber kein Zeichen raus. Ob
> es an meiner Hardware liegt. Ich glaube nicht.

Testen ist besser.

Prozessor aus dem Sockel raus.
Mit einer Drahtbrücke den Pin Tx mit Rx brücken und am PC im 
Terminalprogramm klimpern (lokales Echo am PC abschalten).

Wenn das was du klimperst vom Board zurückkommt, dann ist es nicht die 
Hardware. Gegentest: Brücke raus und das Echo über den µC muss aufhören.

von Holger P. (Gast)


Lesenswert?

Es ist nicht die Hardware. Ich habe LED's an der RS232 ( auf der 12V 
Seite ) auf der Platine links zu sehen. Die gehen beim eingang auf alle 
fälle.

In meinem Code habe icht zum ende
1
ldi Dummy1,0b01010101
2
out PortC,Dummy1 ; Musster raus OK.

un das muster kommt nie. Also hängt er im Code fest.

Aber das mit der Brücke versuche ich mal so oder so... Also PIN 2 und 3 
im Sockel des Meaga kurz... klar Mega vorher raus :-)

von Holger P. (Gast)


Angehängte Dateien:

Lesenswert?

Danke für dein Tipp um die Hardware zu testen.

Hardware geht. Echo kommt und die LED's blinken fein wie sie es sollen.
Verstehe gerade nicht warum in dem anderen Thread gefragt wird wie man 
die LED's an die RS232 anschließen muss. 500Ohm und ab gegen Masse. Nun 
werde ich gleich mal in dem Thread schreiben.

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> Danke für dein Tipp um die Hardware zu testen.
>
> Hardware geht. Echo kommt und die LED's blinken fein wie sie es sollen.

Gut.
Ist doch beruhigend zu wissen, dass da alles klappt und das Kabel auch 
richtig ausgekreuzt ist

1
serout:
2
    ldi      Dummy1,UCSR0A

nicht LDI sondern LDS!

von Karl H. (kbuchegg)


Lesenswert?

1
; RS232 Frame-Format: 8 Bit 
2
ldi Dummy1, (1<<USBS0)|(3<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
3
sts UCSR0C, Dummy1

Braucht der 88 kein URSEL?
(Ich hab nicht nachgesehen, ich frag nur)

von Holger P. (Gast)


Lesenswert?

Mit LDS kommt nun was und das Programm läuft auch durch, hängt also 
nicht mehr.

URSEL mal schauen was das ist. Bin wie getippt noch total am anfang. 
Beim Tiny2313 ging es so.

von Spess53 (Gast)


Lesenswert?

Hi

>Braucht der 88 kein URSEL?

Nein.

MfG Spess

von Holger P. (Gast)


Lesenswert?

Habe eben hier im Forum gesucht und folgendes gefunden.

Joachim B. schrieb:
> Eine "Tücke" bei dem 88er: hast du das CKDIV8-Fuse noch gesetzt? das ist
> standardmäßig gesetzt, glaub ich. In die Falle bin ich zu beginn auch
> getappt :)
>
> Gruß


Aber auch das nicht setzen des CKDIV8-Fuse zeigt mir noch wirr warr an.

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> Mit LDS kommt nun was und das Programm läuft auch durch, hängt also
> nicht mehr.

D.h. die kriegst díe falschen Zeichen?

Dann ist dein nächster abzuklärender Punkt der hier
1
.equ F_CPU = 8000000                            ; Systemtakt in Hz

Nur weil du einen Quarz auf der Platine hast, bedeutet das nicht, dass 
er auch benutzt wird.

Probehalber kannst du ja mal
1
.equ F_CPU = 1000000                            ; Systemtakt in Hz

probieren (alle Megas werden mit 1Mhz ausgeliefert)

von Holger P. (Gast)


Lesenswert?

Wenn ich den Quarz raus nehme geht nix mehr habe ich schon getestet. 
Aber ich werde mal einen anderen Quarz nehemn. Habe die Fuse auf Extern 
gesetzt.

Ext. Crystal Osc. 8.0-    MHz; Start-up time PWRDWN/RESET: 258 CK/14 CK 
+ 65 ms

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> Wenn ich den Quarz raus nehme geht nix mehr habe ich schon getestet.

Gut

> Aber ich werde mal einen anderen Quarz nehemn. Habe die Fuse auf Extern
> gesetzt.
>
> Ext. Crystal Osc. 8.0-    MHz; Start-up time PWRDWN/RESET: 258 CK/14 CK
> + 65 ms


Passt auch.
Bleibt nur noch die CKDIV8 Fuse.


Hast du eigentlich einen C-Compiler bei dir?
In C wäre ein Testprogramm schnell geschrieben, mit dem man die 
tatsächliche Arbeitsgeschwindigkeit schnell feststellen oder zumindest 
abklären kann.

von Holger P. (Gast)


Lesenswert?

Ne du.

Bin froh wenn ich ein Zeichen aus der RS232 bekomme. An solche Programme 
versuche ich mich lieber nicht.

Ich glaube schon das es was mit der Baudrate zutun hat

38400 8-N-1 sollte das sein
1
.equ F_CPU = 8000000                            ; Systemtakt in Hz
2
.equ BAUD  = 38400                              ; Baudrate
3
4
; Berechnungen
5
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
6
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
7
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
8
 
9
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
10
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
11
.endif 
12
13
14
15
16
17
18
19
; Baudrate einstellen
20
ldi Dummy1, HIGH(UBRR_VAL)
21
sts UBRR0H, Dummy1
22
ldi Dummy1, LOW(UBRR_VAL)
23
sts UBRR0L, Dummy1
24
25
; RS232 Frame-Format: 8 Bit 
26
ldi Dummy1, 1<<TXEN0 ; TX aktivieren 
27
sts UCSR0B, Dummy1
28
29
ldi Dummy1, (1<<USBS0)|(3<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
30
sts UCSR0C, Dummy1

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> Ne du.
>
> Bin froh wenn ich ein Zeichen aus der RS232 bekomme. An solche Programme
> versuche ich mich lieber nicht.
>
> Ich glaube schon das es was mit der Baudrate zutun hat

Mit Sicherheit.
Und in 99% aller Fälle hat es damit zu tun, dass das hier

> .equ F_CPU = 8000000                            ; Systemtakt in Hz

nicht stimmt :-)

Deine LED sitzen noch mal wo?
(Dann schreib ich schnell ein Testprogramm)

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:

> Deine LED sitzen noch mal wo?
> (Dann schreib ich schnell ein Testprogramm)

Schon gesehen.
Port C. Anscheinend 8 Stück :-)

von Holger P. (Gast)


Lesenswert?

Ich habe an allen Port's LED's. Die LED an RXD und TXD sitzt direkt 
hinter dem MAX an der 12Volt Seite. An Port C habe ich aber nur 6 LED's 
PC6=Reset und PC7 gibt es ja nicht

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

ok

Das ist das Testprogramm
1
/*
2
 
3
  Testprogramm für CPU Takt
4
  Hier die vermeintliche Taktrate des µC eintragen
5
  Im Beispiel hier: 1Mhz
6
  
7
  */
8
  #define F_CPU 8000000
9
 
10
  #include <avr/io.h>
11
  #include <util/delay.h>
12
 
13
  /*
14
     Hier die tatsächlich verwendeten Parameter angeben
15
  */
16
 
17
  #define LED_PORT    PORTC
18
  #define LED_DDR     DDRC
19
  #define LED_PIN     PC0
20
 
21
  int main()
22
  {
23
    LED_DDR |= (1<<LED_PIN);
24
 
25
    while( 1 ) {
26
      LED_PORT ^= (1<<LED_PIN);
27
      _delay_ms(1000);
28
    }
29
  }

im Anhang das Hex-File, compiliert für einen Mega88.

Wenn dein Mega88 mit 8 Mhz läuft, dann ist die LED am POrt C, Pin 0 1 
Sekunde an, 1 Sekunde aus.
Läuft er mit 1 Mhz, dann ist sie 8 Sekunden an, 8 Sekunden aus.

von Holger P. (Gast)


Lesenswert?

Alle ports sind High nur PC0 Pin23 Blinkt fein im Sekundentakt. Selbst 
TXD hinterm MAX ist High

von Karl H. (kbuchegg)


Lesenswert?

Holger P. schrieb:
> Alle ports sind High nur PC0 Pin23 Blinkt fein im Sekundentakt.

OKay.
Dann ist es diesmal ausnahmsweise nicht die Prozessor-Taktfrequenz :-)

<Nochmal Code durchgehen>
Hmmmmm

von Karl H. (kbuchegg)


Angehängte Dateien:

Lesenswert?

Testprogramm
1
#include <avr/io.h>
2
3
#define F_CPU 8000000UL
4
#define BAUD 38400UL      // Baudrate
5
 
6
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
8
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
9
 
10
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
11
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
12
#endif 
13
14
15
void uart_init(void)
16
{
17
  UBRR0 = UBRR_VAL;
18
  UCSR0B |= (1<<TXEN0);
19
  // Frame Format: Asynchron 8N2
20
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
21
}
22
23
int main()
24
{
25
  uart_init();
26
27
  while( 1 ) {
28
29
    while (!(UCSR0A & (1<<UDRE0)))
30
      ;
31
 
32
    UDR0 = 'x';
33
  }  
34
}

Irgendwie ist mir bei den sts versus out nicht ganz geheuer. Also lass 
ich das den C-Compiler machen :-)

von Holger P. (Gast)


Lesenswert?

Du 1000 Dank aber ich habe den Fehler gefunden

In der Zeile

FString: .db "******* Hallo kleine Welt *******",13,10,0




war die 0 weg und somit hat er soviel übertragen das ich den anfang 
nicht gesehen habe sondern nur den misst am ende.

Wow es geht .... juhhhhhuuuuu... und nun ab ins Bett morgen Schule.

von Karl H. (kbuchegg)


Lesenswert?

Super.

von Holger P. (Gast)


Lesenswert?

Nun die Katze ist ja aus dem Sack :-)

OK so werde ich hier mal weiter tippen ( Micha nicht schummeln )

Also es geht an den Bootloader, es ist mir klar das ich bis zum ende 
viele Fehler machen werde aber der Weg ist das Ziel.

Ich scheitere aber schon daran die Option  "Linker Options" im AVR 
Studio zu finden.

Mein erstes Ziel soll sein ein kleines Programm in dem Bootbereich zu 
schreiben und zu schauen ob es beim startet auch abläuft. So wollte ich 
nun mal folgendes in den Bootbereich schreiben:
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1    = r16
4
5
.equ F_CPU = 8000000                            ; Systemtakt in Hz
6
.equ BAUD  = 38400                              ; Baudrate
7
8
; Berechnungen
9
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
10
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
11
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
12
 
13
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
14
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
15
.endif 
16
17
; Ports initialisieren
18
ldi  Dummy1, 0b00000000
19
out DDRC,Dummy1 ; Port-C Eingang
20
out DDRB,Dummy1 ; Port-B Eingang
21
ldi  Dummy1, 0b00000010
22
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD
23
24
; Baudrate einstellen
25
ldi Dummy1, HIGH(UBRR_VAL)
26
sts UBRR0H, Dummy1
27
ldi Dummy1, LOW(UBRR_VAL)
28
sts UBRR0L, Dummy1
29
30
; RS232 Frame-Format: 8 Bit 
31
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
32
sts UCSR0B, Dummy1
33
34
ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
35
sts UCSR0C, Dummy1 
36
37
38
rcall FirmOut       ; Meldung auf RS232 ausgeben
39
40
41
;Alle Interrups aus
42
cli
43
44
45
loop:
46
   rjmp loop 
47
    
48
49
          
50
.include "rs232.asm"                   ; RS232 Funktionen

In rs232.asm wird nur ein Text auf die RS232 ausgegeben.
Um das aber nun testen zu können müsste ich das Programm in den Bereich 
0x1c00 schreiben aber wo stelle ich das in AVR-Studio ein. Wie im 
Tutorial beschrieben gibt es diesen Menupunkt nicht.


----

Achja ich finde es hier ganz OK ;-)

von spess53 (Gast)


Lesenswert?

Hi

>Um das aber nun testen zu können müsste ich das Programm in den Bereich
>0x1c00 schreiben aber wo stelle ich das in AVR-Studio ein.
1
  .cseg    ; vorsichtshalber
2
  .org $1C00
3
4
  dein Programm

MfG Spess

von Holger P. (Gast)


Lesenswert?

Danke

Und damit kann ich mir sicher sein das jenes Programm ab speicher 1c00 
geschrieben wird.

Wenn ich beim Flashen erase Device nicht aktiviere bleibt das Programm 
bei 0000 noch drin oder?

von Holger P. (Gast)


Lesenswert?

Jo ist so freu

habe nun
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1    = r16
4
5
.equ F_CPU = 8000000                            ; Systemtakt in Hz
6
.equ BAUD  = 38400                              ; Baudrate
7
8
; Berechnungen
9
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
10
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
11
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
12
 
13
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
14
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
15
.endif 
16
17
18
.cseg    
19
.org $0E00 ; Programm im BootLoader speichern.
20
21
22
; Ports initialisieren
23
ldi  Dummy1, 0b00000000
24
out DDRC,Dummy1 ; Port-C Eingang
25
out DDRB,Dummy1 ; Port-B Eingang
26
ldi  Dummy1, 0b00000010
27
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD
28
29
; Baudrate einstellen
30
ldi Dummy1, HIGH(UBRR_VAL)
31
sts UBRR0H, Dummy1
32
ldi Dummy1, LOW(UBRR_VAL)
33
sts UBRR0L, Dummy1
34
35
; RS232 Frame-Format: 8 Bit 
36
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
37
sts UCSR0B, Dummy1
38
39
ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
40
sts UCSR0C, Dummy1 
41
42
43
rcall FirmOut       ; Meldung auf RS232 ausgeben
44
45
46
;Alle Interrups aus
47
cli
48
49
50
loop:
51
   rjmp 0x0000 
52
    
53
54
          
55
.include "rs232.asm"                   ; RS232 Funktionen

in den Mega geschrieben. Das gleiche Programm hatte ich mit einem 
anderen Ausgabetext schon in 0x0000 stehen. Jetzt kommt erst der Text 
aus dem BootLoader und dann der aus dem Hauptprogramm. Ich glaube den 
ersten Schritt habe ich.

von Spess53 (Gast)


Lesenswert?

Hi

Na klappt doch.

Bist du einer der Kandidaten, in dem es hier

Beitrag "Beginner fragen"

geht?


MfG Spess

von Holger P. (Gast)


Lesenswert?

Spess53 schrieb:
> Bist du einer der Kandidaten

Sorry kann nix dafür das er geschrieben hat.


Aber weiter im Text. Ich bin total Happy, könnte mal jemand über das 
Programm schauen?

Was sollte der BootLoader bist jetzt machen? Also:

Er wartet 250ms bis ein U gesendet wird damit er bereit für ein *U*pdate 
ist. Kommt kein U so springt er zu 0x000. Momentan noch nicht da ja dort 
nix steht und er wieder anfangen würde.

Kommt das U fragt er nach einem Passwort ab. Wird die eingabe mit Enter 
abgeschlossen vergleicht er mit dem Passwort. Ist das Passwort falsch so 
startet der BootLoader neu.

Ist das Passwort richtig geht es weiter und er fragt nach den 
Flashdaten.

Soweit bin ich nun, mir ist klar das er hängenbleibt bis die 
Passwortabfrage mit Enter abgeschlossen wird. Aber ich glaube nicht das 
ich das noch ändere. Ich sage mal Pech wenn einer soweit geht und nix 
eingibt. Für was gibt es den Neustart des Gerätes :-)

Hier das Programm. Oder ist es besser es als Datei anzuhängen?
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1    = r16
4
.def Zaehler   = r17
5
.def Durchlauf1 = r18
6
.def Durchlauf2 = r19
7
.def EZeichen   = r20
8
9
.equ F_CPU = 8000000                            ; Systemtakt in Hz
10
.equ BAUD  = 38400                              ; Baudrate
11
12
; Berechnungen
13
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
14
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
15
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
16
 
17
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
18
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
19
.endif 
20
21
22
23
.macro RS232StrComp
24
    ldi   zl,low(@0*2);    ; Z Pointer laden
25
    ldi   zh,high(@0*2)    ;  
26
    rcall KV
27
.endmacro
28
29
30
.cseg    
31
.org $0E00 ; Programm im BootLoader speichern.
32
33
34
; Ports initialisieren
35
ldi  Dummy1, 0b00000000
36
out DDRC,Dummy1 ; Port-C Eingang
37
out DDRB,Dummy1 ; Port-B Eingang
38
ldi  Dummy1, 0b00000010
39
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD
40
41
; Baudrate einstellen
42
ldi Dummy1, HIGH(UBRR_VAL)
43
sts UBRR0H, Dummy1
44
ldi Dummy1, LOW(UBRR_VAL)
45
sts UBRR0L, Dummy1
46
47
; RS232 Frame-Format: 8 Bit 
48
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
49
sts UCSR0B, Dummy1
50
51
ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
52
sts UCSR0C, Dummy1 
53
54
55
;Alle Interrups aus
56
cli
57
58
Neu:
59
;RS232 Buffer Zeiger auf 0
60
  ldi Dummy1,0
61
    sts RS232Zeiger,Dummy1 
62
  
63
;RS232 Buffer speicher löschen SRAM
64
  ldi xl,low(RS232Buffer);            ; Z Pointer laden
65
    ldi xh,high(RS232Buffer);
66
  ldi Zaehler,20    
67
BClear:
68
  st  x+,Dummy1
69
    dec Zaehler
70
  brne BClear
71
72
Begin:
73
    ldi   Durchlauf1,6  ; Durchlaufzähler auf 6 setzen ( 5*50ms=250ms Wartezeit ) nur 5 weil 0 nicht zählt 
74
75
Start:
76
    dec   Durchlauf1     ; Durchlauf um ein verringern 
77
  breq  StartH         ; Lang genug gewartet ab zum Hauptprogramm
78
79
    ldi   Durchlauf2,225 ; Durchlaufzähler auf 225 ( 50ms )setzen
80
  ldi   Dummy1,'?' ; Zeichen in Dummy1 ( R16 )
81
  rcall sercharout ; auf der RS232 ausgeben.
82
83
loop:
84
  dec   Durchlauf2 ; Durchlauf um ein verringern 
85
  breq  Start      ; Lang genug gewartet ab zum Hauptprogramm
86
  ldi   Zaehler,0  ; Zähler auf 0 setzen
87
88
loop1:
89
  inc Zaehler      ; Zähler erhöhen damit überlauf zustande kommt.
90
    breq loop        ; Überlauf war da gehe zu start
91
92
     lds Dummy1,UCSR0A
93
     sbrs Dummy1,7    ; warten bis ein Byte angekommen ist
94
  rjmp loop1
95
96
    lds  EZeichen,udr0 ; Empfangenes Zeichen holen RXC0 ( Bit 7 von UCSR0A ) löschen.
97
    cpi  EZeichen,'U'  ; Wurde U gesendet? ( U für Update )
98
    brne Begin         ; Kein U neu Warten
99
100
    ; Passwort: auf RS232 ausgeben. Da U gesendet wurde
101
    ldi   zl,low(PasswortString*2) ; Z Pointer laden
102
    ldi   zh,high(PasswortString*2)
103
104
    rcall serout_string ; Ausgabe des Strings RS232 Routine
105
106
PasswortEingabe:
107
     lds Dummy1,UCSR0A
108
     sbrs Dummy1,7    ; warten bis ein Byte angekommen ist
109
  rjmp PasswortEingabe
110
111
    lds  EZeichen,udr0 ; Empfangenes Zeichen holen RXC0 ( Bit 7 von UCSR0A ) löschen.
112
    cpi  EZeichen,13   ; Wurde Enter gesendet?
113
    brne Speichern     ; Kein Enter Zeichen Speichen
114
115
; prüfen auf hinterlegtes Passwort    
116
  ldi   zl,low(Passwort*2);    ; Z Pointer laden
117
    ldi   zh,high(Passwort*2)    ;  
118
119
; RS232Buffer mit Z Pointer vergleichen
120
       ldi   xl,low(RS232Buffer)  ; X Pointer laden
121
       ldi   xh,high(RS232Buffer) 
122
123
XXX:   lpm  Dummy1,Z+       ; nächstes Byte aus dem Flash laden
124
       tst  Dummy1          ; = Null? 
125
       breq Kende           ; Vergleich fertig und somit OK 
126
KVW:   ld   Zaehler,X+      ; Zeichen aus SRAM holen
127
       cp   Dummy1,Zaehler
128
       brne  Kende
129
       rjmp  XXX
130
Kende:
131
       brne  Neu            ; Falsches Passwort BootLoader neu ausführen.
132
133
; OK Flashdaten: auf RS232 ausgeben. Da Passwort richtig war.
134
    ldi   zl,low(FlashDatenString*2) ; Z Pointer laden
135
    ldi   zh,high(FlashDatenString*2)
136
137
    rcall serout_string ; Ausgabe des Strings RS232 Routine    
138
139
Stop:
140
    rjmp Stop
141
142
StartH:
143
    rjmp Stop
144
    rjmp 0x0000
145
146
  ; Zeichen abspeichern 
147
Speichern:
148
  ldi   xl,low(RS232Buffer-1)  ; X Pointer laden
149
    ldi   xh,high(RS232Buffer-1) 
150
      
151
     lds   Dummy1,RS232Zeiger     ; den RS232-Zeiger aus dem Speicher holen
152
    inc   Dummy1                 ; Zeiger um eins weiterschieben
153
  cpi   Dummy1,21              ; Auf Speichergrenze von 20 Byte testen 
154
  brne  SOK                    ; Noch keine 20 Byte 
155
  ldi   Dummy1,1               ; 20 Byte überschritten wieder bei 1 anfangen  
156
SOK:
157
    sts   RS232Zeiger,Dummy1
158
ZeigerStellen:
159
    adiw  xl:xh,1                ; Zeiger erhöhen
160
  dec   Dummy1
161
  brne  ZeigerStellen
162
  st    x,EZeichen             ; Zeichen ins SRAM
163
Ende_InRS232:
164
    pop   Dummy1
165
    out   SREG,Dummy1
166
    pop   Dummy1
167
    rjmp  PasswortEingabe        ; Zurück weiter Zeichen einsammeln
168
169
170
171
.include "rs232.asm" ; RS232 Funktionen
172
173
174
Passwort: .db "Geheim",0,0
175
176
.dseg
177
RS232Zeiger: .Byte 1
178
RS232Buffer: .Byte 20

Aber die richtige Arbeit fängt jetzt erst an oder?

von Holger P. (Gast)


Lesenswert?

Achja das ganze verbraucht erst:

ATmega88 memory use summary [bytes]:
Segment   Begin    End      Code   Data   Used    Size   Use%
---------------------------------------------------------------
[.cseg] 0x001c00 0x001d02    224     34    258    8192   3.1%
[.dseg] 0x000100 0x000115      0     21     21    1024   2.1%
[.eseg] 0x000000 0x000000      0      0      0     512   0.0%

Assembly complete, 0 errors. 0 warnings

von Holger P. (Gast)


Lesenswert?

Sehe ich das richtig? Bevor ich das aus dem Datenblatt von ATMEl nicht 
verstehe geht es mit meinem Projekt nicht weiter?
1
;-the routine writes one page of data from RAM to Flash
2
; the first data location in RAM is pointed to by the Y pointer
3
; the first data location in Flash is pointed to by the Z-pointer
4
;-error handling is not included
5
;-the routine must be placed inside the boot space
6
; (at least the Do_spm sub routine). Only code inside NRWW section can
7
; be read during self-programming (page erase and page write).
8
;-registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
9
; loophi (r25), spmcrval (r20)
10
; storing and restoring of registers is not included in the routine
11
; register usage can be optimized at the expense of code size
12
;-It is assumed that either the interrupt table is moved to the Boot
13
; loader section or that the interrupts are disabled.
14
.equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
15
.org SMALLBOOTSTART
16
Write_page:
17
; page erase
18
ldi spmcrval, (1<<PGERS) | (1<<SPMEN)
19
rcallDo_spm
20
; re-enable the RWW section
21
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
22
rcallDo_spm
23
; transfer data from RAM to Flash page buffer
24
ldi looplo, low(PAGESIZEB) ;init loop variable
25
ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
26
Wrloop:
27
ld r0, Y+
28
ld r1, Y+
29
ldi spmcrval, (1<<SPMEN)
30
rcallDo_spm
31
adiw ZH:ZL, 2
32
sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
33
brne Wrloop
34
; execute page write
35
subi ZL, low(PAGESIZEB) ;restore pointer
36
sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
37
ldi spmcrval, (1<<PGWRT) | (1<<SPMEN)
38
rcallDo_spm
39
; re-enable the RWW section
40
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
41
rcallDo_spm
42
; read back and check, optional
43
ldi looplo, low(PAGESIZEB) ;init loop variable
44
ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
45
subi YL, low(PAGESIZEB) ;restore pointer
46
sbci YH, high(PAGESIZEB)
47
Rdloop:
48
lpm r0, Z+
49
ld r1, Y+
50
cpse r0, r1
51
rjmp Error
52
sbiw loophi:looplo, 1 ;use subi for PAGESIZEB<=256
53
brne Rdloop
54
; return to RWW section
55
; verify that RWW section is safe to read
56
Return:
57
in temp1, SPMCR
58
sbrs temp1, RWWSB ; If RWWSB is set, the RWW section is not
59
ready yet
60
ret
61
; re-enable the RWW section
62
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
63
rcallDo_spm
64
rjmp Return
65
Do_spm:
66
; check for previous SPM complete
67
Wait_spm:
68
in temp1, SPMCR
69
sbrc temp1, SPMEN
70
rjmp Wait_spm
71
; input: spmcrval determines SPM action
72
; disable interrupts if enabled, store status
73
in temp2, SREG
74
cli
75
; check that no EEPROM write access is present
76
Wait_ee:
77
sbic EECR, EEWE
78
rjmp Wait_ee
79
; SPM timed sequence
80
out SPMCR, spmcrval
81
spm
82
; restore SREG (to enable interrupts if originally enabled)
83
out SREG, temp2
84
ret

von Holger P. (Gast)


Lesenswert?

Heute ist ja alles so ruhig.

von Holger P. (Gast)


Lesenswert?

So ich habe mich mal da durch gekämpft. Habe auch folgendes umgesetz:
1
; *************************************************
2
; * Flash speicher löschen/beschreiben/überprüfen *
3
; *************************************************
4
Flashen:
5
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
6
  ldi zh,0;
7
  ldi Zaehler,33 ; Zähler laden mit 32 ( eins mehr 0 wird nicht gezählt ) 32*2=64=größe einer Page.
8
9
; Page buffer löschen
10
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
11
    rcall Start_SPM
12
13
; Wieder bereit machen für RWW
14
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
15
    rcall Start_SPM
16
17
NextPageAdresse:
18
; In r0 und r1 werte die in den buffer kommen
19
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
20
    mov  r0, Dummy1
21
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
22
    mov r1, Dummy1
23
  
24
    ldi SPMKommando, (1<<SELFPRGEN)
25
    rcall Start_SPM
26
    
27
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
28
    dec Zaehler          ; 1 von Zähler abziehen. 
29
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
30
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer
31
32
Programmieren:
33
; Jetzt Buffer ins Flash schreiben
34
  mov zl,0; Zeiger auf den Anfang des Flash setzen
35
  ldi zh,0;
36
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
37
  rcall Start_SPM
38
39
Bereit:
40
; Wieder bereit machen für RWW
41
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
42
    rcall Start_SPM
43
44
    in Dummy1, SPMCSR
45
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
46
    rjmp Ende
47
    rjmp Bereit
48
49
;******************
50
51
Start_SPM:
52
53
; Läuft noch ein SPM? Ja? Warte bis fertig.
54
Wait_spm:
55
    in Dummy1, SPMCSR
56
    sbrc Dummy1, SELFPRGEN
57
    rjmp Wait_spm
58
59
; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
60
Wait_ee:
61
    sbic EECR, EEPE
62
    rjmp Wait_ee
63
64
; SPM starten
65
    out SPMCSR, SPMKommando
66
    spm
67
    ret

Lasse ich das ganze in AVR-Studio laufen so wird auch fein ab Adresse 0 
des Programmspeichers alle mit AA 3C abwechseln gefüllt. Also von Word 0 
bis Word 1F also 32 Wörter = 64 Byte. So zeigt mir das MemoryFenster es 
an.

Was habe ich mich gefreut :-)

aber tippe ich nun
1
ldi zl,63; Zeiger auf den Anfang des Flash setzen

in beiden zuweisungen von zl so wird nix ab Wort 32 ausgefüllt sondern 
auch ab Wort 0.

Wo mach ich ein Denkfehler???

von Holger P. (Gast)


Lesenswert?

Es geht, es geht

Juuuhhhuuuuuuu

Ich muss wie hier getippt 63 angeben nicht 32 wie ich es gemacht habe. 
Hier zählt das Byte nicht das Word.

Somit sieht meine Routine nun so aus:
1
; *************************************************
2
; * Flash speicher löschen/beschreiben/überprüfen *
3
; *************************************************
4
Flashen:
5
    ldi yl,low(RS232Buffer*2) ; Y Pointer laden
6
    ldi yh,high(RS232Buffer*2)
7
8
  ldi Zaehler,33 ; Zähler laden mit 32 ( eins mehr 0 wird nicht gezählt ) 32*2=64=größe einer Page.
9
10
; Page buffer löschen
11
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
12
    rcall Start_SPM
13
14
; Wieder bereit machen für RWW
15
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
16
    rcall Start_SPM
17
18
NextPageAdresse:
19
; In r0 und r1 werte die in den buffer kommen
20
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
21
  ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
22
  
23
  ldi SPMKommando, (1<<SELFPRGEN)
24
  rcall Start_SPM
25
    
26
  adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
27
  dec Zaehler          ; 1 von Zähler abziehen. 
28
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
29
  rjmp NextPageAdresse ; Nächste Zeichen in Buffer
30
31
Programmieren:
32
; Jetzt Buffer ins Flash schreiben
33
  subi zl, low(64); Zeiger wieder 64 Byte zurück ( 32 Wörter )
34
  subi zh, high(64);
35
  
36
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
37
  rcall Start_SPM
38
39
Bereit:
40
; Wieder bereit machen für RWW
41
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
42
    rcall Start_SPM
43
44
    in Dummy1, SPMCSR
45
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
46
    ret
47
    rjmp Bereit
48
49
50
Start_SPM:
51
52
; Läuft noch ein SPM? Ja? Warte bis fertig.
53
Wait_spm:
54
  in Dummy1, SPMCSR
55
  sbrc Dummy1, SELFPRGEN
56
    rjmp Wait_spm
57
58
; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
59
Wait_ee:
60
  sbic EECR, EEPE
61
    rjmp Wait_ee
62
63
; SPM starten
64
    out SPMCSR, SPMKommando
65
    spm
66
    ret

Der Aufruf lautet:
1
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
2
  ldi zh,0;
3
4
    rcall Flashen ; Schreibt RS232Buffer in Programmspeicher z Zeigt auf erste Speicheradresse ( nicht aufs Word )

wow weiter geht es. Jetzt muss ich mir nur noch ein Protokoll ausdenken 
wie die daten über RS232 zum ATMegaa88 kommen.
ich denke mal 64 Byte und danach ein Byte ob fertig oder nicht.
Im Programm muss ich dann nur z immer um 64 erhöhen.

Oder tippe ich mal nicht. Kommt ja wenig reaktion hier :-)

von Holger P. (Gast)


Lesenswert?

Wo mach ich hier nur ein Gedankenfehler
1
    ldi yl,low(RS232Buffer*2) ; Y Pointer laden
2
    ldi yh,high(RS232Buffer*2)
3
4
5
; In r0 und r1 werte die in den buffer kommen
6
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
7
    ld r1, y+ ; In R1 Byte aus dem RS232 Buffer

In r0 und in r1 steht nicht der Inhalt des RS232Buffer

Habe im Buffer 3C und AA hinengeschriben ( Im Simulator ) aber beim 
ersten Durchlauf habe ich in r0 und in r1 FF stehen.

von Holger P. (Gast)


Lesenswert?

So ich bin schon ein ganzes Stück weiter.

Mein BootLoader ist nun in der  Beta-Version.
Ich möchte nun mal bitte dass ihr mal drüber schaut und mir sagt ob es 
gegen das Prinzip, was ich hier verfolge, einen Einwand gibt.

Die einzelnen Funktionen werde ich natürlich auch aufzeigen. Aber erst 
mal geht es mir darum, die Übersicht zu gewährleisten und das 
Funktionsprinzip darzustellen.

Also hier der Code:
1
.INCLUDE "m88def.inc"
2
3
.def Dummy1    = r16
4
.def Zaehler   = r17
5
.def Durchlauf1 = r18
6
.def Durchlauf2 = r19
7
.def EZeichen   = r20
8
.def SPMKommando = r21
9
10
.equ F_CPU = 8000000                            ; Systemtakt in Hz
11
.equ BAUD  = 38400                              ; Baudrate
12
.equ PAGESIZEBYTE = PAGESIZE*2                  ; PAGESIZEB ist Page größein BYTES, nicht in Wörtern
13
.equ BootLoaderStart = $0E00                    ; Adresse des BootLoader
14
.equ Hauptprogramm = $0000                      ; Adresse des Hauptprogramms
15
16
; Berechnungen
17
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
18
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
19
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
20
 
21
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
22
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
23
.endif 
24
25
26
.cseg 
27
.org BootLoaderStart ; Programm im BootLoader speichern.
28
29
; ***********************************************************************
30
; * Stackpointer initialisieren                                         *
31
; ***********************************************************************
32
    ldi Dummy1, high(RAMEND) 
33
    out SPH,Dummy1           
34
    ldi Dummy1, low(RAMEND)
35
    out SPL,Dummy1
36
37
; ***********************************************************************
38
; * Port, Baud und Interrupts instaliesieren                            *
39
; *   Ports alle auf Eingang bis auf PD1=Ausgang TXD                    *
40
; *   Baud 38400,N,8,1                                                  *
41
; *   Alle Interrups aus                                                *
42
; ***********************************************************************
43
    rcall Init_Port_Baud_Interrupt
44
    
45
; ***********************************************************************
46
; * Auf Eingang U warten über die RS232 max 250 ms.                     *
47
; * Sendet alle 50ms ein ? aus                                          *
48
; *                                                                     *
49
; * Könnte nie wieder kommen da nach 250ms kein U Zeichen empfangen     *
50
; * wurde und ins Hauptprogramm spring HauptStart (0x0000)              *
51
; * Der return (ret) wird somit nie ausgeführt sondern: breq HauptStart *
52
; ***********************************************************************  
53
    rcall Wait_U
54
55
; ***********************************************************************
56
; * Login auf RS232 ausgeben. Da U gesendet wurde                       *
57
; ***********************************************************************
58
    ldi   zl,low(LoginString*2) ; Z Pointer laden
59
    ldi   zh,high(LoginString*2)
60
    rcall serout_string         ; Ausgabe des Strings RS232 Routine
61
62
; ***********************************************************************
63
; * RS232 Buffer leeren ( mit 0 füllen )                                *
64
; ***********************************************************************
65
    rcall Clear_RS232_Buffer
66
67
; ***********************************************************************
68
; * Überprüft auf hinterlegtes Passwort.                                *
69
; * Passwort steht hier unter Passwort ( Passwort: .db "Geheim",0,0 )   *
70
; *                                                                     *
71
; * Bei falschen Passwort wird Bootloader neu gestartet kein ret        *
72
; * sondern brne  BootLoaderStart                                       *
73
; *                                                                     *
74
; * Wartet mit dem vergleichen bis chr(13) nach dem Passwort            *
75
; * gesendet wurde.                                                     *
76
; ***********************************************************************  
77
    rcall PasswortEingabe
78
79
; ***********************************************************************
80
; * Count auf RS232 ausgeben.                                           *
81
; ***********************************************************************
82
    ldi   zl,low(PageCountString*2) ; Z Pointer laden
83
    ldi   zh,high(PageCountString*2)
84
    rcall serout_string             ; Ausgabe des Strings RS232 Routine
85
86
; ***********************************************************************
87
; * In Zaehler ( r17 ) wird die Anzahl der Pages über RS232 empfangen.  *
88
; ***********************************************************************
89
    rcall Read_Page_Size
90
91
Read_Block:
92
; ***********************************************************************
93
; * RS232 Buffer leeren ( mit 0 füllen )                                *
94
; *                                                                     *
95
; * ACK chr(6) auf RS232 ausgeben. Block anfordern                      *
96
; ***********************************************************************
97
    rcall Clear_RS232_Buffer
98
    ldi   Dummy1, 6
99
100
Nochmal:
101
    rcall sercharout; Ausgabe von ACK bzw NAK Zeichens    
102
103
; ***********************************************************************
104
; * Liest 68 Byte ein                                                   *
105
; * Byte 1= Low des Flash                                               *
106
; * Byte 2= High des Flash                                              *
107
; * Byte 3-66= Flash-Daten ( 64Byte=1 Page=32 Wörter                    *
108
; * Byte 67-68= CRC-16 Modbus von 1-66                                  *
109
; ***********************************************************************  
110
    rcall Read_RS232_Block
111
112
    cpi  Dummy1, 255    ; Bei 255 ist ein Fehler aufgetretten. 
113
    brne Start_Flashen  ; Kein Fehler RS232Buffer ins Flash
114
115
; ***********************************************************************
116
; * RS232 Buffer leeren ( mit 0 füllen )                                *
117
; *                                                                     *
118
; * NAK chr(21) auf RS232 ausgeben. Fehler im Block neu versuch         *
119
; ***********************************************************************
120
    rcall Clear_RS232_Buffer
121
    ldi   Dummy1, 21
122
    rjmp  Nochmal       ; Block erneut anfragen. 
123
124
Start_Flashen:
125
; ***********************************************************************
126
; * Schreibt RS232Buffer+2 in Programmspeicher                          *
127
; * 64Byte=1 Page=32 Wörter                                             *
128
; *                                                                     *
129
; * RS232Buffer gibt LOW des Programmspeichers an                       *
130
; * RS232Buffer+1 gibt High des Programmspeichers an                    *
131
; ***********************************************************************  
132
    rcall Flashen 
133
    dec  Zaehler        ; Pagezähler um eins weniger
134
    breq Fertig         ; Zahler auf 0 fertig Pages gelesen und im Flash  
135
    rjmp Read_Block     ; Noch nicht alle Pages gelesen   
136
137
Fertig:
138
; ***********************************************************************
139
; * Ready auf RS232 ausgeben und Hauptprogramm 0x0000 starten.          *
140
; ***********************************************************************
141
    ldi   zl,low(ReadyString*2) ; Z Pointer laden
142
    ldi   zh,high(ReadyString*2)
143
    rcall serout_string ; Ausgabe des Strings RS232 Routine
144
    
145
HauptStart:
146
    rjmp Hauptprogramm  ; Startet Hauptprogramm
147
148
149
.include "Passwort.asm"     ; Passwortabfrage und kontrolle
150
.include "Init_P_B_I.asm"   ; Port Baud und Interrupt instaliesieren
151
.include "rs232.asm"        ; RS232 Funktionen
152
.include "flashen.asm"      ; Flashen Funktionen
153
.include "ReadPageSize.asm" ; Liest PageSize über RS232
154
155
; ***********************************************************************
156
; * Liest ein Block = 68Byte ein                                        *
157
; * Byte 1= Low des Flash                                               *
158
; * Byte 2= High des Flash                                              *
159
; * Byte 3-66= Flash-Daten ( 64Byte=1 Page=32 Wörter                    *
160
; * Byte 67-68= CRC-16 Modbus von 1-66                                  *
161
; ***********************************************************************  
162
.include "ReadRS232Block.asm" 
163
164
; ***********************************************************************
165
; * Sollte die 14 Byte (incl.0) nicht übersteigen da sonst der Speicher *
166
; * von 512Byte des Bootloaders nicht ausreicht.                        *
167
; ***********************************************************************
168
Passwort: .db "Geheim",0,0 
169
170
.dseg
171
RS232Zeiger: .Byte 1
172
RS232Buffer: .Byte 68

Sprachrohr frei. Feuert los :-)

Ach ja Danke an alle die mir bis jetzt soweit geholfen haben das ich es 
soweit geschafft habe.

Und allen schon mal im voraus die mir weiter helfen werden.

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
Noch kein Account? Hier anmelden.