; Musterprogramm .nolist ;include-file nicht in Listing .include "m32def.inc" ;Definitionen für ATmega128 einbinden .list ;Listing erstellen .equ NurMuster = 10 .equ LEDPort = PortB ;.equ für Variablenzuweisungen .equ LEDPortDirection = DDRB ;.def für Registerzuweisungen .equ LED_On_Off_Bit = 7 .equ LED_R_L_Bit = 6 .equ LED_Cont_Step_Bit = 5 .equ LED_ADC_Tast_Bit = 4 .equ LED_V1_Bit = 3 .equ LED_V2_Bit = 2 .equ LED_Unused1_Bit = 1 .equ LED_DoStep_Bit = 0 .equ MotorPort = PortC .equ MotorPortDirection = DDRC .equ MotorEn = 1 ;1 für Enable .equ MotorRL = 2 ;0 für rechts .equ MotorPuls = 3 ;Step bei fallender Flanke .equ MotorHV = 4 ;0 für volle Schritte .equ MotorReset = 5 ;Lowaktiv .equ Tasten = PinA .equ NoKey = 0xff ;11111111 keine Taste gedrückt .equ Sta_Sto_Key = 0x7f ;01111111 erste Taste .equ R_L_Key = 0xbf ;10111111 zweite Taste .equ Step_Cont_Key=0xdf ;11011111 dritte Taste .equ Adc_Tast_Key= 0xef ;11101111 vierte Taste .equ V1_Key = 0xf7 ;11110111 fünfte Taste .equ V2_Key = 0xfb ;11111011 sechste Taste .equ DoStep_Key = 0xfe ;11111110 achte Taste ;siebte Taste (11111101 wird nicht benutzt) .equ key_pin = PIND .equ key_port = PORTD .equ key_ddr = DDRD .def akku = r16 ;r16 als Arbeitsregister "akku" .equ MyCount_A = 255 .equ MyCount_i = 255 .def MyBits1 = r17 .equ KeyPressed = 0 .equ Motor_On_Off_Bit= 1 ;1: Motor an .equ Motor_R_L_Bit = 2 ;0: Rechts .equ Cont_Step_Bit = 3 ;1: Dauer, keine Winkelverstellungen .equ ADC_Tast_Bit = 4 ;1: Drehzahl vom ADCoder Tasten V1,V2 .equ V1_Bit = 5 ;V1 und V2: Verstellwinkel .equ V2_Bit = 6 .equ StepBit = 7 ;Motor-Clock .def Key = r18 ;Gültiger Tastencode .def OldKey = r19 ;Hilfsspeicher für Tastatur-ISR .def StepSollAnz = r20 ;Anzahl Steps für gewählten Winkel .def DrehzByTast = r21 ;Drehzahlvorgabe mit den Tasten .def DrehzByADC = r22 ;Drehzahlvorgabe mit dem ADC .equ DrehzMin = 200 ;höchster Wert im Timer bedeutet .equ Drehz2 = 150 ;langsamste Drehzahl .equ Drehz3 = 100 .equ DrehzMax = 2 .equ WinkelMin = 50 .equ Winkel2 = 100 .equ Winkel3 = 150 .equ WinkelMax = 200 .def StepCounter = r23 .equ CyBitNr = 0 .equ ZBitNr = 1 ;******************************************************************************************************************** ; Macros .macro PinTog sbis @0,@1 ;Pin toggeln rjmp SetPin ;I/O-Adresse und Pin-Nr. werden ClrPin: cbi @0,@1 ;an das Macro übergeben rjmp PinTogX SetPin: sbi @0,@1 PinTogX: .endmacro .macro BitTog sbrs @0,@1 ;Bit toggeln geht nur mit Hilfe des rjmp SetBit ;T-Bits im SREG. Dazu die Befehle ClrBit: clt ;clt (Clear T) und set (Set T) rjmp BitTogX ;dazu werden das Register und das zu SetBit: set ;toggelnde Bit an das Macro übergeben BitTogX: bld @0,@1 ; T ins Register schreiben .endmacro .macro BitOut ;Ausgeben eines Bits auf einen I/O-Port bst @0,@1 ;(i.A. der LED-Port, daher wird hier invertiert) brtc BitOut1 ;das Bit wird zunächst in T gespeichert, dann wird BitOut0: cbi @2,@3 ;T abgefragt und bei T=0 das Bit gesetzt u. umgekehrt rjmp BitOutX ;Beispiel: BitOut1: sbi @2,@3 ;BitOut MyBits1,Motor_R_L_Bit,MotorPort,MotorRL BitOutX: .endmacro .macro BitSet ;Bit setzen. Umweg über T, da einzelne Bits in set ;Registern nicht gesetzt werden können. bld @0,@1 ;mit bld (Bit Load from T) wird das Bit (@1) im .endmacro ;Register (@0) gesetzt. .macro BitClr ;Bit löschen. clt bld @0,@1 .endmacro .macro push_sreg ;SREG auf Stack sichern in akku,sreg push akku .endmacro .macro pop_sreg ;SREG vom Stack zurückholen pop akku out sreg,akku .endmacro ;******************************************************************************************************************** .cseg ;Beginn des Code-Segmentes .org 0x0000 ;Interrupt-Vektor für RESET rjmp Progstart .org 0x0018 ;Interrupt-Vektor T/C-1-Interrupt rjmp TastTimerISR .org 0x002a ;Interrupt-Vektor ADC ;rjmp ADCISR .org 0x0034 ;Interrupt-Vektor T/C-3-Interrupt ;rjmp MotorTimerISR .org 0x0045 ;Ende der Interrupt-Vektor-Tabelle ;******************************************************************************************************************** ;Beginn des Hauptprogrammes progstart: ldi akku,LOW(RAMEND) ;Stack initialisieren out SPL,akku ;Wichtig: Immer Low-Byte zuerst ldi akku,HIGH(RAMEND) out SPH,akku ;call MotorInit call SysInit ;call ADCInit call TastInit loop: ldi akku,NurMuster loop1: dec akku brbc ZBitNr,loop1 ; Zu Loop1, wenn Z-Bit nicht gesetzt, also wenn akku noch nicht Null ist. ; PinTog MotorPort,motorpuls PinTog LEDPort,LED_ADC_Tast_Bit call Delay jmp loop ;******************************************************************************************************************** Delay: ldi r20,MyCount_i ldi r21,MyCount_A loopa: loopi: NOP NOP DEC r20 brne loopi dec r21 brne loopa ret ;******************************************************************************************************************** MotorInit: push akku ldi akku,0xfe out MotorPortDirection,akku sbi MotorPort,MotorEn cbi MotorPort,MotorReset nop nop nop sbi MotorPort,MotorReset pop akku ret ;******************************************************************************************************************** ; ;SysInit: ; Aufgaben: - LED-Port als Ausgang ; - Alle LEDs aus ; Eingangsgrößen: keine ; Ausgangsgrößen: keine SysInit:push akku ;Akku nicht zerstören ser akku ;Alle Bits in akku setzen out LEDPortDirection,akku ;LED-Port als Ausgang out LEDPort,akku ;LED "an" würde durch Ausgabe einer Null erreicht. pop akku ret ;******************************************************************************************************************** ADCInit: ; PORTB OUT Leds push akku ldi akku, 0xFF ;PORT B auf Ausgang out DDRB, akku ldi akku, 0b11111110 ;Port A Pin 0 auf Eingang, 1-7 Ausgang out DDRA, akku ldi akku, 0xFF ;LEDS ausschalten Port B out PORTB, akku cbi ADMUX, REFS1 ; AVCC as Voltage Reference sbi ADMUX, REFS0 sbi ADMUX, ADLAR cbi ADMUX, MUX4 ; Single Ended Input ADC0 cbi ADMUX, MUX3 cbi ADMUX, MUX2 cbi ADMUX, MUX1 cbi ADMUX, MUX0 sbi ADCSRA, ADEN ; ADC enable cbi ADCSRA, 5 cbi ADCSRA, 4 ;no Free Run cbi ADCSRA, 3 ;messen: ; ldi akku, (1< Ende mov Key,akku PinTog LEDPort,0 ; setze bit key pressed Ende: ret ;******************** TastRead2: in key, key_pin ; den jetzigen Zustand der Taster holen mov akku, key ; und in akku sichern cpi akku, NoKey brne gedrueckt cpi OldKey, NoKey breq End PinTog LEDPort,0 mov Key,OldKey mov OldKey, akku gedrueckt: mov OldKey, akku End: ret ;******************** TastInit: ldi akku, (1< neuer Schleifendurchlauf and akku, key ; War das ein 1->0 Übergang, wurde der Taster also ; gedrückt (in key steht das Ergebnis vom XOR) brne loop6 ; PinTog LEDPort,0 ; den Zustand der LED umdrehen rjmp loop6