Ich hab einige Zeilen gefunden


Code:
'
' SLAVE-Adresse 100
' nur Daten empfangen möglich/erforderlich --> MASTER-WRITE
' 5 Servos
' Im Feld Daten wird die Nr. des Servo's  und dessen Laufrichtung verschlüsselt übergeben
'
'******************************************

Servo1 Alias Portb.1
Servo2 Alias Portb.2
Servo3 Alias Portb.3
Servo4 Alias Portb.4
Servo5 Alias Portb.5

Dim Daten As Byte
Dim I As Byte

$baud = 9600

On Int0 Ext_int0
On Ovf0 Tim0_ovf
Goto Reset
$asm

;***************************************************************************
;* Refers to the application note AVR302 documentation for more
;* detailed description.
;*
;* USAGE
;* Insert user code in the two locations marked "insert user code here".
;*
;* NOTES
;* Minimum one instruction will be executed between each interrupt.
;*
;* STATISTICS
;* Code Size         : 160
;* Register Usage    : 5 High, 0 Low
;* Interrupt Usage   : EXT_INT0 and TIM0_OVF
;* Port Usage        : PD4(T0) and PD2(INT0)
;* XTAL              :  - I2C Fast Mode     : min 16.0MHz
;*                      - I2C Standard Mode : min  3.0MHz
;*
;***************************************************************************

;**** Includes ****

.include "2313def.inc"


;**** Global I2C Constants ****


;.def Devadr = 0x50 ; Slave Device Address        geändert
;.def Devadrm = 0x7f ; Slave Multi Address Mask   geändert

;.def Pinmaskx = 0x14 ; <=>(1 << Pd4) +(1 << Pd2)  geändert

;**** Global Register Variables ****

.def Temp = R16 ; Temporary Variable
.def Etemp = R17 ; Extra Temporary Variable
.def I2cdata = R18 ; I2C Data Register
.def I2cadr = R19 ; I2C Address And Direction Register
.def I2cstat = R20 ; I2C Temporary Sreg Storage

;**** Interrupt Vectors ****
;     Anpassung wegen Umstellung von 1200 auf 2313 !!!

;         rjmp RESET          ;Reset handle
;         rjmp EXT_INT0        ;INT0 handle
;         rjmp Xxx             ;int_1                          eingefügt
;         rjmp Xxx             ;time1_capt                     eingefügt
;         rjmp xxx             ;time1_compa                    eingefügt
;         rjmp xxx             ;time1_compb                    eingefügt
;         Rjmp Xxx             ;Time1_ovfl                     eingefügt
;         rjmp TIM0_OVF        ;Timer 0 overflow handle
;
; ( rjmp ANA_COMP ) ; ( Analog comparator handle )
;
;Xxx:

;***************************************************************************
;*
;* INTERRUPT
;* EXT_INT0 / i2c_wakeup
;*
;* DESCRIPTION
;* Detects the start condition and handles the data transfer on
;* the I2C bus.
;*
;* Received data is stored in the r0 register and r0 is transmitted
;* during a master read transfer.
;*
;* NOTE
;* This interrupt code, in some cases, jumps to code parts in the
;* TIM0_OVF / i2c_skip section to reduce code size.
;*
;***************************************************************************

Ext_int0:
           in i2cstat,SREG    ; store SREG


;*************************
;* Get I2C Slave Address *
;*************************

I2c_get_adr:
          ldi i2cadr,1        ; initialize address register
Wlo_ga0:
          Sbic Pind , Pind4   ; Wait For Scl Low
          rjmp wlo_ga0
          rjmp first_ga
Do_ga:
                              ; Do

Wlo_ga:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_ga

         mov  temp,i2cadr     ; test address

     ;orginal andi    temp,Devadrm      ; mask register full floating bit
         andi R16,0x7f                                               ;geändert

     ;orginal cpi     temp,devadr         ; if device addressed

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

         cpi  R16,0x32        ;dig.Adresse (RR&Co)  = 100             geändert
                              ;0x32 = binär 0110010 + 0 (R/W-Bit)
                              ;100  = binär 01100100

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

         in   temp,SREG       ; set T flag ("T = Z")
         bst  temp,1


First_ga:
         sec                  ; set carry
Whi_ga:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_ga
         sbis PIND,PIND2      ; if SDA low
         clc                  ; clear carry
         rol i2cadr           ; shift carry into address register

         brcc do_ga           ; while register not full

Wlo_ca:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_ca

;**** Check Address ****
                              ; if T flag set (device addressed)
         brts i2c_adr_ack     ; acknowledge address
                              ; else
         rjmp i2c_adr_miss    ; goto address miss handle

;**** Acknowledge Address ****

I2c_adr_ack:
         sbi DDRD,DDD2        ; assert acknowledge on SDA
Whi_aa:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_aa

