mikrocontroller.net

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


Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Captain Subtext (captainsubtext)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schubse dich dann mal zum AVR-Tutorial. SCHUBS! ;)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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)
.include "tn2313def.inc " 

ldi  r16,  0b11111111
out  DDRB,  r16
ldi  r16,  0b?0000110
out  DDRB,  r16

Autor: Captain Subtext (captainsubtext)
Datum:

Bewertung
0 lesenswert
nicht 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)
>
>
> .include "tn2313def.inc "
> 
> ldi  r16,  0b11111111
> out  DDRB,  r16
> ldi  r16,  0b?0000110
> out  DDRB,  r16
> 

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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch mal danke...

Also
.include "tn2313def.inc " 

ldi  r16,  0b11111111
out  DDRB,  r16
ldi  r16,  0b00000110
out  DDRD,  r16

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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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:
.INCLUDE "tn2313def.inc"

  ldi  r16, 0b11111111
  out  DDRB, r16
  ldi  r16, 0b00000110
  out DDRD, r16

  cbi  PortD,2
  
Loop:

  cbi  PortB,7
  sbi  PortB,6

  rcall Warte

  cbi  PortB,6
  sbi  PortB,7
    
  rcall Warte 

  rjmp Loop


Warte:
  ldi r16, $10
S0:
  ldi r17, $ff
S1: 
  ldi r18, $ff 
S2: 
  dec r18
  cpi r18, 0 
  brne S2
  dec r17
  cpi r17, 0 
  brne S1
  dec r16
  cpi r16, 0
  brne S0
  ret

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Langes versuchen und tüfteln hat mich zu folgender Schleife bewegt:
; ============================= 
;    Delay 
;    500ms:
; ----------------------------- 
Delay500ms:
         ldi  Dummy1, $24
S1:      ldi  Dummy2, $BC
S2:      ldi  Dummy3, $C4
S3:      dec  Dummy3
         brne S3
         dec  Dummy2
         brne S2
         dec  Dummy1
         brne S1
         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.

; ============================= 
;    Delay 
;    $24,$BC,$C4 = 500ms:
; ----------------------------- 
.macro  Delay
         ldi  Dummy1, @0
S1:      ldi  Dummy2, @1
S2:      ldi  Dummy3, @2
S3:      dec  Dummy3
         brne S3
         dec  Dummy2
         brne S2
         dec  Dummy1
         brne S1
.endmacro

Der aufruf mit
    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
    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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?


.org 0x000          ; kommt ganz an den Anfang des Speichers
    rjmp RESET      ; Interruptvektoren überspringen
                    ; und zum Hauptprogramm
    
    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

RESET:      ; hier beginnt das Hauptprogramm  

    ; Stackpointer initialisieren
    ldi Dummy1, low(RAMEND) ;stack 
    out SPL, Dummy1 

    ; Ports initialisieren
    ldi  Dummy1, 0b11111111
    out  DDRB, Dummy1
    ldi  Dummy1, 0b00000110
    out DDRD, Dummy1

    ; Baudrate einstellen
    ldi     Dummy1, HIGH(UBRR_VAL)
    out     UBRRH, Dummy1
    ldi     Dummy1, LOW(UBRR_VAL)
    out     UBRRL, Dummy1
 
    ; Frame-Format: 8 Bit 
    ldi Dummy1, (1<<UCSZ1) | (1<<UCSZ0) ; 8 Bit Daten kein Paraty, 1 Stopbit
    out UCSRC, Dummy1 

    ldi Dummy1, (1<<TXEN) | (1<<RXCIE) | (1<<RXEN) ; TX aktivieren Interrupt bei Empfang RX (Empfang) aktivieren
    out UCSRB, Dummy1
  
    sei

Endlos:
    rjmp Endlos

InRS232:
    push Zeichen      ; Zeichen sichern (auf Stack legen)
    in   Zeichen,UDR  ; Empfangenes Zeichen holen Interrupt löschen
    pop  Zeichen      ; Zeichen wiederherstellen
    sbi  PortB,6      ; Setzt PortB Bit 6 (LED an)
    sbi  PortB,7      ; Setzt PortB Bit 7 (LED an)
    reti              ; Zurück aus dem Interrupt
   

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

Autor: Holger P. (holg_i)
Datum:

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

Der ATtiny2313 hat andere IRQ-Vektoren
.org 0x000          ; kommt ganz an den Anfang des Speichers
    rjmp RESET      ; Interruptvektoren überspringen
                    ; und zum Hauptprogramm
    
    reti          ; IRQ0 Handler
    reti          ; IRQ1 Handler
    reti          ; Timer/Counter1 Capture Event
    reti          ; Timer/Counter1 Compare Match A
    reti          ; Timer/Counter1 Overflow
    reti          ; Timer/Counter0 Overflow
    rjmp InRS232  ; USART0, Rx Complete
    reti          ; USART0 Data Register Empty
    reti          ; USART0, Tx Complete
    reti          ; Analog Comparator
    reti          ; Pin Change Interrupt
    reti          ; Timer/Counter1 Compare Match B
    reti          ; Timer/Counter0 Compare Match A
    reti          ; Timer/Counter0 Compare Match B
    reti          ; USI Start Condition
    reti          ; USI Overflow
    reti          ; EEPROM Ready
    reti          ; Watchdog Timer Overflow

Also diese Frage ist geklärt.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
                   rjmp RESET              ; Reset
                   rjmp EXT_INT0           ; IRQ0 Request
                   rjmp EXT_INT1           ; IRQ1 Request
                   rjmp TIMER1_CAPT        ; Timer1 Capture
                   rjmp TIMER1_COMPA       ; Timer1 CompareA
                   rjmp TIMER1_OVF         ; Timer1 Overflow
                   rjmp TIMER0_OVF         ; Timer0 Overflow
                   rjmp USART_RXC          ; USART, Rx Complete
                   rjmp USART_UDRE         ; USART Data Register Empty
                   rjmp USART_TXC          ; USART, Tx Complete
                   rjmp ANA_COMP           ; Analog Comparator
                   rjmp PC_INT             ;
                   rjmp TIMER1_COMPB       ;
                   rjmp TIMER0_COMPA       ;
                   rjmp TIMER0_COMPB       ;
                   rjmp USI_START          ; USI Start Condition
                   rjmp USI_OVERFLOW       ; USI Overflow
                   rjmp EEPROM_Ready       ;
                   rjmp WDT_OVERFLOW       ; Watchdog Timer Overflow

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So warst du wesendlich schneller als ich... ich brauchte fast eine 
Stunde

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

xyz:          push r16
              in r16,SREG
              push r16
              ....

              pop r16
              out SREG,r16
              pop r16
              reti


MfG Spess

Autor: Bernd Volker (volker88)
Datum:
Angehängte Dateien:
  • preview image for 1.JPG
    1.JPG
    183 KB, 268 Downloads

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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
ldi   xl,low(RS232Buffer)
ldi   xh,high(RS232Buffer)
ld Dummy,x+
cpi Dummy,K
brne Weiter1
rjmp Fehler
Weiter1:
ld Dummy,x+
cpi Dummy,a
brne Weiter2
rjmp Fehler
Weiter2:
ld Dummy,x+
cpi Dummy,n
brne Weiter3
rjmp Fehler
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
    ; Zeichen von der RS232 empfangen und auswerten;
InRS232:
    push  Dummy1
    in    Dummy1,SREG
    push  Dummy1

    in    EZeichen,udr                  ; Empfangenes Zeichen holen Interrupt löschen
    cpi   EZeichen,13                   ; Wurde Enter gesendet?
    brne  Speichern                     ; Kein Enter Zeichen in SRAM Speichern
  
  
  
Hier wollte ich vergleichen  
  
  
    ; Meldung Syntax error ausgeben.
    ldi     zl,low(SError*2);            ; Z Pointer laden
    ldi     zh,high(SError*2);
    rcall   serout_string                 ; Ausgabe des Strings RS232 Routine
    
    ldi Dummy1,0                         ; Zeiger wieder vorne
    sts RS232Zeiger,Dummy1  
    rjmp  Ende_InRS232

Speichern:
    ldi   xl,low(RS232Buffer-1)         ; X Pointer laden
    ldi   xh,high(RS232Buffer-1)        ;
    
    lds   Dummy1,RS232Zeiger            ; den RS232-Zeiger aus dem Speicher holen
    inc   Dummy1                        ; Zeiger um eins weiterschieben
    cpi   Dummy1,21                     ; Auf Speichergrenze von 20 Byte testen 
    brne  SOK                           ; Noch keine 20 Byte 
    ldi   Dummy1,1                       ; 20 Byte überschritten wieder bei 1 anfangen  
SOK:
    sts   RS232Zeiger,Dummy1
ZeigerStellen:
    adiw  xl:xh,1                       ; Zeiger erhöhen
    dec   Dummy1
    brne  ZeigerStellen
    st    x,EZeichen                    ; Zeichen ins SRAM
Ende_InRS232:
    pop   Dummy1
    out   SREG,Dummy1
    pop   Dummy1
    reti              ; Zurück aus dem Interrupt

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK OK man sollte erst überlegen und dann fragen :-)

Es geht ich habe es folgenderweise gelöst:
    ; Kommandos vergleichen
    ldi   zl,low(K_Gelb_an*2);    ; Z Pointer laden
    ldi   zh,high(K_Gelb_an*2)    ;  
  
    ldi   xl,low(RS232Buffer)     ; X Pointer laden
    ldi   xh,high(RS232Buffer)    ;
  
KV1:
    lpm                           ; nächstes Byte aus dem Flash laden
    adiw  zl:zh,1                 ; Zeiger erhöhen
    and   r0,r0                   ; = Null? 
    brne  KV1W                    ; Weiter vergleichen da noch nicht Null
    rjmp  V1OK                    ; Vergleich fertig und somit OK 
KV1W:    
    ld    Dummy1,x                ; Zeichen aus SRAM holen
    adiw  xl:xh,1                 ; Zeiger erhöhen
    cp    r0,Dummy1
    brne  KO2
    rjmp  KV1
  
V1OK:
    ; Meldung LED gelb auf RS232 ausgeben.
    ldi     zl,low(LEDGelb_an*2)          ; Z Pointer laden
    ldi     zh,high(LEDGelb_an*2)         ;
    rcall   serout_string                 ; Ausgabe des Strings RS232 Routine
    sbi    PortB,7                         ; Setzt PortB Bit 7 (LED an)
    rjmp  KFertig

KO2:

    ; Meldung Syntax error ausgeben.
    ldi     zl,low(SError*2);            ; Z Pointer laden
    ldi     zh,high(SError*2);
    rcall   serout_string                ; Ausgabe des Strings RS232 Routine

    ; Speicher wieder löschen und zeiger auf 0 setzen
KFertig:
    ldi xl,low(RS232Buffer);            ; Z Pointer laden
    ldi xh,high(RS232Buffer);
    ldi Dummy2,20    
    ldi Dummy1,0
    sts RS232Zeiger,Dummy1               
BuClear:
    st  x+,Dummy1
    dec Dummy2
    brne BuClear
    rjmp  Ende_InRS232

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Damit das ganze einwenig übersichtlicher wird habe ich mal ein Macro 
gemacht.
; ============================= 
;    RS232StrComp
;    prüfen @0 mit RS232Buffer
; ----------------------------- 
.macro RS232StrComp
    ldi   zl,low(@0*2);    ; Z Pointer laden
    ldi   zh,high(@0*2)    ;  
  
    ldi   xl,low(RS232Buffer)     ; X Pointer laden
    ldi   xh,high(RS232Buffer)    ;
  
KV:
    lpm                           ; nächstes Byte aus dem Flash laden
    adiw  zl:zh,1                 ; Zeiger erhöhen
    and   r0,r0                   ; = Null? 
    brne  KVW                     ; Weiter vergleichen da noch nicht Null
    rjmp  KVOK                    ; Vergleich fertig und somit OK 
KVW:    
    ld    Dummy1,x                ; Zeichen aus SRAM holen
    adiw  xl:xh,1                 ; Zeiger erhöhen
    cp    r0,Dummy1
    brne  KVNOK
    rjmp  KV
KVOK:
   ldi Dummy1 ,1
   rjmp KEnde 
KVNOK:
   ldi Dummy1 ,0
Kende:
.endmacro

aufrufen und auswerten tu ich es so:
    ; Kommandos vergleichen
    RS232StrComp K_Gelb_aus ; prüfen auf gelb=0
    cpi   Dummy1,1
    brne  SERR
    
    ;vergleich war ok 
    rjmp  KFertig

SERR:
   ;vergleich war nicht OK
   ; Meldung Syntax error ausgeben.
    ldi     zl,low(SError*2);            ; Z Pointer laden
    ldi     zh,high(SError*2);
    rcall   serout_string                ; Ausgabe des Strings RS232 Routine
    
    ; Speicher wieder löschen und zeiger auf 0 setzen
KFertig:
    ldi xl,low(RS232Buffer);            ; Z Pointer laden
    ldi xh,high(RS232Buffer);
    ldi Dummy2,20    
    ldi Dummy1,0
    sts RS232Zeiger,Dummy1               
BuClear:
    st  x+,Dummy1
    dec Dummy2
    brne BuClear
    rjmp  Ende_InRS232

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
KV:     push r16
        push r17
XXX:    lpm   r16,Z+                  ; nächstes Byte aus dem Flash laden
        tst r16                       ; = Null? 
        breq  Kende                   ; Vergleich fertig und somit OK 
KVW:    ld    r17,X+                  ; Zeichen aus SRAM holen
        cp    r16,r17
        brne  Kende
        rjmp  XXX
Kende:  pop r17
        pop r16
        ret

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

Das:

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

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

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: oldmax (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja ich habe das so auf der Platiene aufgeteilt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.
serout:
    ldi  Dummy1,UCSR0A
    sbrs  Dummy1,UDRE0            ; Warten bis UDR für das nächste Byte bereit ist
    rjmp  serout      


Aber warum nicht. Beim Tiny2313 hat es doch geklappt.

Wer hilft mir mal wieder?

Der komplette Quelltext sieht so aus:
.INCLUDE "m88def.inc"

.def Dummy1 = r16

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 

.org 0x000     ; kommt ganz an den Anfang des Speichers
  rjmp RESET ; Interruptvektoren überspringen und zum Hauptprogramm

reti ; $001 External Interrupt Request 0
reti ; $002 External Interrupt Request 1
reti ; $003 Pin Change Interrupt Request 0
reti ; $004 Pin Change Interrupt Request 0
reti ; $005 Pin Change Interrupt Request 1
reti ; $006 Watchdog Time-out Interrupt
reti ; $007 Timer/Counter2 Compare Match A
reti ; $008 Timer/Counter2 Compare Match A
reti ; $009 Timer/Counter2 Overflow
reti ; $00A Timer/Counter1 Capture Event
reti ; $00B Timer/Counter1 Compare Match A
reti ; $00C Timer/Counter1 Compare Match B
reti ; $00D Timer/Counter1 Overflow
reti ; $00E TimerCounter0 Compare Match A
reti ; $00F TimerCounter0 Compare Match B
reti ; $010 Timer/Couner0 Overflow
reti ; $011 SPI Serial Transfer Complete
reti ; $012 USART Rx Complete
reti ; $013 USART, Data Register Empty
reti ; $014 USART Tx Complete
reti ; $015 ADC Conversion Complete
reti ; $016 EEPROM Ready
reti ; $017 Analog Comparator
reti ; $018 Two-wire Serial Interface
reti ; $019 Store Program Memory Read

RESET: ; Hier beginnt das Hauptprogramm 


; Stackpointer initialisieren
ldi Dummy1, high(RAMEND) 
out SPH,Dummy1           
ldi Dummy1, low(RAMEND)
out SPL,Dummy1

; Ports initialisieren
ldi  Dummy1, 0b11111111
out DDRB,Dummy1 ; Port-B Ausgang
out DDRC,Dummy1 ; Port-C Ausgang
ldi  Dummy1, 0b11111110
out DDRD,Dummy1 ; Port-D Ausgang PD0=Eingang RXD

; Baudrate einstellen
ldi Dummy1, HIGH(UBRR_VAL)
sts UBRR0H, Dummy1
ldi Dummy1, LOW(UBRR_VAL)
sts UBRR0L, Dummy1

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

ldi Dummy1, 1<<TXEN0; TX aktivieren 
sts UCSR0B, Dummy1

; Alle Port's auf Low
ldi Dummy1,0b00000000
out PortB,Dummy1 ; Port B alles auf Low
out PortC,Dummy1 ; Port C alles auf Low
out PortD,Dummy1 ; Port D alles auf Low

; Meldung auf RS232 ausgeben.
ldi     zl,low(FString*2);            ; Z Pointer laden
ldi     zh,high(FString*2);
rcall   serout_string                        ; Ausgabe des Strings RS232 Routine

ldi Dummy1,0b01010101
out PortC,Dummy1 ; Musster raus OK.

The_End:
    rjmp The_End


; Ausgabe eines Strings aus dem Flash
serout_string:
    lpm                             ; nächstes Byte aus dem Flash laden
    adiw    zl:zh,1                 ; Zeiger erhöhen
  and     r0,r0                   ; = Null? 
  brne    serout                  ; wenn nein, -> raus damit
  ret                             ; Zurück wo du her gekommen bist 
serout:
    ldi      Dummy1,UCSR0A
    sbrs    Dummy1,UDRE0            ; Warten bis UDR für das nächste Byte bereit ist
    rjmp    serout                     
    sts     UDR0, R0                ; Zeichen ausgeben
    rjmp    serout_string           ; nächstes Zeichen bearbeiten

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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
ldi Dummy1,0b01010101
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 :-)

Autor: Holger P. (holg_i)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

serout:
    ldi      Dummy1,UCSR0A

nicht LDI sondern LDS!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Braucht der 88 kein URSEL?

Nein.

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe eben hier im Forum gesucht und folgendes gefunden.

Joachim B. schrieb im Beitrag #1929101:
> 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
.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
.equ F_CPU = 1000000                            ; Systemtakt in Hz

probieren (alle Megas werden mit 1Mhz ausgeliefert)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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
.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 







; Baudrate einstellen
ldi Dummy1, HIGH(UBRR_VAL)
sts UBRR0H, Dummy1
ldi Dummy1, LOW(UBRR_VAL)
sts UBRR0L, Dummy1

; RS232 Frame-Format: 8 Bit 
ldi Dummy1, 1<<TXEN0 ; TX aktivieren 
sts UCSR0B, Dummy1

ldi Dummy1, (1<<USBS0)|(3<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
sts UCSR0C, Dummy1 

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ok

Das ist das Testprogramm
/*
 
  Testprogramm für CPU Takt
  Hier die vermeintliche Taktrate des µC eintragen
  Im Beispiel hier: 1Mhz
  
  */
  #define F_CPU 8000000
 
  #include <avr/io.h>
  #include <util/delay.h>
 
  /*
     Hier die tatsächlich verwendeten Parameter angeben
  */
 
  #define LED_PORT    PORTC
  #define LED_DDR     DDRC
  #define LED_PIN     PC0
 
  int main()
  {
    LED_DDR |= (1<<LED_PIN);
 
    while( 1 ) {
      LED_PORT ^= (1<<LED_PIN);
      _delay_ms(1000);
    }
  }

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.

Autor: Holger P. (holg_i)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Testprogramm
#include <avr/io.h>

#define F_CPU 8000000UL
#define BAUD 38400UL      // Baudrate
 
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif 


void uart_init(void)
{
  UBRR0 = UBRR_VAL;
  UCSR0B |= (1<<TXEN0);
  // Frame Format: Asynchron 8N2
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

int main()
{
  uart_init();

  while( 1 ) {

    while (!(UCSR0A & (1<<UDRE0)))
      ;
 
    UDR0 = 'x';
  }  
}

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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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:
.INCLUDE "m88def.inc"

.def Dummy1    = r16

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 

; Ports initialisieren
ldi  Dummy1, 0b00000000
out DDRC,Dummy1 ; Port-C Eingang
out DDRB,Dummy1 ; Port-B Eingang
ldi  Dummy1, 0b00000010
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD

; Baudrate einstellen
ldi Dummy1, HIGH(UBRR_VAL)
sts UBRR0H, Dummy1
ldi Dummy1, LOW(UBRR_VAL)
sts UBRR0L, Dummy1

; RS232 Frame-Format: 8 Bit 
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
sts UCSR0B, Dummy1

ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
sts UCSR0C, Dummy1 


rcall FirmOut       ; Meldung auf RS232 ausgeben


;Alle Interrups aus
cli


loop:
   rjmp loop 
    

          
.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 ;-)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
  .cseg    ; vorsichtshalber
  .org $1C00

  dein Programm

MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo ist so freu

habe nun
.INCLUDE "m88def.inc"

.def Dummy1    = r16

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 


.cseg    
.org $0E00 ; Programm im BootLoader speichern.


; Ports initialisieren
ldi  Dummy1, 0b00000000
out DDRC,Dummy1 ; Port-C Eingang
out DDRB,Dummy1 ; Port-B Eingang
ldi  Dummy1, 0b00000010
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD

; Baudrate einstellen
ldi Dummy1, HIGH(UBRR_VAL)
sts UBRR0H, Dummy1
ldi Dummy1, LOW(UBRR_VAL)
sts UBRR0L, Dummy1

; RS232 Frame-Format: 8 Bit 
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
sts UCSR0B, Dummy1

ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
sts UCSR0C, Dummy1 


rcall FirmOut       ; Meldung auf RS232 ausgeben


;Alle Interrups aus
cli


loop:
   rjmp 0x0000 
    

          
.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.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Na klappt doch.

Bist du einer der Kandidaten, in dem es hier

Beitrag "Beginner fragen"

geht?


MfG Spess

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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?
.INCLUDE "m88def.inc"

.def Dummy1    = r16
.def Zaehler   = r17
.def Durchlauf1 = r18
.def Durchlauf2 = r19
.def EZeichen   = r20

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 



.macro RS232StrComp
    ldi   zl,low(@0*2);    ; Z Pointer laden
    ldi   zh,high(@0*2)    ;  
    rcall KV
.endmacro


.cseg    
.org $0E00 ; Programm im BootLoader speichern.


; Ports initialisieren
ldi  Dummy1, 0b00000000
out DDRC,Dummy1 ; Port-C Eingang
out DDRB,Dummy1 ; Port-B Eingang
ldi  Dummy1, 0b00000010
out DDRD,Dummy1 ; Port-D Eingang PD1=Ausgang TXD

; Baudrate einstellen
ldi Dummy1, HIGH(UBRR_VAL)
sts UBRR0H, Dummy1
ldi Dummy1, LOW(UBRR_VAL)
sts UBRR0L, Dummy1

; RS232 Frame-Format: 8 Bit 
ldi Dummy1, (1<<RXEN0)|(1<<TXEN0) ; TX aktivieren, RX aktivieren 
sts UCSR0B, Dummy1

ldi Dummy1, (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00) ; 8 Bit Daten kein Paraty, 1 Stopbit
sts UCSR0C, Dummy1 


;Alle Interrups aus
cli

Neu:
;RS232 Buffer Zeiger auf 0
  ldi Dummy1,0
    sts RS232Zeiger,Dummy1 
  
;RS232 Buffer speicher löschen SRAM
  ldi xl,low(RS232Buffer);            ; Z Pointer laden
    ldi xh,high(RS232Buffer);
  ldi Zaehler,20    
BClear:
  st  x+,Dummy1
    dec Zaehler
  brne BClear

Begin:
    ldi   Durchlauf1,6  ; Durchlaufzähler auf 6 setzen ( 5*50ms=250ms Wartezeit ) nur 5 weil 0 nicht zählt 

Start:
    dec   Durchlauf1     ; Durchlauf um ein verringern 
  breq  StartH         ; Lang genug gewartet ab zum Hauptprogramm

    ldi   Durchlauf2,225 ; Durchlaufzähler auf 225 ( 50ms )setzen
  ldi   Dummy1,'?' ; Zeichen in Dummy1 ( R16 )
  rcall sercharout ; auf der RS232 ausgeben.

loop:
  dec   Durchlauf2 ; Durchlauf um ein verringern 
  breq  Start      ; Lang genug gewartet ab zum Hauptprogramm
  ldi   Zaehler,0  ; Zähler auf 0 setzen

loop1:
  inc Zaehler      ; Zähler erhöhen damit überlauf zustande kommt.
    breq loop        ; Überlauf war da gehe zu start

     lds Dummy1,UCSR0A
     sbrs Dummy1,7    ; warten bis ein Byte angekommen ist
  rjmp loop1

    lds  EZeichen,udr0 ; Empfangenes Zeichen holen RXC0 ( Bit 7 von UCSR0A ) löschen.
    cpi  EZeichen,'U'  ; Wurde U gesendet? ( U für Update )
    brne Begin         ; Kein U neu Warten

    ; Passwort: auf RS232 ausgeben. Da U gesendet wurde
    ldi   zl,low(PasswortString*2) ; Z Pointer laden
    ldi   zh,high(PasswortString*2)

    rcall serout_string ; Ausgabe des Strings RS232 Routine

PasswortEingabe:
     lds Dummy1,UCSR0A
     sbrs Dummy1,7    ; warten bis ein Byte angekommen ist
  rjmp PasswortEingabe

    lds  EZeichen,udr0 ; Empfangenes Zeichen holen RXC0 ( Bit 7 von UCSR0A ) löschen.
    cpi  EZeichen,13   ; Wurde Enter gesendet?
    brne Speichern     ; Kein Enter Zeichen Speichen

; prüfen auf hinterlegtes Passwort    
  ldi   zl,low(Passwort*2);    ; Z Pointer laden
    ldi   zh,high(Passwort*2)    ;  

; RS232Buffer mit Z Pointer vergleichen
       ldi   xl,low(RS232Buffer)  ; X Pointer laden
       ldi   xh,high(RS232Buffer) 

XXX:   lpm  Dummy1,Z+       ; nächstes Byte aus dem Flash laden
       tst  Dummy1          ; = Null? 
       breq Kende           ; Vergleich fertig und somit OK 
KVW:   ld   Zaehler,X+      ; Zeichen aus SRAM holen
       cp   Dummy1,Zaehler
       brne  Kende
       rjmp  XXX
Kende:
       brne  Neu            ; Falsches Passwort BootLoader neu ausführen.

; OK Flashdaten: auf RS232 ausgeben. Da Passwort richtig war.
    ldi   zl,low(FlashDatenString*2) ; Z Pointer laden
    ldi   zh,high(FlashDatenString*2)

    rcall serout_string ; Ausgabe des Strings RS232 Routine    

Stop:
    rjmp Stop

StartH:
    rjmp Stop
    rjmp 0x0000

  ; Zeichen abspeichern 
Speichern:
  ldi   xl,low(RS232Buffer-1)  ; X Pointer laden
    ldi   xh,high(RS232Buffer-1) 
      
     lds   Dummy1,RS232Zeiger     ; den RS232-Zeiger aus dem Speicher holen
    inc   Dummy1                 ; Zeiger um eins weiterschieben
  cpi   Dummy1,21              ; Auf Speichergrenze von 20 Byte testen 
  brne  SOK                    ; Noch keine 20 Byte 
  ldi   Dummy1,1               ; 20 Byte überschritten wieder bei 1 anfangen  
SOK:
    sts   RS232Zeiger,Dummy1
ZeigerStellen:
    adiw  xl:xh,1                ; Zeiger erhöhen
  dec   Dummy1
  brne  ZeigerStellen
  st    x,EZeichen             ; Zeichen ins SRAM
Ende_InRS232:
    pop   Dummy1
    out   SREG,Dummy1
    pop   Dummy1
    rjmp  PasswortEingabe        ; Zurück weiter Zeichen einsammeln



.include "rs232.asm" ; RS232 Funktionen


Passwort: .db "Geheim",0,0

.dseg
RS232Zeiger: .Byte 1
RS232Buffer: .Byte 20

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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe ich das richtig? Bevor ich das aus dem Datenblatt von ATMEl nicht 
verstehe geht es mit meinem Projekt nicht weiter?
;-the routine writes one page of data from RAM to Flash
; the first data location in RAM is pointed to by the Y pointer
; the first data location in Flash is pointed to by the Z-pointer
;-error handling is not included
;-the routine must be placed inside the boot space
; (at least the Do_spm sub routine). Only code inside NRWW section can
; be read during self-programming (page erase and page write).
;-registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
; loophi (r25), spmcrval (r20)
; storing and restoring of registers is not included in the routine
; register usage can be optimized at the expense of code size
;-It is assumed that either the interrupt table is moved to the Boot
; loader section or that the interrupts are disabled.
.equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
.org SMALLBOOTSTART
Write_page:
; page erase
ldi spmcrval, (1<<PGERS) | (1<<SPMEN)
rcallDo_spm
; re-enable the RWW section
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
rcallDo_spm
; transfer data from RAM to Flash page buffer
ldi looplo, low(PAGESIZEB) ;init loop variable
ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
Wrloop:
ld r0, Y+
ld r1, Y+
ldi spmcrval, (1<<SPMEN)
rcallDo_spm
adiw ZH:ZL, 2
sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
brne Wrloop
; execute page write
subi ZL, low(PAGESIZEB) ;restore pointer
sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
ldi spmcrval, (1<<PGWRT) | (1<<SPMEN)
rcallDo_spm
; re-enable the RWW section
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
rcallDo_spm
; read back and check, optional
ldi looplo, low(PAGESIZEB) ;init loop variable
ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
subi YL, low(PAGESIZEB) ;restore pointer
sbci YH, high(PAGESIZEB)
Rdloop:
lpm r0, Z+
ld r1, Y+
cpse r0, r1
rjmp Error
sbiw loophi:looplo, 1 ;use subi for PAGESIZEB<=256
brne Rdloop
; return to RWW section
; verify that RWW section is safe to read
Return:
in temp1, SPMCR
sbrs temp1, RWWSB ; If RWWSB is set, the RWW section is not
ready yet
ret
; re-enable the RWW section
ldi spmcrval, (1<<RWWSRE) | (1<<SPMEN)
rcallDo_spm
rjmp Return
Do_spm:
; check for previous SPM complete
Wait_spm:
in temp1, SPMCR
sbrc temp1, SPMEN
rjmp Wait_spm
; input: spmcrval determines SPM action
; disable interrupts if enabled, store status
in temp2, SREG
cli
; check that no EEPROM write access is present
Wait_ee:
sbic EECR, EEWE
rjmp Wait_ee
; SPM timed sequence
out SPMCR, spmcrval
spm
; restore SREG (to enable interrupts if originally enabled)
out SREG, temp2
ret

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Heute ist ja alles so ruhig.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich habe mich mal da durch gekämpft. Habe auch folgendes umgesetz:
; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
  ldi zh,0;
  ldi Zaehler,33 ; Zähler laden mit 32 ( eins mehr 0 wird nicht gezählt ) 32*2=64=größe einer Page.

; Page buffer löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
    ldi Dummy1, 0b10101010 ; 10101010 zum Testen
    mov  r0, Dummy1
    ldi Dummy1, 0b00111100 ; 00111100 zum Testen
    mov r1, Dummy1
  
    ldi SPMKommando, (1<<SELFPRGEN)
    rcall Start_SPM
    
    adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
    dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
    rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
  mov zl,0; Zeiger auf den Anfang des Flash setzen
  ldi zh,0;
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
  rcall Start_SPM

Bereit:
; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

    in Dummy1, SPMCSR
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
    rjmp Ende
    rjmp Bereit

;******************

Start_SPM:

; Läuft noch ein SPM? Ja? Warte bis fertig.
Wait_spm:
    in Dummy1, SPMCSR
    sbrc Dummy1, SELFPRGEN
    rjmp Wait_spm

; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
Wait_ee:
    sbic EECR, EEPE
    rjmp Wait_ee

; SPM starten
    out SPMCSR, SPMKommando
    spm
    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
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???

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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:
; *************************************************
; * Flash speicher löschen/beschreiben/überprüfen *
; *************************************************
Flashen:
    ldi yl,low(RS232Buffer*2) ; Y Pointer laden
    ldi yh,high(RS232Buffer*2)

  ldi Zaehler,33 ; Zähler laden mit 32 ( eins mehr 0 wird nicht gezählt ) 32*2=64=größe einer Page.

; Page buffer löschen
    ldi SPMKommando, (1<<PGERS) | (1<<SELFPRGEN)
    rcall Start_SPM

; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

NextPageAdresse:
; In r0 und r1 werte die in den buffer kommen
  ld r0, y+ ; In r0 Byte aus den RS232 Buffer
  ld r1, y+ ; In R1 Byte aus dem RS232 Buffer
  
  ldi SPMKommando, (1<<SELFPRGEN)
  rcall Start_SPM
    
  adiw ZH:ZL,2         ; Zeiger um 2 erhöhen 
  dec Zaehler          ; 1 von Zähler abziehen. 
    breq Programmieren   ; Zahler auf 0 fertig Buffer schreiben 
  rjmp NextPageAdresse ; Nächste Zeichen in Buffer

Programmieren:
; Jetzt Buffer ins Flash schreiben
  subi zl, low(64); Zeiger wieder 64 Byte zurück ( 32 Wörter )
  subi zh, high(64);
  
  ldi SPMKommando, (1<<PGWRT) | (1<<SELFPRGEN)
  rcall Start_SPM

Bereit:
; Wieder bereit machen für RWW
    ldi SPMKommando, (1<<RWWSRE) | (1<<SELFPRGEN)
    rcall Start_SPM

    in Dummy1, SPMCSR
    sbrs Dummy1, RWWSB ; RWWSB noch gesetzt noch nicht bereit
    ret
    rjmp Bereit


Start_SPM:

; Läuft noch ein SPM? Ja? Warte bis fertig.
Wait_spm:
  in Dummy1, SPMCSR
  sbrc Dummy1, SELFPRGEN
    rjmp Wait_spm

; Läuft noche das EEPROM schreiben? Ja? Warte bis fertig.
Wait_ee:
  sbic EECR, EEPE
    rjmp Wait_ee

; SPM starten
    out SPMCSR, SPMKommando
    spm
    ret

Der Aufruf lautet:
   ldi zl,0; Zeiger auf den Anfang des Flash setzen
  ldi zh,0;

    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 :-)

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo mach ich hier nur ein Gedankenfehler
    ldi yl,low(RS232Buffer*2) ; Y Pointer laden
    ldi yh,high(RS232Buffer*2)


; In r0 und r1 werte die in den buffer kommen
    ld r0, y+ ; In r0 Byte aus den RS232 Buffer
    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.

Autor: Holger P. (holg_i)
Datum:

Bewertung
0 lesenswert
nicht 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:
.INCLUDE "m88def.inc"

.def Dummy1    = r16
.def Zaehler   = r17
.def Durchlauf1 = r18
.def Durchlauf2 = r19
.def EZeichen   = r20
.def SPMKommando = r21

.equ F_CPU = 8000000                            ; Systemtakt in Hz
.equ BAUD  = 38400                              ; Baudrate
.equ PAGESIZEBYTE = PAGESIZE*2                  ; PAGESIZEB ist Page größein BYTES, nicht in Wörtern
.equ BootLoaderStart = $0E00                    ; Adresse des BootLoader
.equ Hauptprogramm = $0000                      ; Adresse des Hauptprogramms

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif 


.cseg 
.org BootLoaderStart ; Programm im BootLoader speichern.

; ***********************************************************************
; * Stackpointer initialisieren                                         *
; ***********************************************************************
    ldi Dummy1, high(RAMEND) 
    out SPH,Dummy1           
    ldi Dummy1, low(RAMEND)
    out SPL,Dummy1

; ***********************************************************************
; * Port, Baud und Interrupts instaliesieren                            *
; *   Ports alle auf Eingang bis auf PD1=Ausgang TXD                    *
; *   Baud 38400,N,8,1                                                  *
; *   Alle Interrups aus                                                *
; ***********************************************************************
    rcall Init_Port_Baud_Interrupt
    
; ***********************************************************************
; * Auf Eingang U warten über die RS232 max 250 ms.                     *
; * Sendet alle 50ms ein ? aus                                          *
; *                                                                     *
; * Könnte nie wieder kommen da nach 250ms kein U Zeichen empfangen     *
; * wurde und ins Hauptprogramm spring HauptStart (0x0000)              *
; * Der return (ret) wird somit nie ausgeführt sondern: breq HauptStart *
; ***********************************************************************  
    rcall Wait_U

; ***********************************************************************
; * Login auf RS232 ausgeben. Da U gesendet wurde                       *
; ***********************************************************************
    ldi   zl,low(LoginString*2) ; Z Pointer laden
    ldi   zh,high(LoginString*2)
    rcall serout_string         ; Ausgabe des Strings RS232 Routine

; ***********************************************************************
; * RS232 Buffer leeren ( mit 0 füllen )                                *
; ***********************************************************************
    rcall Clear_RS232_Buffer

; ***********************************************************************
; * Überprüft auf hinterlegtes Passwort.                                *
; * Passwort steht hier unter Passwort ( Passwort: .db "Geheim",0,0 )   *
; *                                                                     *
; * Bei falschen Passwort wird Bootloader neu gestartet kein ret        *
; * sondern brne  BootLoaderStart                                       *
; *                                                                     *
; * Wartet mit dem vergleichen bis chr(13) nach dem Passwort            *
; * gesendet wurde.                                                     *
; ***********************************************************************  
    rcall PasswortEingabe

; ***********************************************************************
; * Count auf RS232 ausgeben.                                           *
; ***********************************************************************
    ldi   zl,low(PageCountString*2) ; Z Pointer laden
    ldi   zh,high(PageCountString*2)
    rcall serout_string             ; Ausgabe des Strings RS232 Routine

; ***********************************************************************
; * In Zaehler ( r17 ) wird die Anzahl der Pages über RS232 empfangen.  *
; ***********************************************************************
    rcall Read_Page_Size

Read_Block:
; ***********************************************************************
; * RS232 Buffer leeren ( mit 0 füllen )                                *
; *                                                                     *
; * ACK chr(6) auf RS232 ausgeben. Block anfordern                      *
; ***********************************************************************
    rcall Clear_RS232_Buffer
    ldi   Dummy1, 6

Nochmal:
    rcall sercharout; Ausgabe von ACK bzw NAK Zeichens    

; ***********************************************************************
; * Liest 68 Byte ein                                                   *
; * Byte 1= Low des Flash                                               *
; * Byte 2= High des Flash                                              *
; * Byte 3-66= Flash-Daten ( 64Byte=1 Page=32 Wörter                    *
; * Byte 67-68= CRC-16 Modbus von 1-66                                  *
; ***********************************************************************  
    rcall Read_RS232_Block

    cpi  Dummy1, 255    ; Bei 255 ist ein Fehler aufgetretten. 
    brne Start_Flashen  ; Kein Fehler RS232Buffer ins Flash

; ***********************************************************************
; * RS232 Buffer leeren ( mit 0 füllen )                                *
; *                                                                     *
; * NAK chr(21) auf RS232 ausgeben. Fehler im Block neu versuch         *
; ***********************************************************************
    rcall Clear_RS232_Buffer
    ldi   Dummy1, 21
    rjmp  Nochmal       ; Block erneut anfragen. 

Start_Flashen:
; ***********************************************************************
; * Schreibt RS232Buffer+2 in Programmspeicher                          *
; * 64Byte=1 Page=32 Wörter                                             *
; *                                                                     *
; * RS232Buffer gibt LOW des Programmspeichers an                       *
; * RS232Buffer+1 gibt High des Programmspeichers an                    *
; ***********************************************************************  
    rcall Flashen 
    dec  Zaehler        ; Pagezähler um eins weniger
    breq Fertig         ; Zahler auf 0 fertig Pages gelesen und im Flash  
    rjmp Read_Block     ; Noch nicht alle Pages gelesen   

Fertig:
; ***********************************************************************
; * Ready auf RS232 ausgeben und Hauptprogramm 0x0000 starten.          *
; ***********************************************************************
    ldi   zl,low(ReadyString*2) ; Z Pointer laden
    ldi   zh,high(ReadyString*2)
    rcall serout_string ; Ausgabe des Strings RS232 Routine
    
HauptStart:
    rjmp Hauptprogramm  ; Startet Hauptprogramm


.include "Passwort.asm"     ; Passwortabfrage und kontrolle
.include "Init_P_B_I.asm"   ; Port Baud und Interrupt instaliesieren
.include "rs232.asm"        ; RS232 Funktionen
.include "flashen.asm"      ; Flashen Funktionen
.include "ReadPageSize.asm" ; Liest PageSize über RS232

; ***********************************************************************
; * Liest ein Block = 68Byte ein                                        *
; * Byte 1= Low des Flash                                               *
; * Byte 2= High des Flash                                              *
; * Byte 3-66= Flash-Daten ( 64Byte=1 Page=32 Wörter                    *
; * Byte 67-68= CRC-16 Modbus von 1-66                                  *
; ***********************************************************************  
.include "ReadRS232Block.asm" 

; ***********************************************************************
; * Sollte die 14 Byte (incl.0) nicht übersteigen da sonst der Speicher *
; * von 512Byte des Bootloaders nicht ausreicht.                        *
; ***********************************************************************
Passwort: .db "Geheim",0,0 

.dseg
RS232Zeiger: .Byte 1
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.