- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 7 von 7

Thema: HC-SR04 mit AtMega328

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174
    AtMega328_uart_std.asm
    Code:
    ;************************Unterprogramme******************************
    rx:        rcall        data_received    ;warte auf daten von PC
            cpi            temp1,' '        ;vergleich auf leerzeichen
            brne        rx                ;sonst wenn falsch warte weiter
            ldi            temp1,'*'        ;
            rcall        data_transmit    ;sende * als ack
            ret
    
    tx:        rcall        wait150ms
            ldi            temp1,'T'
            rcall        data_transmit    ;sende T
            ldi            temp1,'S'
            rcall        data_transmit    ;sende S
            ldi            temp1,'T'
            rcall        data_transmit    ;sende T
            ret
    ;*********************Textausgabe aus DB***********************************
    txt_out_rs_debug:
            rcall        debug_pnt        ;Pointer für Debug laden wird alles in SRAM ab Adresse $0060 geschrieben
    txt_out_rs:
            lpm            temp1,z+        ;!!! muss in der .db *2 genommen werden
            cpi            temp1,$ff
            breq        txt_out_rs_end
        ;    st            x+,temp1        ;nur einschalten wenn debug angesprungen wird
            rcall        data_transmit    ;z.b.: ldi ZH,high(out0*2)
            rjmp        txt_out_rs
    txt_out_rs_end:
            ret
    
    debug_pnt:
            ldi            xh,high(RSdebug)
            ldi            xl,low(RSdebug)
            ret
    
    ;***********This is an ENTER omg*******************************************
    enter_rs232:
            ldi            temp1,$0d
            rcall        data_transmit
            ldi            temp1,$0a
            rcall        data_transmit
            ret
    
    leer_zeichen_rs232:
            ldi            temp1,' '
            rcall        data_transmit
            ret
    
    ;***************************ZahlenAusgabe*************************
    zahl_rs_load_out_xy:    
            rcall        hex_dez            ;Zahlenwandlung
            push        yh                ;on stack anderer AdressBereich
            push        yl                ;on stack
            rcall        load_Y_ergk1    ;Startbyte ; load_Y_ergk(n) (5Byte), n=1(4byte), n=2(3byte), n=3(2byte), n=4(1byte)
            ldi            temp3,high(erg_k+3)
            ldi            temp4,low(erg_k+3); Ende
            rjmp        zahl_rs_load_out2
    
    zahl_rs_load_out:
        ;    ld            mathergll,y+    ;alles in die Mathregs laden
        ;    clr            mathergl
        ;    clr            mathergh
        ;    clr            matherghh
            rcall        hex_dez            ;Zahlenwandlung
            push        yh                ;on stack anderer AdressBereich
            push        yl                ;on stack
            rcall        load_Y_ergk2    ;maximale Ausgabe an Zahlen also 5Byte; load_Y_ergk1(4byte),2(3byte),3(2byte),4(1byte)
            ldi            temp3,high(erg_k+5)
            ldi            temp4,low(erg_k+5)
    zahl_rs_load_out2:
            rcall        zahl_out_rsx    ;Dez in ASCII + Ausgabe
            cp            yl,temp4        ;
            brne        zahl_rs_load_out2
            pop            yl                ;from stack
            pop            yh                ;from stack
            ret    
    
    zahl_out_rsx:                        ;RSX Ausgabe mit Variabler BYTEZAHL durch load_Y_ergk festgelegt
            ld            temp1,y+
            rjmp        zahl_out_rs
    zahl_out_rs1:                        ;rs Ausgabe 2er Zahlen = 1Byte
            ld            temp1,y            ;   nur um 1byte auszugeben 
    zahl_out_rs:                        ;wird nur rs1 angesprungen müssen die Daten vorher geladen werden  
            mov            temp2,temp1
            swap        temp1
            andi        temp1,$0f
            ori            temp1,$30
            rcall        data_transmit    ;Zehnerausgabe
                                        ;Ausgbabe 1er Zahl
            mov            temp1,temp2
            andi        temp1,$0f
            ori            temp1,$30
            rcall        data_transmit    ;Einerausgabe
            ret
    
    ;*****************Wandlung von 1A-hex in 1A-ASCII = 31 , 41 Anzeige ist 1 A 
    adr_hex_ASCII_rs:                            ;Daten vorher in Temp1 laden
    pc_ser2:mov            temp2,temp1                ;byte sichern 
    
            swap        temp1                    ;swapen
            andi        temp1,$0f                ;ausanden
            cpi            temp1,$0a                ;vergleich ob >= 10
            brsh        pc_ser21                ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
            subi        temp1,-$30                ;wenn nein mach HexZahl zu ASCII-Zahl
            rjmp        pc_ser22
    pc_ser21:            
            subi        temp1,-$37                ;HexBuchstabe zu ASCII-Buschstabe
    pc_ser22:        
            rcall        data_transmit            ;und ab damit zum PC
            mov            temp1,temp2                ;gesichertes byte laden
            andi        temp1,$0f                ;ausanden
            cpi            temp1,$0a                ;vergleich ob >= 10
            brsh        pc_ser31                ;wenn ja mach ein HexBuchstabe zu ASCII-Buschstabe
            subi        temp1,-$30                ;wenn nein mach HexZahl zu ASCII-Zahl
            rjmp        pc_ser32
    pc_ser31:
            subi        temp1,-$37                ;HexBuchstabe zu ASCII-Buschstabe
    pc_ser32:
            rcall        data_transmit            ;und ab damit zum PC
            rcall        leer_zeichen_rs232        ;leerzeichen
            rcall        enter_rs232                ;wenn ja mach noch ein ENTER
            ret
    
    ;************************uart_init mit RX interrupt**********************
    usart_init:
            ldi            temp0,high (UBRR0)
            ldi            temp1,low  (UBRR0)
            sts            UBRR0H,temp0                ;9600 Baud einstellen PDF S.133 table52
            sts         UBRR0L,temp1
    
            rcall        char_size8                    ;8 zeichen, 1 stoppbit
            
            lds            temp0,UCSR0A
            ori            temp0,(0<<U2X0|0<<MPCM0)    ;no DoubleSpeed, no MultiProzComMode
            sts            UCSR0A,temp0
            
            ret
    
    char_size5:
             ldi          temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|0<<UCSZ01|0<<UCSZ00|0<<UCPOL0)  ; UCSRC1 or UBRRH0,USBS=0 stoppbits1,
            sts         UCSR0C,temp0    
             ldi          temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02)     ;enable RX u TX  <=5bit(UCSZ2=0) 
            sts         UCSR0B,temp0    ;
            ret                        
            
    char_size6:
             ldi          temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|0<<UCSZ01|1<<UCSZ00|0<<UCPOL0)  ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
            sts         UCSR0C,temp0    
             ldi          temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02)     ;enable RX u TX  <=6bit(UCSZ2=0) 
            sts         UCSR0B,temp0    
            ret                                                
                
    char_size7:
             ldi          temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|0<<UCSZ00|0<<UCPOL0)  ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
            sts         UCSR0C,temp0        
             ldi          temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02)     ;enable RX u TX  <=7bit(UCSZ2=0) 
            sts         UCSR0B,temp0    ;
            ret                                            
            
    char_size8:
             ldi          temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|1<<UCSZ00|0<<UCPOL0)  ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
            sts         UCSR0C,temp0    
             ldi          temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|0<<UCSZ02)     ;enable RX u TX  <=7bit(UCSZ2=0) 
            sts         UCSR0B,temp0    
            ret                    
    
    char_size9:
             ldi          temp0,(0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|1<<UCSZ00|0<<UCPOL0)  ;UCSRC1 or UBRRH0,USBS=0 stoppbits1,
            sts         UCSR0C,temp0    
             ldi          temp0,(0<<RXCIE0|0<<TXCIE0|0<<UDRIE0|1<<RXEN0|1<<TXEN0|1<<UCSZ02)     ;enable RX u TX  <=9bit(UCSZ2=1) 
            sts         UCSR0B,temp0    
            ret                                
    
    ;************************uart_deinit********************************
    usart_all_aus:
            clr            temp0
            sts            UCSR0B,temp0
            sts            UCSR0C,temp0
            sts            UBRR0L,temp0
            sts            UBRR0H,temp0
            ret
    
    usart_ofln:                                    ;wenn unterprogramme nicht 
            clr            temp0                    ;gestört werden dürfen
            sts            UCSR0B,temp0                ;nur usart offline
            ret
    
    ;**********************daten_senden*********************************
    INT_USART_RX:
            ;siehe data_transmit;** man kann in der wartezeit andere sachen erledigen
            ;bis der int kommt im INT selbst könnte man ne art daten-lese-schleife implementieren
            ;um weitere daten zu senden die dann an temp1>>>UDR weitergegeben werden
            sts         UDR0,temp1            ; Put LSB data (r17) into buffer, tranceived data
            reti
    ;(polling)
    data_transmit:
            lds            temp0,UCSR0A
            sbrs        temp0,UDRE0            ;**
            rjmp        data_transmit        ;**
            sts         UDR0,temp1            ; Put LSB data (r17) into buffer, tranceived data
            ret
    
    ;**********************daten_empfangen **********************
    INT_USART_TX:
            lds            temp1,UDR0            ; Put data from buffer into r17, received Data
            ;siehe data_received;** man kann in der wartezeit andere sachen erledigen
            ;bis der int kommt im INT selbst könnte man ne art daten-schreib-schleife implementieren
            ;um weitere daten zu empfangen die dann an UDR>>>temp1 weitergegeben werden
            reti
    ;(polling)
    data_received:
            lds            temp0,UCSR0A
            sbrs        temp0,RXC0            ;**
            rjmp        data_received        ;**
            lds             temp1,UDR0            ; Put data from buffer into r17, received Data
            ret
    
    ;********************DatenRegisterLeereInterrupt***********************
    INT_UDRE:
            ;SOLANGE dieses register leer ist wird diese routine aufgerufen
            ;also eigentlich immer wenn UDR=0
            reti
    AtMega328_RS_Txt_out.asm
    Code:
    ;**************Zeichen AUSGABE PC**************************************
    werbe_rs:
            ldi         ZH,high(rs_out0*2)
            ldi         ZL,low(rs_out0*2)
            rcall         txt_out_rs
            ;rcall         txt_out_rs_debug
            rcall        enter_rs232
            ret
    
    Sonar1_rs:
            ldi         ZH,high(rs_out1*2)
            ldi         ZL,low(rs_out1*2)
            rcall         txt_out_rs
            ;rcall         txt_out_rs_debug
            ;rcall        enter_rs232
            ret
    
    millimeter_rs:
            ldi         ZH,high(rs_out2*2)
            ldi         ZL,low(rs_out2*2)
            rcall         txt_out_rs
            ;rcall         txt_out_rs_debug
            rcall        enter_rs232
            rcall        enter_rs232
            ret
    
    microsekunden_rs:
            ldi         ZH,high(rs_out3*2)
            ldi         ZL,low(rs_out3*2)
            rcall         txt_out_rs
            ;rcall         txt_out_rs_debug
            rcall        enter_rs232
            ret
    
    ;************************Zahleausgabe*******************************
    HCSR04_micros_out_uart:
            rcall        Sonar1_rs
            lds            mathergll,Sonar1l    ;alles in die Mathregs laden
            lds            mathergl,Sonar1h
            clr            mathergh
            clr            matherghh        
            rcall        zahl_rs_load_out
            rcall        microsekunden_rs
            ret
    
    HCSR04_mm_out_uart:
            rcall        Sonar1_rs
            rcall        zahl_rs_load_out_xy ;variable Ausgabe 
            rcall        millimeter_rs
            ret
    
    ;************************direktwandlung*wort*in*ASCII***************
    rs_out0: .db "Ultraschall hc-sr04 V0.1",$ff
    rs_out1: .db "Distanz:  ",$ff
    rs_out2: .db "mm",$ff
    rs_out3: .db "us",$ff
    HC_SR04_2.asm
    Code:
    ;********************HC-SR04 Ultraschallsensor*******************
    .equ HCSR04_ddr    = DDRD
    .equ HCSR04_pin    = PIND
    .equ HCSR04_port= PORTD
    
    .equ Echo        = 3
    .equ Trigger    = 4
    
    .equ CTC_T0     = 7         ; benötigt um 1µs zu erzeugen
    
    .equ T1_max_h    = $75   ;high der 30000µs
    .equ T1_max_l    = $30    ;low der  30000 µs 
    
    .equ V_US_20    = 3430    ;dm/s 343 bezogen auf 20°C! Mit Temperatursensor kann hier eingegriffen werden 
    ;************************Init************************************
    init_HCSR04:
            sbi            HCSR04_ddr,Trigger        ;Triggerpin als Ausgang setzen
            cbi            HCSR04_ddr,ECHO
            cbi            HCSR04_port,ECHO        ;Echopin = INT1 als Eingang
    
            rcall        INIT_EXT_INT01            ;Int1 = Echo und Aktivierung von T0 auf st. Flanke
            rcall        mode2_T0_init            ;Auflösung 1µs im CTC ohne INT von OCR0A/B, Toggle OCR0B=PD5, Teiler 1 mit CTC_T0 
            rcall        mode0_T1_init            ;Teiler auf ext. Eingang PD5, OCR1A = T1_max
            
            ret
    
    ;**********************Messung starten***************************
    HCSR04_Start:
            clr            temp1
            out            TCNT0,temp1
            sts            TCNT1h,temp1
            sts            TCNT1l,temp1
            rcall        HCSR04_Trigger            ;Trigger starten
    ;HCSR04 beginnt nach 450µs mit dem setzen des Echos auf High
    ;deshalb INT1 auf steigende Flanke
    HCSR04_wait:
            nop
            nop
            nop
            nop
            sbis        HCSR04_pin,Echo            ;warten bis EchoPin H ist
            rjmp        HCSR04_wait                ;sonst Sprung    
    HCSR04_wait2:
            nop
            nop
            nop
            nop
            sbic        HCSR04_pin,Echo
            rjmp        HCSR04_wait2            ;warten bis Echo zurück kommt H-L
            rcall        prescaler_T0_off        ;
            rcall        prescaler_T1_off        ;beide Timer stoppen
            lds            temp1,TCNT1L
            lds            temp0,TCNT1H            ;Zeit in µs auslesen = doppelter Weg
            lsr            temp0
            ror            temp1                    ;einmal halbieren
            sts            sonar1h,temp0
            sts            sonar1l,temp1            ;Rohzeit in µs speichern = einfacher Weg
            ret
    
    HCSR04_Trigger:
            sbi            HCSR04_port,Trigger
            rcall        wait10us
            rcall        wait10us
            cbi            HCSR04_port,Trigger
            ret
    
    ;***********************Berechnung der Entfernung anhand      ************************
    ;***********************der Geschwindigkeit und der gem. Zeit ************************
    Zeit_zu_Entfernung: ;Geschwindigkeit Schall * Zeit = Entfernung Bsp.: 343m/s * 15001µs = 5145343µm
            ldi            temp3,high (V_US_20)
            ldi            temp2,low (V_US_20)        ;feste oder errechnete Schgallgeschwindigkeit laden
            lds            temp1,sonar1h
            lds            temp0,sonar1l            ; Zeit in µs laden
            
            mov            math1h,temp3
            mov            math1l,temp2
            mov            math2h,temp1
            mov            math2l,temp0
    
            rcall        hmul_2_16bit            ; Berechnung durchführen Erg in Mathergll:hh
            ret
    - - - Aktualisiert - - -

    zum angesprochenen Punkt der Luftdruck kann vernachlässigt werden solange man es nicht im Vakuum nutzen möchte...
    http://automatisierungstechnik.fh-pf...tLuftdruck.pdf
    Geändert von avr_racer (20.08.2018 um 12:35 Uhr)

  2. #2
    HaWe
    Gast
    Zitat Zitat von avr_racer Beitrag anzeigen
    zum angesprochenen Punkt der Luftdruck kann vernachlässigt werden solange man es nicht im Vakuum nutzen möchte...
    http://automatisierungstechnik.fh-pf...tLuftdruck.pdf
    stimmt, eher ist die absolute Feuchte interessant, aber auch das wird in der Messgenauigkeit eher untergehen

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174
    Nachtrag Zeitschleifen für 16Mhz

    zeitschleifen_16Mhz.asm
    Code:
    ;************************zeitschleifen******************************************
    
    wait1us:nop
            ret
    
    wait6us:push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$0f
            rjmp        z_loop2
    
    wait9us:push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$19
            rjmp        z_loop2
    
    wait10us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$1c
            rjmp        z_loop2
    
    wait25us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$4c
            rjmp        z_loop2
    
    wait50us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$9c
            rjmp        z_loop2
    
    wait55us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$ac
            rjmp        z_loop2
    
    wait58us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$b6
            rjmp        z_loop2
    
    wait60us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$bc
            rjmp        z_loop2
    
    wait64us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$c9
            rjmp        z_loop2
    
    wait70us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$dc
            rjmp        z_loop2
    
    wait100us:
            push        xh
            push        xl
            ldi            xh,$01
            ldi            xl,$3c
            rjmp        z_loop2
    
    wait500us:
            push        xh
            push        xl
            ldi            xh,$06
            ldi            xl,$3a
            rjmp        z_loop2
    
    wait1ms:push        xh
            push        xl
            ldi            xh,$0c
            ldi            xl,$78
            rjmp        z_loop2
    
    
    wait10ms:push        xh
            push        xl
            ldi            xh,$7c
            ldi            xl,$cc
            rjmp        z_loop2
    
    wait150ms:
            ldi            temp0,$0f
            rjmp        waitx10ms
    
    wait750ms:
            ldi            temp0,$4b
            rjmp        waitx10ms
    
    wait1s:    ldi            temp0,$64
            rjmp        waitx10ms
    
    
    
    z_loop2:sbiw        xh:xl,$01
            cpi            xl,$00
            brne        z_loop2
            cpi            xh,$00
            brne        z_loop2
            pop            xl
            pop            xh
            ret
    
    waitxms:rcall        wait1ms
            dec            temp0
            brne        waitxms
            ret
    
    waitx10ms:
            rcall        wait10ms
            dec         temp0
            brne        waitx10ms
            ret

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174
    So Update wie angekündigt

    mit / ohne Temperatursensor
    Berechnung der Geschwindigkeit bei ändernder Temperatur

    Ultraschall mit DS18S20 auf RS232.zip

Ähnliche Themen

  1. Verkaufe Arduino Nano V3.0 mit Atmega328
    Von razer6 im Forum Kaufen, Verkaufen, Tauschen, Suchen
    Antworten: 0
    Letzter Beitrag: 08.05.2017, 16:25
  2. ATMega328 Massefläche des MLF-Gehäuses
    Von rapo im Forum AVR Hardwarethemen
    Antworten: 2
    Letzter Beitrag: 07.02.2016, 22:17
  3. Bascom Atmega328 Chip ID : FFFFF
    Von Projekt 2252 im Forum Bascom / C / ASM / Sketch / Codesammlung / Programmschnipsel
    Antworten: 1
    Letzter Beitrag: 30.07.2014, 19:26
  4. Syncfehler mit Arduino Nano ATmega328
    Von Sokapex im Forum Arduino -Plattform
    Antworten: 4
    Letzter Beitrag: 26.05.2013, 13:32
  5. SainSmart uno r3-atmega328
    Von Droggelbecher im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 18
    Letzter Beitrag: 04.01.2013, 12:57

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen