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

Thema: Ds18s20 + uart

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174

    Ds18s20 + uart

    Anzeige

    Praxistest und DIY Projekte
    Hallo Bastler aller Welt,
    hier mal ein wenig Quelltext um einen/mehrere DS18S20 anzusprechen.

    AVRStudio 4.19 730
    Atmega8
    STK500

    Inhalt:
    1. ds1820_init.asm
    2. ds1820.asm
    3. uart_std.asm
    4. EEprom.asm
    5. zeitschleifen.asm


    Über pc_ser:
    wird die Adresse des DS ausgelesen und im EEprom gespeichert.
    Achtung zum auslesen nur immer einen DS am Pin

    ds_mess_adr:
    hier werden alle Slaves gleichzeitig angesprochen um die Temperaturmessung zu starten und anhand aller Adressen,
    die im EEprom stehen, die Temps ausgelesen, umgewandelt, im SRAM 3bytig vorgehalten (Vozeichen,Grad,Halbegrad)
    und dann über die UART verschickt

    ds_mess:
    ist nur für einen Sensor am Bus vorgesehen über den Befehl SKIP_ROM + Ausgabe über UART

    temp_rs232:
    Ausgabe an UART wie folgt DS01 +22.50°C usw



    Wünsche viel Spaß damit

    ds1820_init.asm
    Code:
    ;###########################################
    ;# Projekt:     DS18S20    + UART                #
    ;#                                             #
    ;#                                            #
    ;# Taktfrequenz des AVR: 4 MHz                 #
    ;#                                             #
    ;# CS-SOFT                                     #
    ;###########################################
    
    .include "m8def.inc"    ;Atmega8
    
    .def math1h     = r8
    .def math1l     = r9
    .def math2h     = R10
    .def math2l     = r11
    .def matherghh    = r12
    .def mathergh    = r13
    .def mathergl    = r14
    .def mathergll    = r15
    
    .def temp0 = r16     ;
    .def temp1 = r17     ;
    .def temp2 = r18
    .def temp3 = r19     ;
    .def temp4 = r20
    .def cnt   = r21
    
    .equ cpu    = 4000000
    .equ Baud    = 9600
    .equ UBRRx    = cpu/(16*Baud)-1
    
    /*
    ;**********LCD Port mit 74HC164
    .equ port_lcd_x =     portd        
    .equ ddrx_lcd_x =     ddrd
    ;                    Pinbelegungen
    ;                                 STD
    .equ SClock        =                 2        ;LCD    ;;;
    .equ SRS        =                2
    .equ SData        =                 4        ;74164    ;;;;;so Kann die HW angeschlossen sein
    .equ SRW        =                4
    .equ Light        =                 5        ;LCD    ;;;;;
    .equ SEnable    =                 6        ;74164    ;;;
    
    ;**********LCD-Port parallel für LCD-Simulationssoftware HapSim
    .equ     port_lcd_x = portd                ;auch für parallel notwendig
    .equ     ddrx_lcd_x = ddrd                ;auch für parallel notwendig
    .equ st_port_lcd_x = portb
    .equ st_ddrx_lcd_x = ddrb
    ;                    Pinbelegungen
    ;                                STD        ;
    .equ RS            =                0        ;
    .equ RW            =                1
    .equ Light        =                 2        ;
    .equ Enable        =                 3        ;
    
    ;Entry Set
    .equ SH            =    0 ;1 = Display shift    0 = not shifted
    .equ ID            =    1 ;1 = increase         0 = decrease
    .equ HES        =    2 ;immer 1 setzen Symbolisiert das Ende
                          ;des Commandos
    ;DISPLAY on/off
    .equ B            =    0 ;1 = Blink         0 = no Blink
    .equ C            =    1 ;1 = Cursor on     0 = Cursor off
    .equ D            =    2 ;1 = Disp on        0 = Disp off
    .equ HD            =    3 ;immer 1 setzen Symbolisiert das Ende
                          ;des Commandos
    ;Shift
    .equ RL            =    2 ;1 = right shift    0 = left shift
    .equ SC            =    3 ;1 = Disp shift    0 = Cursor move
    .equ HS            =    4 ;immer 1 setzen Symbolisiert das Ende
                          ;des Commandos
    ;SET Function
    .equ F            =    2 ;1 = 5x10            0 = 5x7
    .equ N            =    3 ;1 = 2line(4line)    0 = 1line
    .equ DL            =    4 ;1 = 8bit int        0 = 4bit interface
    .equ HSF        =    5 ;immer 1 setzen Symbolisiert das Ende
                          ;des Commandos
    */
    ;****DS18S20 auf port -->
    .equ ddrx_ds        = ddrc        ;
    .equ portx_ds        = portc        ;hier änder falls anderer Port
    .equ pinx_ds        = pinc        ;
    .equ pin_ds_x        = 0            ;hier auf welchen Pin
    .equ dsIDrng        = $0080        ;Speicherbereich für DS-ID's = Y-Pointer wird nur temporär genutzt
    .equ dstemp            = $0090        ;Speicherbereich für Temp mit Kommastelle = Y-Pointer
    
    ;**********SRAM
    .equ     erg_k        =    $0060            ;erg_k wird bis zu 4 weiteren bytes genutzt sprich erg_k+4
    .equ     ocr2s        =    $0065            ;für T2
    .equ     ocra1h        =    $0066            ;;;;;
    .equ     ocra1l        =    $0067            ;;;;;;;; für T1 A channel
    .equ     ocrb1h        =    $0068            ;;;;;
    .equ     ocrb1l        =    $0069            ;;;;;;;; für T1 B channel
    .equ     icr1xh        =    $006a            ;;;;;
    .equ     icr1xl        =    $006b            ;;;;;;;; für T1 ICR
    .equ    hadc        =    $006c            ;adc
    .equ    ladc        =    $006d            ;adc
    .equ    eep_adrh    =    $006e            ;eeprom
    .equ    eep_adrl    =    $006f            ;eeprom
    .equ    LTC_wertH    =    $0070
    .equ    LTC_wertL    =    $0071
    .equ    Poti0        =    $0072            ;Potentiometer 0
    .equ    ploudr        =    $0073            ;poti für lautstärke rechts
    .equ    ploudl        =    $0074            ;poti für lautstärke links
    .equ    phigh        =    $0075            ;poti für höhen        
    .equ    pbass        =    $0076            ;poti für bass
    .equ     halbeh        =    $0077        ;
    .equ    halbel        =    $0078
    
    .equ     temp_lsb    =    $0080        ;
    .equ     temp_msb    =    $0081        ;
    .equ     th_register    =    $0082        ;
    .equ     tl_register    =    $0083        ;
    .equ     res_byte4    =    $0084        ;
    .equ     res_byte5    =    $0085        ;
    .equ     cnt_remain    =    $0086        ;
    .equ     cnt_per_c    =    $0087        ;
    .equ     crc            =    $0088        ;gesperrt ID wird ausgelesen aber nicht gespeichert
    .equ    dsnmax        =    $0089
        
    ;***************************Einsprungadressen***********************
    .cseg
    .org $0000
        rjmp    stack
    .org $0001            ;1
        reti;rjmp    INT_0
    .org $0002            ;2
        reti;rjmp    INT_1
    .org $0003            ;3
        reti;rjmp    INT_OC2
    .org $0004            ;4
        reti;rjmp    INT_OVF2
    .org $0005            ;5
        reti;rjmp    INT_ICP1
    .org $0006            ;6
        reti;rjmp    INT_OC1A
    .org $0007            ;7
        reti;rjmp    INT_OC1B
    .org $0008            ;8
        reti;rjmp    INT_OVF1
    .org $0009            ;9
        reti;rjmp    INT_OVF0
    
            reti        ;a keine SPI Routinen
    
    .org $000b            ;b
        reti;rjmp    INT_URXC
    .org $000c            ;c
        reti;rjmp    INT_UDRE
    .org $000d            ;d
        reti;rjmp    INT_UTXC
    .org $000e            ;e
        reti;rjmp    adc_rdy
    .org $000f            ;f
        reti;rjmp    eeprom_rdy
    .org $0010            ;10
        reti;rjmp    ac_int
    
            reti        ;11    keine 2wireRoutinen
            reti        ;12 keine SPMRoutinen
    
    ;***************************Init mit allem drumdran*****************
    
    stack:    ldi         temp1,high(ramend)  ;Stackpointer festlegen
            out         sph, temp1
            ldi         temp1,low(ramend)   ;Stackpointer festlegen
            out         spl, temp1
            rcall        sram                
    
            ldi            temp0,(1<<pb0|1<<pb1|1<<pb2|1<<pb3)
            out            portb,temp0
            
            rcall        usart_init            ;Uart initalisieren
            rcall        werbe1_rs            ;Werbung
        ;    rcall        wait1s
            
    ;***********************masterprogramm*******************************
    start:    sbis        pinb,0
            rcall        pc_ser                ;SerienNummer erfassen 1nes Sensor und in EEP speichern und Ausgabe RS232
            
            sbis        pinb,2
            rcall        ds_mess_adr            ;Temp von n-Sensoren mit Adresse auslesen und Ausgabe RS232
            sbis        pinb,3
            rcall        ds_mess                ;Temp 1nes Sensors auslesen und Ausgabe RS232
            rjmp        start
    
    ;*******************Über RS232 Anzeige SerialNummer**************************
    pc_ser:    rcall        wait150ms            ;warten
            rcall        txt_adr_rs            ;Txt an RS232
            rcall        ds18_get_ser        ;Adresse + EEP
            rcall        adr_hex_ASCII_rs    ;Ausgabe auf RS232
            ret
    
    ;******************Messung mehrerer Sensoren über Adresse + Temp auf LCD*****
    ds_mess_adr:
            rcall        wait150ms            ;warten
            rcall        ds18_t_adr            ;TempAdress lesen
            rcall        temp_rs232            ;Ausgabe auf RS232
            ret
    
    ;******************Messung eines Sensors + Temp auf LCD**********************
    ds_mess:rcall        wait150ms            ;warten
            rcall        ds18_t_skip_rom        ;Temp 1 Sensors
            rcall        temp_rs232_1        ;Ausgabe auf RS232
            ret
    
    ;*******************Asugabe auf RS232****************************************
    temp_rs232:
            clr            cnt                    ;löschen
            rcall        rd_ds_n                ;Anzahl der DS laden
            rcall        load_dstemp_Y        ;Temperaturspeicherbereich laden
    temp_rs232_2:            
            rcall        txt_DSn_rs            ;Textausgabe
            inc            cnt                    ;+1
            push        cnt                    ;on stack
            mov            temp1,cnt            ;moven
            rcall        zahl_out_rs1        ;Ausgabe Zahl
            rcall        leer_zeichen_rs232    ;leerzeichen        
        
            ld            temp1,y                ;von fester Adr laden
            rcall        data_transmit        ;senden
            subi        temp1,$20            ;+- Zeichen zerstören sonst wird endlos gespeichert
            st            y+,temp1            ;zurückspeichern y+1
    
            rcall        temp_rs_load        ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
            rcall        txt_punkt_rs
            rcall        temp_rs_load        ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer    
            rcall        txt_grad_cel_rs
            rcall        enter_rs232            ;Enter1
            
            pop            cnt                    ;from stack
            lds            temp1,dsnmax        ;Sensoranzahl
            cp            cnt,temp1            ;vergleich
            brne        temp_rs232_2        ;!= spring
            rcall        enter_rs232            ;Enter2
            ret
    
    temp_rs232_1:
            rcall        load_dstemp_Y        ;Temperaturbereich laden
            rcall        txt_DSn_rs            ;Textausgabe
            ldi            temp1,$01            ;
            rcall        zahl_out_rs1        ;Ausgabe Zahl
            rcall        leer_zeichen_rs232            
        
            ld            temp1,y                ;von fester Adr laden
            rcall        data_transmit        ;senden
            subi        temp1,$20            ;+- Zeichen zerstören sonst wird endlos im Ram gespeichert
            st            y+,temp1            ;zurückspeichern y+1
    
            rcall        temp_rs_load        ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer
            rcall        txt_punkt_rs
            rcall        temp_rs_load        ;hier erfolgt Ausgabe Hex->Dez + Ausgabe der Zehner+Einer    
            rcall        txt_grad_cel_rs
            rcall        enter_rs232            ;Enter1
            
            ret
    
    ;**********************Masterclr***************************************
    sram:    clr            temp0
            ldi            yl,low(SRAM_START)
            ldi            yh,high(SRAM_START)            ;Masterclr des Sram's über
    sram2:    st            y+,temp0                ;die indirekte Adressierung
            cpi            yl,$a0                    ;bis zur zelle x löschen
            brne        sram2        
            ret
    
    ;*******************Ausgabe RS232************************************
    werbe1_rs:
            ldi            zh,high(out1*2)
            ldi            zl,low(out1*2)
            rcall        txt_out_rs
            rcall        enter_rs232
            ret
    
    txt_adr_rs:
            ldi            zh,high(out2*2)
            ldi            zl,low(out2*2)
            rcall        txt_out_rs
            ret
    
    txt_DSn_rs:
            ldi            zh,high(out3*2)
            ldi            zl,low(out3*2)
            rcall         txt_out_rs
            ret
    
    txt_grad_cel_rs:
            ldi            zh,high(out4*2)
            ldi            zl,low(out4*2)
            rcall         txt_out_rs
            ret
    
    txt_punkt_rs:
            ldi            zh,high(out5*2)
            ldi            zl,low(out5*2)
            rcall         txt_out_rs
            ret
    
    ;****************DatenBank******************************************
    out1:    .db "DS18S20 + RS232",$ff
    out2:    .db "DS Adr: ",$ff
    out3:    .db "DS",$ff
    out4:    .db "°C",$ff
    out5:    .db ".",$ff
    
    ;*************************weitere*includedata***********************
    .include "ds1820.asm"                                                    ;ds1820
    ;.include "j:\etronik\Software3\sonstiges\origin\lcd_KS0066_KS0070_8bit.asm"     ;LCD-Routinen
    ;.include "l:\etronik\Software3\sonstiges\origin\lcd_KS0066_KS0070_8bit_HapSim.asm"
    .include "j:\etronik\Software3\sonstiges\origin\EEprom.asm"
    .include "j:\etronik\Software3\sonstiges\origin\uart_std.asm"
    .include "j:\etronik\Software3\sonstiges\origin\zeitschleifen.asm"
    ;*************************ENDE**************************************
    ds1820
    Code:
    ;dssensonsor auf portX pinY
    ;*************************temp eines sensors auslesen******************        
    ds18_t_skip_rom:    
            cli
            rcall        ds_reset            ;wer ist da???
            rcall        skip_rom            ;ansprechen aller slaves +
            rcall        convert_t            ;start tempmessung
            rcall        ds_reset            ;wer ist da???
            rcall        skip_rom            ;ansprechen aller slaves+vorbereitung der tempmessung        
            rcall        read_scratchpad        ;Sensor auslesen tempim temp_lsb, vorzeichen im temp_msb
            rcall        ds_reset
            rcall        Diven_2                ;Div /2 mit Beachtung Vorzeichen
            sei
            ret
    
    ;*******************mehrere Sensoren anhand adresse auslesen***********
    ds18_t_adr:
            cli
            rcall        ds_reset            ;wer ist da???
            rcall        skip_rom            ;ansprechen aller slaves +
            rcall        convert_t            ;start tempmessung
            
            clr            zl                    ;
            clr            zh                    ;pointer clr
            sts            eep_adrl,zl            ;
            sts            eep_adrh,zh            ;        
            rcall        rd_ds_n                ;anzahl ds aus eeprom holen = Durchläufe
            lds            cnt,dsnmax            ;cnt = dsnmax
    ds18_t_adr2:
            rcall        adr_ee_sr            ;adresse von eeprom in sram laden
            rcall        ds18_get_t_adr        ;sendet adressen um temp zu lesen
            rcall        Diven_2                ;Div /2 mit Beachtung Vorzeichen
            dec            cnt                    ;-1
            cpi            cnt,$00                ;=?
            brne        ds18_t_adr2            ;!= zu label springen
            sei
            ret        
    
    ds18_get_t_adr:
            rcall        ds_reset            ;wer ist da???
            rcall        match_rom            ;adresse senden
            rcall        read_scratchpad        ;auslesen
            rcall        ds_reset            ;
            ret    
    
    ;*****************************uniqe-serial*****************************
    ds18_get_ser:
            rcall        ds_reset            ;wer ist da???
            rcall        read_rom            ;Befehl senden um adresse lesen
            rcall        adr_sr_ee            ;DS-Adress von SRAM -> EEProm
            ret
    
    ;*********************adresse in EEprom ablegen************************
    adr_sr_ee:
            clr            zl
            clr            zh
            sts            eep_adrl,zl
            sts            eep_adrh,zh            ;immer auf anfang setzen
            rcall        load_ID_rng_Y        ;Speicherbereich laden
    adr_sr_ee2:
            rcall        eeprom_read            ;von erster adresse lesen
            cpi            temp0,$10            ;wenn keine $10
            brne        adr_sr_ee3            ;dann springe
            rcall        nxt_adr_eep            ;nächste eeprom-ZEILE!!!!!
            lds            temp0,eep_adrh
            cpi            temp0,$01            ;= $100 = 256/8byte = N-Sensoren    
            breq        eeprom_voll
            rjmp        adr_sr_ee2            ;sonst ist ein sensor schon abgespeichert
    adr_sr_ee3:
            ld            temp0,y+            ;von pointer y laden
            rcall        eeprom_write        ;schreibe wert von y in eeprom
            rcall        adr_cnt                ;nächste adresse vorbereiten
            cpi            yl,dsIDrng+8        ;yl = stopadresse ?
            brne        adr_sr_ee3            ;wenn != stopadresse zu label
            lds            temp0,dsnmax        ;sonst weiter
            inc            temp0                ;wieviele Sensoren abgespeichert wurden
            sts            dsnmax,temp0
            rcall        wr_ds_n                ;und anzahl der DS in eeprom speichern
            ret
    
    eeprom_voll:
            ldi            temp1,0b10010100
        ;    rcall        out_max_sens        ;hier könnte ein Anzeige realisiert werden
            rcall        nxt_adr_eem            ;weil max. Anzahl der Sensoren erreicht ist
            ret
    
    nxt_adr_eep:
            adiw        zh:zl,$10            ;EEP ADR plus
            sts            eep_adrl,zl
            sts            eep_adrh,zh    
            ret
    
    nxt_adr_eem:
            sbiw        zh:zl,$10            ;EEP ADR minus
            sts            eep_adrl,zl
            sts            eep_adrh,zh    
            ret
    
    ;*********************************Adresse von ee in sram*****************
    adr_ee_sr:                                ;adresse muss vorher in eep_adrh:l geladen werden in dem programm was dieses aufruft
            rcall        load_ID_rng_Y        ;weil adr_ee_sr wird auch zum auslesen weiter Sensoren genutzt
    adr_ee_sr_1:
            rcall        eeprom_read            ;auslesen der adr beginnend mit family code (10h)    
            st            y+,temp0            ;8byte in sram schreiben
            rcall        adr_cnt                ;neu adresse hoch zählen eeprom spalte
            cpi            yl,dsIDrng+8        ;yl = stoppadresse ??
            brne        adr_ee_sr_1            ;nein
            rcall        nxt_adr_eep            ;sonst neue adresse laden
            ret
    
    ;********************Pointer setzen**************************************
    load_ID_rng_Y:
            ldi            yl,low(dsIDrng)        ;ID's speichern
            ldi            yh,high(dsIDrng)
            ret
    
    load_dstemp_Y:
            ldi            yh,high(dstemp)        ;Temperaturbereich
            ldi            yl,low(dstemp)    
            ret
    
    ;*********************Anzahl der DS's von eeprom lesen feste Adresse*****
    rd_ds_n:lds            temp1,eep_adrl
            lds            temp2,eep_adrh
            push        temp1
            push        temp2
            ldi            temp0,$0f
            sts            eep_adrl,temp0
            clr            temp2
            sts            eep_adrh,temp2
            rcall        eeprom_read
            sts            dsnmax,temp0
            pop            temp2
            pop            temp1
            sts            eep_adrh,temp2
            sts            eep_adrl,temp1
            ret
    
    ;********************Anzahl der DS's in eeprom schreiben feste Adresse****
    wr_ds_n:lds            temp1,eep_adrl
            lds            temp2,eep_adrh
            push        temp1
            push        temp2
            ldi            temp1,$0f
            sts            eep_adrl,temp1
            clr            temp2
            sts            eep_adrh,temp2
            lds            temp0,dsnmax
            rcall        eeprom_write
            pop            temp2
            pop            temp1
            sts            eep_adrh,temp2
            sts            eep_adrl,temp1
            ret
    
    ;***ansprechen aller slave's, tempmessung auslösen aller sensoren*******
    ;***nachfolgend muss keine adr gesendet werden nur 1slave einfache******
    ;***kommunikation ohne adr zu senden ***********************************
    skip_rom:
            ldi            temp1,$cc
            rcall        write_command        ;read or write
            ret
    
    ;**************************read rom 64bits=8byte*********************
    read_rom:
            ldi            temp1,$33            ;Befehl
            rcall        write_command        ;senden
            rcall        lesen                ;Adresse lesen 0 -> 7 + 8tes byte = CRC!!!!!!!!!!!!
            ret
    
    ;**************************Adressierung mit 64bit********************
    match_rom:
            ldi            temp1,$55            ;Befehl
            rcall        write_command        ;senden Achtung Adresse ohne CRC senden also nur 8/9byte senden    
            rcall        schreiben            ;8bytes schreiben
            ret
    
    ;*******************write_scratchpad(schreiben Th und Tl 2byte)******
    write_scratchpad:
            ldi            temp1,$4e            ;Befehl
            rcall        write_command        ;senden
            rcall        load_ID_rng_Y        ;lese/schreib Pointer laden
    write_scratchpad2:
            ld            temp1,y+            ;laden
            rcall        write_command        ;Bytes senden
            cpi            yl,temp_lsb+2        ;Vergleich auf +2
            brne        write_scratchpad2
            ret    
    
    ;*******************read_scratchpad(auslesen der 9byte)**************
    read_scratchpad:
            ldi            temp1,$be            ;Befehl
            rcall        write_command        ;senden
            rcall        lesen                ;9bytes lesen
            ret        
    
    ;***********Convert---T temperaturmessung starten im ds**************
    convert_t:
            ldi            temp1,$44            ;Befehl
            rcall        write_command        ;senden
            rcall        wait6us                
            cbi            ddrx_ds,pin_ds_x    
            rcall        wait9us                
            sei                                ;Global INT-Freigabe
            rcall        wait750ms            ;unterdrückung 85.00 im disp.
    convert_t1:
            sbis        pinx_ds,pin_ds_x
            rjmp        convert_t1
            cli                                ;Global INT-Sperre
            ret
    
    ;*********************auslesen*****************************************
    lesen:    rcall        load_ID_rng_Y        ;lese/schreib Pointer laden
    lesen_2:rcall        read_bit            ;Bytes lesen
            st            y+,temp3            ;speichern
            cpi            yl,temp_lsb+9        ;Vergleich auf +9
            brne        lesen_2
            ret
    
    ;*********************schreiben**************************************
    schreiben:
            rcall        load_ID_rng_Y        ;lese/schreib Pointer laden
    schreiben_2:
            ld            temp1,y+            ;laden
            rcall        write_command        ;Bytes lesen
            cpi            yl,temp_lsb+8        ;Vergleich auf +8
            brne        schreiben_2
            ret
    
    ;*****************************RESETPULS*********************************
    ds_reset:
            sbi            ddrx_ds,pin_ds_x        
            cbi            portx_ds,pin_ds_x        ;puls senden
            rcall        wait500us                ;
            cbi             ddrx_ds,pin_ds_x        ;freigabe für DS
            rcall        wait70us                
    wait_puls:
            sbic        pinx_ds,pin_ds_x
            rjmp        wait_puls                ;falls bus high zurück
    wait_puls_end:                                ;auf Antwort warten
            sbis        pinx_ds,pin_ds_x
            rjmp        wait_puls_end            ;falls bus low zurück
            ret
    
    ;************************Unterprogramme******************************
    ;Byte schreiben
    write_command:
            ldi            temp2,$08            ;8Bits
    write_command1:
            sbrs        temp1,0
            rcall        write_0                ;schreibe 1
            sbrc        temp1,0
            rcall        write_1                ;schreibe 0
            lsr            temp1                ;hier schiebbefehl von ror auf lsr geändert sonst
            dec            temp2                ;wenn ror muss unter read_bit clc eingefügt werden
            brne        write_command1        ;hatte auf UniqueSerial keinen einfluss weil kein bit im C
            ret                                ;stand
    
    write_1:cbi            portx_ds,pin_ds_x
            sbi            ddrx_ds,pin_ds_x
            rcall        wait6us
            cbi            ddrx_ds,pin_ds_x
            rcall        wait64us
            ret
    
    write_0:cbi            portx_ds,pin_ds_x
            sbi            ddrx_ds,pin_ds_x
            rcall        wait60us
            cbi            ddrx_ds,pin_ds_x
            rcall        wait10us
            ret
    
    ;Byte lesen
    read_bit:
            clc                                ;
            clr            temp3                ;datenwort in temp3
            ldi            temp4,$08            ;8bits
    read_bit0:
            lsr            temp3                ;hier ror zu lsr geändertvweil bei temp ein bit zuviel
            cbi            portx_ds,pin_ds_x    ;DS anstupsen um
            sbi            ddrx_ds,pin_ds_x    ;nächstes Bit zu holen
            rcall        wait6us                ;warten
            cbi            ddrx_ds,pin_ds_x    ;Pin für DS freigeben
            rcall        wait9us                ;warten
            sbis        pinx_ds,pin_ds_x    ;abfrage auf
            rjmp        read_bit1            ;0 lesen
            ldi         temp2,$80            ;1 lesen
            add         temp3,temp2
            rjmp         read_bit2
    read_bit1:
            ldi            temp2,$00
            add            temp3,temp2
    read_bit2:
            rcall        wait55us
            dec            temp4
            brne        read_bit0
            ret
    
    ;*****Division /2 liest erst MSB für +- dann Berechnen ************
    Diven_2:rcall        load_dstemp_Y        ;startadress für Bereich wo die Temps gespeichert werden
            rcall        Diven_3        
    Diven_22:
            lds            temp0,temp_msb
            cpi            temp0,$ff            ;Vergleich auf Minus
            breq        diven_minus
    diven_plus:
            ldi            temp0,'+'
            st            y+,temp0
            lds            temp0,temp_lsb
            lsr            temp0
            st            y+,temp0
            rcall        diven_komma
            st            y+,temp0
            ret
    
    diven_minus:
            ldi            temp0,'-'
            st            y+,temp0
            lds            temp0,temp_lsb
            neg            temp0
            lsr            temp0
            st            y+,temp0
            rcall        diven_komma
            st            y+,temp0        
            ret
    
    diven_komma:
            in            temp1,SREG
            sbrc        temp1,SREG_C
            rcall        set_half
            sbrs        temp1,SREG_C
            rcall        clr_half
            ret
    
    set_half:
            ldi            temp0,$32
            ret
    
    clr_half:
            clr            temp0
            ret
    
    Diven_3:ld            temp0,y
            cpi            temp0,'+'
            breq        Diven_31
            cpi            temp0,'-'
            breq        Diven_31
            ret
    Diven_31:
            adiw        yh:yl,$03
            rjmp        Diven_3
            
    ;***********************Zeiteschleifen*******************************
    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
    
    ;**************Zeichen AUSGABE PC**************************************
    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($0060)
            ldi            xl,low($0060)
            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*************************************
    temp_rs_load:
            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_ergk4    ;ERGK + 4 = $0064 wird nur ein byte ausglesen
            rcall        zahl_out_rs        ;Dez in ASCII + Ausgabe
            pop            yl                ;from stack
            pop            yh                ;from stack
            ret    
    
    zahl_out_rs:    ;Ausgabe 2er Zahlen
            ld            temp1,y
    zahl_out_rs1:
            mov            temp2,temp1
            swap        temp1
            andi        temp1,$0f
            ori            temp1,$30
            rcall        data_transmit
                    ;Ausgbabe 1er Zahl
            mov            temp1,temp2
            andi        temp1,$0f
            ori            temp1,$30
            rcall        data_transmit
            ret
    
    ;**********Speicherpunkte wieviele Stellen ausgegeben werden sollen*********
    load_Y_ergk:
            ldi            yh,high(erg_k)            
            ldi            yl,low(erg_k)            ;speicherpunkt laden
            ret
    
    load_Y_ergk1:
            ldi            yh,high(erg_k+1)            
            ldi            yl,low(erg_k+1)            ;speicherpunkt laden
            ret
    
    load_Y_ergk2:
            ldi            yh,high(erg_k+2)            
            ldi            yl,low(erg_k+2)            ;speicherpunkt laden
            ret
    
    load_Y_ergk3:
            ldi            yh,high(erg_k+3)            
            ldi            yl,low(erg_k+3)            ;speicherpunkt laden
            ret
    
    load_Y_ergk4:
            ldi            yh,high(erg_k+4)            
            ldi            yl,low(erg_k+4)            ;speicherpunkt laden
            ret
    
    ;*****************Wandlung von 1A-hex in 1A-ASCII = 31 , 41 Anzeige ist 1 A
    adr_hex_ASCII_rs:        
            rcall        load_ID_rng_Y            ;Bereich laden der gewandelt und ausgegeben werden soll
    pc_ser2:ld            temp1,y+                ;erstes byte
            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
            cpi            yl,dsIDrng+8            ;ENDE ?
            brne        pc_ser2                    ;nein
            rcall        enter_rs232                ;wenn ja mach noch ein ENTER
            ret
    Angehängte Dateien Angehängte Dateien
    Geändert von avr_racer (12.08.2017 um 13:27 Uhr) Grund: load_hex_dez durch hex_dez ersetzt

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied Avatar von avr_racer
    Registriert seit
    01.04.2014
    Ort
    MecklenburgVorpommern
    Beiträge
    174
    das muss noch in die uart_std.asm mit eingefügt werden irgendwie reicht Zeichenvorrat nicht
    Code:
    ;*************************AUSGBAE zahlen********************************
    ;**********Wandlungsvorbereitung von HEX in DEZ******
    hex_dez: push        xl
            push        xh
            push        zl
            push        zh
            mov            zh,matherghh        ;highhigh    ;wenn ZH=ff>>LCD=42949967295
            mov            zl,mathergh            ;highlow    ;wenn ZL=ff>>LCD=16777215       bei ZH=0
            mov            xh,mathergl            ;high        ;wenn XH=ff>>LCD=65535            bei ZH:ZL=0
            mov            xl,mathergll        ;low        ;wenn xl=ff>>LCD=255             bei XH=0
            push        yl
            push        yh
            rcall        load_Y_ergk            ;Speicherbereich laden          
            ldi           cnt,$ff                ;
    num_1000000000:                            ;Milliarden 
            inc           cnt
            subi          xh, byte2(1000000000)
            sbci          zl, byte3(1000000000)
            sbci        zh,    byte4(1000000000)
            brcc          num_1000000000
            swap        cnt
            st            y,cnt     
            ldi           cnt,$0a
    num_100000000:                             ;100Millionen
            dec           cnt                    ;+1
            subi          xh, byte2(-100000000)
            sbci          zl, byte3(-100000000)
            sbci        zh,    byte4(-100000000)
            brcs          num_100000000        ;ja
            ld            temp0,y
            or            cnt,temp0
            st            y+,cnt                ;fertig speichern
            ldi           cnt,$ff                ;
    num_10000000:                            ;10Millionen
            inc           cnt
            subi          xl, byte1(10000000)
            sbci          xh, byte2(10000000)
            sbci        zl,    byte3(10000000)
            sbci        zh, 0
            brcc          num_10000000
            swap        cnt
            st            y,cnt       
            ldi           cnt,$0a
    num_1000000:                             ;1Million
            dec           cnt                    ;+1
            subi         xl, byte1(-1000000)    ;
            sbci          xh, byte2(-1000000)    ;vergleich auf >1000000
            sbci        zl,    byte3(-1000000)
            brcs          num_1000000            ;ja
            ld            temp0,y
            or            cnt,temp0
            st            y+,cnt                ;fertig speichernn      
            ldi           cnt,$ff                ;
    num_100000:                                ;100Tausend
            inc           cnt
            subi          xl, byte1(100000)
            sbci          xh, byte2(100000)
            sbci        zl,    byte3(100000)
            brcc          num_100000
               swap        cnt
            st            y,cnt    
            ldi           cnt,$0a
    num_10000:                                 ;10Tausend
            dec           cnt                    ;+1
            subi         xl, byte1(-10000)    ;
            sbci          xh, byte2(-10000)    ;vergleich auf >10000
            sbci        zl, byte3(-10000)
            brcs         num_10000            ;ja
            ld            temp0,y
            or            cnt,temp0
            st            y+,cnt                ;fertig speichern      
            ldi           cnt,$ff                
    num_1000:                                ;Tausender 
            inc           cnt
            subi          xl, low(1000)
            sbci          xh, high(1000)
            brcc          num_1000
            swap        cnt
            st            y,cnt        
            ldi           cnt,$0a
    num_100:dec           cnt                    ;100
            subi          xl, low(-100)
            sbci          xh, high(-100)
            brcs          num_100
               ld            temp0,y
            or            cnt,temp0
            st            y+,cnt    
            ldi          cnt,$ff
    num_10:    inc           cnt                    ;Zehner + Einer
            subi          xl, 10
            brcc          num_10
            subi          xl, -10
               swap        cnt
            or            cnt,xl
            st            y+,cnt 
            pop            yh
            pop            yl
            pop            zh
            pop            zl
            pop            xh
            pop            xl 
            ret
    
    ;************************uart_init mit RX interrupt**********************
    usart_init:
            ldi         temp0,(0<<URSEL)
            out            UCSRC,temp0
            clr            temp0
            out            UBRRH,temp0
            ldi            temp0,UBRRx                    ;9600 Baud einstellen PDF S.133 table52
            out         UBRRL,temp0
    
            rcall        char_size8                    ;8 zeichen, 1 stoppbit
            
            ldi            temp0,(0<<U2X|0<<MPCM)        ;no DoubleSpeed, no MultiProzComMode
            out            UCSRA,temp0
            
            ret
    
    char_size5:
            ldi         temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
            out         UCSRC,temp0    
            ldi         temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2)    ;enable RX u TX  <=5bit(UCSZ2=0) 
            out         UCSRB,temp0    ;
            ret                        
            
    char_size6:
            ldi         temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|0<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
            out         UCSRC,temp0    
            ldi         temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2)    ;enable RX u TX  <=6bit(UCSZ2=0) 
            out         UCSRB,temp0    
            ret                                                
                
    char_size7:
            ldi         temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|0<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
            out         UCSRC,temp0        
            ldi         temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2)    ;enable RX u TX  <=7bit(UCSZ2=0) 
            out         UCSRB,temp0    ;
            ret                                            
            
    char_size8:
            ldi         temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
            out         UCSRC,temp0    
            ldi         temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|0<<UCSZ2)    ;enable RX u TX  <=7bit(UCSZ2=0) 
            out         UCSRB,temp0    
            ret                    
    
    char_size9:
            ldi         temp0,(1<<URSEL|0<<UMSEL|0<<UPM1|0<<UPM0|0<<USBS|1<<UCSZ1|1<<UCSZ0|0<<UCPOL) ;URSEL=1 UCSRC1 or UBRRH0,USBS=1 stoppbits1,
            out         UCSRC,temp0    
            ldi         temp0,(0<<RXCIE|0<<TXCIE|0<<UDRIE|1<<RXEN|1<<TXEN|1<<UCSZ2)    ;enable RX u TX  <=9bit(UCSZ2=1) 
            out         UCSRB,temp0    
            ret                                
    
    ;************************uart_deinit********************************
    usart_all_aus:
            clr            temp0
            out            UCSRB,temp0
            out            UCSRC,temp0
            out            UBRRL,temp0
            out            UBRRH,temp0
            ret
    
    usart_ofln:                                    ;wenn unterprogramme nicht 
            clr            temp0                    ;gestört werden dürfen
            out            UCSRB,temp0                ;nur usart offline
            ret
    
    ;**********************daten_senden*********************************
    INT_UTXC:
            ;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
            out         UDR,temp1            ; Put LSB data (r17) into buffer, tranceived data
            reti
    ;(polling)
    data_transmit:
            sbis        UCSRA,UDRE            ;**
            rjmp        data_transmit        ;**
            out         UDR,temp1            ; Put LSB data (r17) into buffer, tranceived data
            ret
    
    ;**********************daten_empfangen **********************
    INT_URXC:
            in             temp1,UDR            ; 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 senden die dann an UDR>>>temp1 weitergegeben werden
            reti
    ;(polling)
    data_received:
            sbis        UCSRA,RXC            ;**
            rjmp        data_received        ;**
            in             temp1,UDR            ; 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
    eeprom.asm
    Code:
    ;*************************************
    eeprom_init:
            ldi        temp0,(1<<EERIE)
            out        EECR,temp0
            sei
            ret
    
    eeprom_rdy:
            ;siehe eeprom_write ;** man kann in der wartezeit andere sachen erledigen
            ;bis der int kommt, um dann weitere daten an den eeprom zum schreiben zu senden 
            ;nur bei eeprom schreiben möglich
            reti
    
    ;Adreessierung im eeprom
    adr_cnt:lds        temp0,eep_adrl
            inc        temp0
            cpi        temp0,$ff
            breq    adr_cnt2
            sts        eep_adrl,temp0
            ret
    adr_cnt2:
            clr        temp0
            sts        eep_adrl,temp0
            lds        temp0,eep_adrh
            inc        temp0
            sts        eep_adrh,temp0
            cpi        temp0,$02
            breq    error_eeprom
            ret
    error_eeprom:
            ;voll
            ret
    
    EEPROM_write:                
            sbic     EECR,EEWE        ;** falls eewe im eecr noch gesetzt
            rjmp     EEPROM_write    ;** spring zu zurück
            lds        r18,eep_adrh
            out     EEARH, r18        ;highbyte der adr
            lds        r17,eep_adrl
            out     EEARL, r17        ;lowbyte der adr
            out     EEDR,r16        ;zu speichernder wert
            sbi     EECR,EEMWE        ;sperrt eeprom master write enable
            sbi     EECR,EEWE        ;setze EEWE um eeprom zu schreiben
            ret
    
    EEPROM_read:                
            sbic     EECR,EEWE        ;falls eewe im eecr noch gesetzt
            rjmp     EEPROM_read        ;springe zurück
            lds        r18,eep_adrh
            out     EEARH, r18        ;highbyte der adr
            lds        r17,eep_adrl
            out     EEARL, r17        ;lowbyte der adr
            sbi     EECR,EERE        ;sperrt lesen des eeproms
            in         r16,EEDR        ;zu lesender wert
            ret
    zeitschleifen.asm
    Code:
    ;************************zeitschleifen******************************************
    wait1us:nop
            ret
    
    wait6us:push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$02
            rjmp        z_loop2
    
    wait9us:push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$04
            rjmp        z_loop2
    
    wait10us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$05
            rjmp        z_loop2
    
    wait25us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$15
            rjmp        z_loop2
    
    wait50us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$2e
            rjmp        z_loop2
    
    wait55us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$33
            rjmp        z_loop2
    
    wait58us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$36
            rjmp        z_loop2
    
    wait60us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$37
            rjmp        z_loop2
    
    wait64us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$3c
            rjmp        z_loop2
    
    wait70us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$42
            rjmp        z_loop2
    
    wait100us:
            push        xh
            push        xl
            ldi            xh,$00
            ldi            xl,$60
            rjmp        z_loop2
    
    wait500us:
            push        xh
            push        xl
            ldi            xh,$01
            ldi            xl,$f0
            rjmp        z_loop2
    
    wait1ms:push        xh
            push        xl
            ldi            xh,$03
            ldi            xl,$e4
            rjmp        z_loop2
    
    wait10ms:push        xh
            push        xl
            ldi            xh,$27
            ldi            xl,$0b
            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
            brne        z_loop2
            pop            xl
            pop            xh
            ret
    
    waitxms:rcall        wait1ms
            dec            temp0
            brne        waitxms
            ret
    
    waitx10ms:
            rcall        wait10ms
            dec            temp0
            brne        waitx10ms
            ret
    Geändert von avr_racer (12.02.2015 um 17:39 Uhr) Grund: streiche load_hex_dez zu hex_dez

Ähnliche Themen

  1. MSP430 und DS18s20
    Von Lutze53 im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 0
    Letzter Beitrag: 17.10.2011, 10:01
  2. Prüfsumme beim DS18S20
    Von hardware.bas im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 16.09.2010, 14:45
  3. DS18S20
    Von Naturp im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 4
    Letzter Beitrag: 29.04.2010, 12:14
  4. DS18S20 ID Fehler
    Von apohero im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 15.05.2008, 11:26
  5. Genauigkeit des DS18S20
    Von franzl im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 07.05.2006, 20:55

Berechtigungen

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

12V Akku bauen