;**** Check Transfer Direction ****

         lsr i2cadr           ; if master write
         brcc i2c_master_write; goto master write handle


;*******************************
;* Transmit Data (master read) *
;*******************************

I2c_master_read:

;**** Load Data (handle outgoing data) ****

;!INSERT USER CODE HERE !
;!NOTE! If the user code is more than ONE instruction then wait
; states MUST be inserted as shown in description.

         mov i2cdata,r0       ; insert data in "serial"
                              ; register (user code example)
         sec                  ; shift MSB out and "floating empty flag" in
         rol i2cdata

Wlo_mr:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_mr


;**** Transmitt data ****

         brcc fb_low_mr       ; if current data bit high
         cbi DDRD,DDD2        ; release SDA
         rjmp fb_mr           ; goto read loop
Fb_low_mr:
                              ; Else
         sbi DDRD,DDD2        ; force SDA
Fb_mr:
         Lsl I2cdata          ; If Data Register Not Empty

Loop_mr:
Whi_mr:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_mr
Wlo_mr2:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_mr2

         brcc b_low_mr        ; if current data bit high

         cbi DDRD,DDD2        ; release SDA
         lsl i2cdata          ; if data register not empty
         brne loop_mr         ; loop
         rjmp done_mr         ; done
B_low_mr:
                              ; Else
         sbi DDRD,DDD2        ; force SDA
         lsl i2cdata          ; if data register not empty
         brne loop_mr         ; loop

Done_mr:
Whi_mr2:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_mr2
Wlo_mr3:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_mr3

         cbi DDRD,DDD2        ; release SDA

;**** Read Acknowledge from Master ****

Whi_ra:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_ra

         sec                  ; read acknowledge
         sbis PIND,PIND2
         clc
         brcc i2c_master_read ; if ack transfer (next) data

Wlo_ra:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_ra

         rjmp i2c_wait_cond   ; goto wait condition (rep. start or stop)


;*******************************
;* Receive Data (master write) *
;*******************************

I2c_master_write:

Wlo_mw0:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_mw0
         cbi DDRD,DDD2        ; remove acknowledge from SDA

Whi_mw:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_mw

         in temp,PIND         ; sample SDA (first bit) and SCL

      ;orginal: andi temp,pinmask
         andi R16,0x14        ; mask out SDA and SCL              geändert
Do_mw:
                              ; Do
         in etemp,PIND        ; new sample

      ;orginal: andi etemp,pinmask
         andi R17,0x14        ; mask out SDA and SCL              geändert
         cp etemp,temp
         breq do_mw           ; while no change

         sbrs etemp,PIND4     ; if SCL changed to low
         rjmp receive_data    ; goto receive data

         sbrs etemp,PIND2     ; if SDA changed to low
         rjmp i2c_get_adr     ; goto repeated start
                              ; else
         rjmp i2c_stop        ; goto transfer stop

Receive_data:
         ldi i2cdata,2        ; set i2cdata MSB to zero
         sbrc temp,PIND2      ; if SDA sample is one
         ldi i2cdata,3        ; set i2cdata MSB to one

Do_rd:
                              ; Do
Wlo_rd:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_rd
         sec                  ; set carry
Whi_rd:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_rd

         sbis PIND,PIND2      ; if SDA low
         clc                  ; clear carry
         rol i2cdata          ; shift carry into data register

         brcc do_rd           ; while register not full

;**** Acknowledge Data ****

I2c_dat_ack:
Wlo_da:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_da
         sbi DDRD,DDD2        ; assert acknowledge on SDA
Whi_da:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_da
                              ; (acknowledge is removed later)

;**** Store Data (handle incoming data) ****
; insert wait states here if nessesary

         Sbi Ddrd , Ddd4      ;(start Wait State)             aktiviert

;!INSERT USER CODE HERE !
;!NOTE! If the user code is more than TWO instruction then wait
; states MUST be inserted as shown in description.

         mov r0,i2cdata       ; Store data receved in "serial"
                              ; register (user code example)


         Gosub Bearbeitung


         cbi DDRD,DDD4        ; (end wait state)              aktiviert
         cbi DDRD,DDD2        ; remove acknowledge from SDA

         ;Rjmp I2c_master_write ; Start On Next Transfer      geändert / nur Datenempfang
         rjmp I2c_stop

;***************************************************************************
;*
;* INTERRUPT
;* TIM0_OVF / i2c_skip
;*
;* DESCRIPTION
;* This interrupt handles a "address miss". If the slave device is
;* not addressed by a master, it will not acknowledge the address.
;*
;* Instead of waiting for a new start condition in a "busy loop"
;* the slave set up the counter to count 8 falling edges on SCL and
;* returns from the current interrupt. This "skipping" of data
;* do not occupies any processor time. When 8 egdes are counted, a
;* timer overflow interrupt handling routine (this one) will check
;* the next condition that accure. If it       's a stop condition
;* the transfer ends, if it   's a repeated start condition a jump
;* to the i2c_wakeup interrupt will read the new address. If a new
;* transfer is initiated the "skipping" process is repeated.
;*
;***************************************************************************

Tim0_ovf:
                              ; (timer 0 Overflow Handle )
         in i2cstat,SREG      ; store SREG

I2c_adr_miss:

;**** Drop Acknowledge ****

Whi_dac:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_dac
Wlo_dac:
         Sbic Pind , Pind4    ; Wait For Scl Low
         rjmp wlo_dac

                              ; disable timer 0 overflow interrupt


     ;orginal: ldi temp,(0<<TOIE0)

         clr temp             ;                                eingefügt
         sbr temp,&b00000000  ;                                geändert
         Out Timsk , Temp
                              ; enable external interrupt request 0

     ;orginal: ldi temp,(1<<INT0)

         clr temp             ;                                eingefügt
         sbr temp,&b01000000  ;                                geändert
         Out Gimsk , Temp


;************************
;* Wait for a Condition *
;************************

I2c_wait_cond:
Whi_wc:
         Sbis Pind , Pind4    ; Wait For Scl High
         rjmp whi_wc

         in temp,PIND         ; sample SDA (first bit) and SCL

     ;orginal:andi temp,pinmask ; mask out SDA and SCL
         andi R16,0x14        ;                                geändert
Do_wc:
                              ; Do
         in etemp,PIND        ; new sample

     ;orginal: andi etemp,pinmask  ; mask out SDA and SCL
         andi R17,0x14        ;                                geändert
         cp etemp,temp
         breq do_wc           ; while no change

         sbrs etemp,PIND4     ; if SCL changed to low
         rjmp i2c_skip_byte   ; goto skip byte

         sbrs etemp,PIND2     ; if SDA changed to low
         rjmp i2c_get_adr     ; goto repeated start
                              ; else
                              ; goto transfer stop


;*************************
;* Handle Stop Condition *
;*************************

I2c_stop:
               ;! Set INT0 to generate an interrupt on low level,
               ;! then set INT0 to generate an interrupt on falling edge.
               ;! This will clear the EXT_INT0 request flag.

  ;orginal: ldi temp,(0<<ISC01)+(0<<ISC00)

         clr temp             ;                             eingefügt
         sbr temp,&b00000000  ;                             geändert
         Out Mcucr , Temp

  ;orginal: ldi temp,(1<<ISC01)+(0<<ISC00)

         clr temp             ;                             eingefügt
         sbr temp,&b00000010  ;                             geändert
         Out Mcucr , Temp

         Out Sreg , I2cstat ; Restore Sreg
         reti                  ; return from interrupt


;****************
;* Skip byte(s) *
;****************

I2c_skip_byte:
                              ; set counter initial value
         ldi temp,-7
         Out Tcnt0 , Temp
                              ; enable timer 0 overflow interrupt
   ;orginal: ldi temp,(1<<TOIE0)

         clr temp             ;                             eingefügt
         sbr temp,&b00000010  ;                             geändert
         Out Timsk , Temp
                              ; disable external interrupt request 0
   ;orginal: ldi temp,(0<<INT0)

         clr temp             ;                             eingefügt
         sbr temp,&b00000000  ;                             geändert
         Out Gimsk , Temp

         Out Sreg , I2cstat ; Restore Sreg
         reti


;***************************************************************************
;*
;* FUNCTION
;* i2c_init
;*
;* DESCRIPTION
;* Initialization of interrupts and port used by the I2C interface
;* and waits for the first start condition.
;*
;* USAGE
;* Jump to this code directly after a reset.
;*
;* RETURN
;* none
;*
;* NOTE
;* Code size can be reduced by 12 instructions (words) if no transfer
;* is started on the I2C bus (bus free), before the interrupt
;* initialization is finished. If this can be ensured, remove the
;* "Wait for I2C Start Condition" part and replace it with a "sei"
;* instruction.
;*
;***************************************************************************

Reset:
I2c_init:

;**** PORT Initialization ****

            ; Initialize PD2 (INT0) for open colector operation (SDA in/out)

    ;orginal: ldi temp,(0<<DDD4)+(0<<DDD2)

         clr temp             ;                             eingefügt
         sbr temp,&b00000000  ;                             geändert
         Out Ddrd , Temp

            ; Initialize PD4 (T0) for open colector operation (SCL in/out)

    ;orginal: ldi temp,(0<<PD4)+(0<<PD2)

         clr temp             ;                             eingefügt
         sbr temp,&b00000000  ;                             geändert
         Out Portd , Temp

;**** Interrupt Initialization ****

            ; Set INT0 to generate an interrupt on falling edge

    ;orginal: ldi temp,(1<<ISC01)+(0<<ISC00)

         clr temp             ;                             eingefügt
         sbr temp,&b00000010  ;                             geändert
         Out Mcucr , Temp

            ; Enable INT0    -> Freigeben INT0 !!!


         clr temp
         sbr temp,&b01000000  ;setzt bit 6 des Reg. Gimsk ( = INT0) auf 1 / on
         Out Gimsk , Temp


            ; Set clock to count on falling edge of T0

    ;orginal: ldi temp,(1<<CS02)+(1<<CS01)+(0<< CS00)

         clr temp             ;                             eingefügt
         sbr temp,&b00000110  ;                             geändert
         Out Tccr0 , Temp


;***************************************************
;* Wait for I2C Start Condition (13 intstructions) *
;***************************************************

Do_start_w:
                              ; Do

         in temp,PIND         ;  sample SDA & SCL
         com temp             ; invert
     ;orginal: andi temp,pinmask  ; mask SDA and SCL
         andi R16,0x14        ;                             geändert
         brne do_start_w      ; while (!(SDA && SCL))

         in temp,PIND         ; sample SDA & SCL
     ;orginal: andi temp,pinmask  ; mask out SDA and SCL
         andi R16,0x14        ;                             geändert
Do_start_w2:
                              ; Do
         in etemp,PIND        ; new sample
     ;orginal: andi etemp,pinmask ; mask out SDA and SCL
         andi R17,0x14        ;                             geändert
         cp etemp,temp
         breq do_start_w2     ; while no change

         sbrc etemp,PIND2     ; if SDA no changed to low
         rjmp do_start_w      ; repeat

         rcall i2c_get_adr    ; call(!) interrupt handle (New transfer)


;***************************************************************************
;*
;* PROGRAM
;* main - Test of I2C slave implementation
;*
;***************************************************************************

Main:
         Rjmp Main            ; Loop Forever


;**** End of File ****

$end Asm



Bearbeitung:

   Daten = Peek(0)
   Config Portb = Output
   Portb = &B11111111         'alle LED aus


   If Daten = 1 Or Daten = 11 Then Gosub Servo_1
   If Daten = 2 Or Daten = 12 Then Gosub Servo_2
   If Daten = 3 Or Daten = 13 Then Gosub Servo_3
   If Daten = 4 Or Daten = 14 Then Gosub Servo_4
   If Daten = 5 Or Daten = 15 Then Gosub Servo_5


Return

Servo_1:

   If Daten = 11 Then Goto Servo_1_links

'-----------------------------------------------
Servo_1_rechts:

   For I = 1 To 18            'nach rechts
      Portb.1 = 0
      Waitms 20
      Portb.1 = 1
      Waitms 1
   Next I
   Portb.1 = 0
Return

Servo_1_links:

   For I = 1 To 18            'nach links
      Portb.1 = 1
      Waitms 20
      Portb.1 = 0
      Waitms 20
   Next I

Return
'-----------------------------------------------
Servo_2:

   If Daten = 12 Then Goto Servo_2_links

   For I = 1 To 18            'nach rechts
      Portb.2 = 0
      Waitms 20
      Portb.2 = 1
      Waitms 1
   Next I
   Portb.2 = 0
Return

Servo_2_links:

   For I = 1 To 18            'nach links
      Portb.2 = 1
      Waitms 20
      Portb.2 = 0
      Waitms 20
   Next I

Return
'-----------------------------------------------
Servo_3:
   If Daten = 13 Then Goto Servo_3_links

   For I = 1 To 18            'nach rechts
      Portb.3 = 0
      Waitms 20
      Portb.3 = 1
      Waitms 1
   Next I
   Portb.3 = 0
Return

Servo_3_links:

   For I = 1 To 18            'nach links
      Portb.3 = 1
      Waitms 20
      Portb.3 = 0
      Waitms 20
   Next I
Return
'-----------------------------------------------
Servo_4:
   If Daten = 14 Then Goto Servo_4_links

   For I = 1 To 18            'nach rechts
      Portb.4 = 0
      Waitms 20
      Portb.4 = 1
      Waitms 1
   Next I
   Portb.4 = 0
Return

Servo_4_links:

   For I = 1 To 18            'nach links
      Portb.4 = 1
      Waitms 20
      Portb.4 = 0
      Waitms 20
   Next I
Return
'-----------------------------------------------
Servo_5:
   If Daten = 15 Then Goto Servo_5_links

   For I = 1 To 18            'nach rechts
      Portb.5 = 0
      Waitms 20
      Portb.5 = 1
      Waitms 1
   Next I
   Portb.5 = 0
Return

Servo_5_links:

   For I = 1 To 18            'nach links
      Portb.5 = 1
      Waitms 20
      Portb.5 = 0
      Waitms 20
   Next I
Return
'-----------------------------------------------