Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .include "m16def.inc"
- .def led=r16
- .def intr_flag=r22
- .def potIndicator=r23
- .def potL=r18
- .def potH=r19
- .def temp=r20
- .def sreg_handler=r21
- .def input=r8
- .def seconds=r9
- .def compL=r24
- .def compH=r25
- .def TEMP1=R26
- .def TEMP2=r27
- .def TEMP3=r28
- .cseg
- .org $00
- jmp RESET
- .org $00C
- jmp TIM_COMPA
- .org $010
- jmp TIM_OVF1
- .org $01C
- jmp ADC_CONV_INTR
- .org $029
- TIM_COMPA:
- in sreg_handler, SREG
- ;7 seconds are finally completed
- ;stop timer
- ori intr_flag, $02 ;set bit 1 to 1
- out SREG, sreg_handler
- reti
- TIM_OVF1:
- in sreg_handler, SREG
- ;set TCCR1B register to 00001100
- ;make it equal to zero after compare OCR1A match-> NOW DO SO
- ldi temp, $0C ;normally $0C
- out TCCR1B, temp
- ;fix TIFR manually, FLAGS ARE RESET BY BEING SET TO ONE!
- ldi temp, $10 ;00010000
- out TIFR, temp
- ;now enable OCR1A interrupt timer
- ldi temp, $10 ;00010000
- out TIMSK, temp
- out SREG, sreg_handler
- reti
- ADC_CONV_INTR:
- in sreg_handler, SREG
- in potH, ADCH
- com potH
- out PORTB, potH
- com potH
- call DELAY_FOR_BUTTONS
- in potL, ADCL
- com potL
- out PORTB, potL
- com potL
- call DELAY_FOR_BUTTONS
- in temp, ADMUX
- com temp
- out PORTB, temp
- call DELAY_FOR_BUTTONS
- ori intr_flag, $01
- out SREG, sreg_handler
- reti
- RESET:
- ;initialize stack pointer
- ldi R16, low(RAMEND)
- out SPL, R16
- ldi R16, high(RAMEND)
- out SPH, R16
- ;set PORTB output
- ori r20, $FF
- out DDRB, r20
- out PORTB, r20
- ;set PORTD input
- andi r20, $00
- out DDRD, r20
- com r20
- out PORTD, r20
- ;set PORTA input
- andi r20, $00
- out DDRA, r20
- com r20
- out PORTA, r20
- ;clear timer
- clr temp
- out TCNT1H, temp
- out TCNT1L, temp
- ;enable interrupts
- sei
- ldi temp, 0x88
- out ADCSRA,temp ;10101111=88
- ldi temp, $c1 ;11000001 for iner ref voltage 2.56 and pot2
- out ADMUX, temp
- clr seconds
- inc seconds
- inc seconds
- inc seconds
- inc seconds
- clr intr_flag
- remain2:
- sbi ADCSRA, 6
- remain1:
- sbrs intr_flag,0
- rjmp remain1
- clr intr_flag
- in led, ADCSRA
- com led
- mini:
- in input, PIND
- sbrc input, 0 ;START switch
- rjmp mini
- dec seconds
- brne remain2
- ;wait for START switch
- START:
- in input, PIND
- sbrc input, 0 ;START switch
- rjmp START
- clr intr_flag
- ;rjmp Y1_Stage_preparation
- ser led
- ;Operation On LED-OPEN LED7
- clr temp
- bst temp,0
- bld led,7
- out PORTB, led
- B1_Prep:
- ;intializations
- clr potIndicator
- ;enable adc
- ;clear flag
- clr intr_flag
- ;******************
- rjmp A1_Prep
- ;enable adc for B1-pot2
- ldi temp, $c1 ;11000001 for iner ref voltage 2.56 and pot2
- out ADMUX, temp
- sbi ADCSRA,6 ;start conversion
- B1_Stage:
- ;checking STOP_HANDLER
- in input, PIND
- sbrs input,7 ;if stop not pressed=1 skip else go back
- rjmp STOP_HANDLER
- sbrs intr_flag,0
- rjmp B1_Stage
- call StageB1B3Handler
- tst potIndicator ;code 1 means it is not low yet
- brne B1_Stage
- ;TEMPORAL CHANGE
- clr temp
- bst temp,0
- bld led,6
- out PORTB, led
- mini_wait:
- in input, PIND
- sbrc input, 0 ;START switch
- rjmp mini_wait
- B3_prep:
- ;clear flag
- clr intr_flag
- clr potIndicator
- ;enable adc for B3-pot4
- ldi temp, $c3 ;11000100 for iner ref voltage 2.56 and pot2
- out ADMUX, temp
- sbi ADCSRA,6 ;start conversion
- B3_Stage:
- ;checking STOP_HANDLER
- in input, PIND
- sbrs input,7 ;if stop not pressed=1 skip else go back
- rjmp STOP_HANDLER
- sbrs intr_flag,0
- rjmp B3_Stage
- call StageB1B3Handler
- tst potIndicator ;code 1 means there is error
- brne B3_Stage
- ;TEMPORAL CHANGE
- ser temp
- bst temp,0
- bld led,6
- out PORTB, led
- A1_Prep:
- ;clear flag
- clr intr_flag
- clr potIndicator
- ;enable adc for B3-pot4
- ldi temp, $c0 ;11000001 for iner ref voltage 2.56 and pot2
- out ADMUX, temp
- sbi ADCSRA,6 ;start conversion
- A1_Stage:
- ;checking STOP_HANDLER
- in input, PIND
- sbrs input,7 ;if stop not pressed=1 skip else go back
- rjmp STOP_HANDLER
- sbrs intr_flag,0
- rjmp A1_Stage
- call StageA1Handler
- tst potIndicator ;code 1 means there is error
- brne A1_Stage
- ;A1-OPEN LED1
- clr temp
- bst temp,0
- bld led,1
- out PORTB, led
- clr intr_flag
- clr potIndicator
- Y1_Press_Stage:
- ;Check sw1-Y1
- in input, PIND
- sbrc input, 1
- rjmp Y1_Press_Stage
- ;Y1-OPEN LED5
- clr temp
- bst temp,0
- bld led,5
- out PORTB, led
- ;open M2
- call M2On
- Acceleration_stage_preparation:
- ;LED 7,5,4,1
- ldi led, $4D
- out PORTB, led
- call DELAY_FOR_BUTTONS
- clr potIndicator
- clr intr_flag
- ;prepare OCR1A for later
- ldi temp, $AB ;(decimal) 43,839
- out OCR1AH, temp
- ldi temp, $3F
- out OCR1AL, temp
- ;first enable only overflow interrupt
- ldi temp, $04 ;00000100
- out TIMSK, temp
- ;begin timer,
- ;(make it equal to zero after compare OCR1A match)->
- ;NOT HERE, IT MAKES IT ZERO
- ;IT NEVER MAKES IT TO THE OVF INTERRUPT
- ldi temp, $04 ;00000100 normally $04
- out TCCR1B, temp
- Acceleration_stage: ;acceleration stage
- sbrc intr_flag, 1
- rjmp Y1_Stage_preparation
- in input, PIND
- sbrs input, 7 ;STOP switch
- rjmp STOP_HANDLER1
- sbrs input, 5 ;Q2 switch
- rjmp Error_Handler1
- rjmp Acceleration_stage
- Y1_Stage_preparation:
- ;LED 7,6,5,4,2,1 00001001
- ldi led, $09
- out PORTB, led
- call DELAY_FOR_BUTTONS
- call Reset_Timer_configuration
- clr potIndicator
- ;important to be done AFTER STOPPING ANY CONVERSION THAT IS CURRENTLY TAKING PLACE
- clr intr_flag
- ;start first conversion
- ldi temp, $C0 ;choose A1
- out ADMUX, temp
- sbi ADCSRA, 6
- Y1_Stage:
- sbrc intr_flag, 0
- call ADC_HANDLER_Y1
- ;it is important to check potIndicator
- ;for code 2 right after return.
- ;This way, we are certain that right after
- ;the B2 is high, the Y2 is immediately activated
- ;and the conversion for pot A1 is done at the same time.
- ;The B2 becoming full must be immediately noticed
- sbrc potIndicator, 1 ;code 2 means move to the next stage
- rjmp Y2_Stage_preparation
- sbrc potIndicator, 0 ;code 1 means there is error
- rjmp Error_Handler
- in input, PIND
- sbrs input, 7 ;STOP switch
- rjmp STOP_HANDLER
- sbrs input, 5 ;Q2 switch
- rjmp Error_Handler
- sbrs input, 4 ;Q1 switch
- rjmp Error_Handler
- ;**************************
- ;CAN I ACTUALLY SWITCH?
- ;sbrs input, 2 ; Y2 switch
- ;rjmp Y2_sudden_switch
- rjmp Y1_Stage
- Y2_sudden_switch:
- ;configuration for AD-CONVERTER
- ;important to be done AFTER STOPPING ANY CONVERSION THAT IS CURRENTLY TAKING PLACE
- clr intr_flag ;only the timer may set a different intr_flag, so the only possible bit open is the 0
- ;therefore i can clear it safely
- ;start first conversion
- ldi temp, $C0 ;choose A1
- out ADMUX, temp
- sbi ADCSRA, 6
- Y2_Stage_preparation:
- ;LED 7,6,4,3,2,1 00100001
- ldi led, $21
- out PORTB, led
- clr potIndicator
- ;*********do not keep, only now
- ;start first conversion
- ldi temp, $C0 ;choose A1
- out ADMUX, temp
- sbi ADCSRA, 6
- ;sbrs input, 2 ; Y2 switch
- ;rjmp Y2_Stage_preparation
- Y2_Stage:
- sbrc intr_flag, 0
- call ADC_HANDLER_Y2
- ;it is important to check potIndicator
- ;for code 2 right after return.
- ;This way, we are certain that right after
- ;the B2 is high, the Y2 is immediately activated
- ;and the conversion for pot A1 is done at the same time.
- ;The B2 becoming full must be immediately noticed
- sbrc potIndicator, 1 ;code 2 means move to the next stage
- rjmp STOP_HANDLER
- sbrc potIndicator, 0 ;code 1 means there is error
- rjmp Error_Handler
- in input, PIND
- sbrs input, 7 ;STOP switch
- rjmp STOP_HANDLER
- sbrs input, 5 ;Q2 switch
- rjmp Error_Handler
- sbrs input, 4 ;Q1 switch
- rjmp Error_Handler
- rjmp Y2_Stage
- Error_Handler1:
- call Reset_Timer_configuration
- Error_Handler:
- ldi led, $FE ;11111110 led 0 on
- out PORTB, led
- ;set PORTC output
- ;ori temp, $FF
- ;out DDRB, temp
- ;out PORTC, led
- ErrorAck:
- in input, PIND
- sbrc input,6
- rjmp ErrorAck
- StartErrorTimer:
- ;prepare OCR1A=4*10^6/64=62500=$3D09
- ldi temp, $F4
- out OCR1AH,temp
- ldi temp, $24
- out OCR1AL,temp
- ;now enable OCR1A interrupt timer
- ldi temp, $10 ;00010000
- out TIMSK, temp
- ;start the counter and set prescaler
- ldi temp, $0B ;for now, for speed, normally it is $0B ;00001011
- out TCCR1B, temp
- clr seconds
- ;wait for ack
- loopBlink:
- sbrc intr_flag, 1
- call BLINK
- ;check STOP_HANDLER
- in input, PIND
- sbrc input,7 ;if not pressed=1 skip wait for stop switch
- rjmp loopBlink
- call Reset_Timer_configuration
- ser temp
- out PORTB, temp
- jmp START
- STOP_HANDLER1:
- call Reset_Timer_configuration
- STOP_HANDLER:
- ser temp
- out PORTB, temp
- jmp START
- StageB1B3Handler:
- clr potIndicator
- tst potH ;chcek if potH=0
- breq ContB ;yes go to cont
- rjmp ErrorB ;no->go to ErrorB
- ContB:
- cpi potL, $1F ;16 ;check if lower tahn min
- brlo ContB_2 ;yes go to cont2
- ErrorB:
- ldi potIndicator, $01
- clr intr_flag
- sbi ADCSRA,6 ;start conversion
- ContB_2:
- ret
- StageA1Handler:
- clr potIndicator
- cpi potH, $02
- brsh ContA1
- ldi potIndicator, $01
- clr intr_flag
- sbi ADCSRA,6 ;start conversion
- ContA1:
- ret
- M2On:
- in input, PIND
- sbrs input,5 ; if its pressed go somewhere- if not pressed clear to go
- rjmp Error_Handler
- ;OPEN LED4
- clr temp
- bst temp,0
- bld led,4 ;this way previous values are not lost
- out PORTB, led ;open LED4
- ret
- ADC_HANDLER_A1:
- cbr intr_flag, $01 ;bit 1
- tst potH
- brne exit_ADC_HANDLER_A1
- cpi potL, 0x10 ;16 A1 is the silo that has been measured. If its is low, error!
- brsh exit_ADC_HANDLER_A1
- ori potIndicator, $01 ;bit 0 of register, indicates problem at A1
- exit_ADC_HANDLER_A1:
- sbi ADCSRA, 6 ;begin conversion once more
- ret
- ADC_HANDLER_Y1:
- in temp, ADMUX
- cpi temp, $C0
- brne potB2_check
- ;load B2 to ADMUX
- ldi temp, $C2
- out ADMUX, temp
- ;the conversion will be initialized at stage4 handler
- call ADC_HANDLER_A1
- ret
- potB2_check:
- cbr intr_flag, $01 ;bit 1
- cpi potH, $02
- brlo exit_adc_handler_stage_5 ;B2 is not full yet
- ori potIndicator, $02 ;bit 1 of register, indicates B2 is full
- exit_adc_handler_stage_5:
- ;load A1 to ADMUX
- ldi temp, $C0
- out ADMUX, temp
- sbi ADCSRA, 6 ;begin conversion once more
- ret
- ADC_HANDLER_Y2:
- in temp, ADMUX
- cpi temp, $C0
- brne potB4_check
- ;load B4 to ADMUX
- ldi temp, $C4
- out ADMUX, temp
- ;the conversion will be initialized at stage4 handler
- call ADC_HANDLER_A1
- ret
- potB4_check:
- cbr intr_flag, $01 ;bit 1
- cpi potH, $02
- brlo exit_adc_handler_stage_6 ;B4 is not full yet
- ori potIndicator, $02 ;bit 1 of register, indicates B2 is full
- exit_adc_handler_stage_6:
- ;load A1 to ADMUX
- ldi temp, $C0
- out ADMUX, temp
- sbi ADCSRA, 6 ;begin conversion once more
- ret
- Reset_Timer_configuration:
- cli
- clr temp
- out TCCR1B, temp
- out TIMSK, temp
- out TCNT1L, temp
- out TCNT1H, temp
- ;include the clearing of any flags
- ldi temp, $14;00010100 clear OCR1A & TIMOVF1 flag
- out TIFR, temp
- cbr intr_flag, $02 ;clear bit 1
- sei
- ret
- Reset_ADC_configuration:
- cli
- clr temp
- out ADMUX, temp
- ;include the clearing of flags
- sbi ADCSRA, 4 ;clear the interrupt flag in case it has risen
- cbr intr_flag, $01 ;clear bit 0, that corresponds to the ADC interrupt
- clr potIndicator
- sei
- ret
- BLINK:
- cbr intr_flag, $02 ;clear bit 1
- ;1 second is completed
- inc seconds
- sbrc seconds,0 ;an peritos sbise
- call blink0Off
- sbrs seconds, 0 ;an artios anapse
- call blink0On
- ret
- blink0On:
- clr temp
- bst temp,0
- bld led,0
- out PORTB, led
- ret
- blink0Off:
- clr temp
- com temp
- bst temp,0
- bld led,0
- out PORTB, led
- ret
- DELAY_FOR_BUTTONS:
- clr TEMP3
- clr TEMP2
- clr TEMP1
- ;1953/256=7
- ;outside here 256 ;1 counter
- ;outside here 7;+ 1 counter
- Start_mini_delay1:
- Start_mini_delay2:
- Start_mini_delay3:;ALL THIS I WANT TO HAPPEN 1953 TIMES
- nop
- nop
- nop
- nop
- inc TEMP3
- cpi TEMP3, $FF
- brne Start_mini_delay3
- clr TEMP3
- inc TEMP2
- cpi TEMP2, $FF
- brne Start_mini_delay2
- clr TEMP2
- inc TEMP1
- cpi TEMP1, $14
- brne Start_mini_delay1
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement