;######################### ;### CA-722 ### ;######################### ;Version 2.1 ;Date: 07 JUN 2005 ;Filename: CA-722.ASM ;Support E-mail: info@astroma-spb.ru ;Target: ACM-801, ACM-811 ;ПРОГРАММА УПРАВЛЕНИЯ ЗАЧИСТНЫМ СТАНКОМ CA-722 ФИРМЫ MURAT .INCLUDE "m64def.inc" ;файл предоставляется компанией Atmel (www.atmel.com) .INCLUDE "ACM-801.inc" ;файл предоставляется компанией Astroma Ltd. (www.astroma-spb.ru) .equ SRAM_ADDRESS =$4000 ;начало рабочей области в SRAM .CSEG BEGIN: CALL GetBaseAddress ;определить базовый адрес программы mov yl,xl ;сохранить в регистровой паре Y mov yh,xh ;подключение обработчика задачи управления ldi r25,HOOK_SYS_TIME ;идентификатор ловушки CALL GetHookHandler ;получить адрес обработчика ловушки sts (RET_ADDRESS),xl ;сохранить для возврата sts (RET_ADDRESS+1),xh clr xl ;инициализация переменных ldi xh,Clr_Len ldi zl,low(Clr_Begin) ldi zh,high(Clr_Begin) CLR_VAR: st Z+,xl dec xh brne CLR_VAR ldi xl,2 sts (TIME_DIV),xl ldi xl,100 sts (SEC_DIV),xl ldi xl,low(TASK) ;X - смещение обработчика задачи управления ldi xh,high(TASK) add xl,yl ;прибавить базовый адрес adc xh,yh ;X - адрес обработчика задачи управления ldi r25,HOOK_SYS_TIME CALL SetHook ;настроить ловушку 200 Hz ;подключение обработчика команды 05h ldi xl,low(COMM_05h) ldi xh,high(COMM_05h) add xl,yl adc xh,yh ldi r25,$05 ;код команды CALL SetCmdHandler ;установить адрес обработчика команды 02h ;подключение обработчика команды 06h ldi xl,low(COMM_06h) ldi xh,high(COMM_06h) add xl,yl adc xh,yh ldi r25,$06 ;код команды CALL SetCmdHandler ;установить адрес обработчика команды 02h ret ;*************************************************************************** ;ОБРАБОТЧИК ЗАДАЧИ УПРАВЛЕНИЯ TASK: push r25 lds r25,(TIME_DIV) ;делитель частоты (получение 100Hz) dec r25 breq RUN_TASK ;если 0 - перейти на обработчик задачи sts (TIME_DIV),r25 ;возврат в систему TASK_EXIT: lds zl,(RET_ADDRESS) lds zh,(RET_ADDRESS+1); Z - адрес возврата pop r25 ijmp ;--------------------------------------------------------------------------- RUN_TASK: ldi r25,2 sts (TIME_DIV),r25 ;инициализция делителя lds r25,(SEC_DIV) ;делитель для получения 1 Hz dec r25 brne TIMER_COMPLETE ldi zl,low(WORK_TIME) ldi zh,high(WORK_TIME) rcall INC_DWORD ldi r25,100 TIMER_COMPLETE: sts (SEC_DIV),r25 sbic PIND,3 ;проверка блокировок (Digital IN 3) rjmp TASK_CONTINUE lds r25,(TASK_PHASE) or r25,r25 breq TASK_EXIT ;остановка при срабатывании блокировок TASK_STOP: sts (TASK_WAIT),r25 ;сброс паузы sts (TASK_WAIT+1),r25 in r25,PORTB andi r25,$F0 ;выключить все out PORTB,r25 TASK_RESTART: clr r25 ;сбросить выполнение задачи sts (TASK_PHASE),r25 rjmp TASK_EXIT ;-------------------------------------------------------------------------- ;отсчет устанавливаемых пауз TASK_PAUSE: lds zl,(TASK_WAIT) lds zh,(TASK_WAIT+1) or zl,zh breq TASK_PAUSE_END lds zl,(TASK_WAIT) sbiw zh:zl,1 sts (TASK_WAIT),zl sts (TASK_WAIT+1),zh TASK_PAUSE_END: ret ;-------------------------------------------------------------------------- ;выбор фазы выполнения задачи TASK_CONTINUE: lds r25,(TASK_PHASE) or r25,r25 breq TASK_PHASE_0 dec r25 breq TASK_PHASE_1 dec r25 breq TASK_PHASE_2 dec r25 brne TASK_CONT_0 rjmp TASK_PHASE_3 TASK_CONT_0: dec r25 brne TASK_CONT_1 rjmp TASK_PHASE_4 TASK_CONT_1: dec r25 brne TASK_STOP rjmp TASK_PHASE_5 ;ФАЗА 0 - ожидание установки профиля TASK_PHASE_0: rcall TASK_PAUSE ;если Z устанолен, пауза завершена brne TASK_EXIT_X sbis PIND,0 ;проверка наличия профиля rjmp TASK_EXIT ldi r25,25 ;устновить паузу 0.25с sts (TASK_WAIT),r25 ldi r25,1 sts (TASK_PHASE),r25;установка фазы 1 TASK_EXIT_X: rjmp TASK_EXIT ;ФАЗА 1 - прижим профиля TASK_PHASE_1: rcall TASK_PAUSE ;если Z устанолен, пауза завершена brne TASK_EXIT_X sbis PIND,0 ;проверка наличия профиля TASK_STOP_X: rjmp TASK_STOP sbi PORTB,3 ;запуск прижима ldi r25,$01 ;установить паузу 3.5c ( 015Eh ) sts (TASK_WAIT+1),r25;(время срабатывания прижима) ldi r25,$5E sts (TASK_WAIT),r25 ldi r25,2 ;установить фазу 2 sts (TASK_PHASE),r25 rjmp TASK_EXIT ;ФАЗА 2 - запуск ножей TASK_PHASE_2: sbis PIND,0 ;проверка наличия профиля rjmp TASK_STOP rcall TASK_PAUSE ;если Z устанолен, пауза завершена brne TASK_EXIT_X ;начиная с этого момента возврат в фазу 0 только через паузу 2c sbic PIND,4 ;проверка S0 rjmp RUN_PHASE_3 ;если только фреза, пропустить ножи sbic PIND,2 ;проверка положения фрезы (S6) rjmp TASK_COMPLETE sbi PORTB,2; ;пуск ножей ldi r25,3 ;устаноить фазу 3 sts (TASK_PHASE),r25 rjmp TASK_EXIT ;ФАЗА 3 - запуск фрезы TASK_PHASE_3: sbis PIND,1 ;проверить S5 rjmp TASK_EXIT ;ножи не дошли, выход RUN_PHASE_3: sbic PIND,5 ;проверка S1 rjmp TASK_PHASE_4_1 ;если только ножи, пропустить фрезу cbi PORTB,2 ;отключение ножей sbi PORTB,0 ;пуск двигателя фрезы sbi PORTB,1 ;пуск подачи фрезы ldi r25,4 ;установить фазу 4 sts (TASK_PHASE),r25 ldi r25,40 ;пауза 0.4с sts (TASK_WAIT),r25 rjmp TASK_EXIT ;ФАЗА 4 - завершение процесса обработки TASK_PHASE_4: rcall TASK_PAUSE brne TASK_EXIT_X in r25,PIND andi r25,0b00000110 ;если 0 - идет процесс обработки breq TASK_EXIT_X TASK_PHASE_4_1: in r25,PORTB andi r25,$F0 ;выключить все out PORTB,r25 ldi r25,5 ;установить фазу 5 sts (TASK_PHASE),r25 rjmp TASK_EXIT ;ФАЗА 5 - ожидание снятия профиля TASK_PHASE_5: sbic PIND,0 ;проверка наличия профиля rjmp TASK_EXIT ;профиль не снят TASK_COMPLETE: ldi r25,200 ;иначе установить паузу 2с sts (TASK_WAIT),r25 ;подсчет операций по видам обработки in r25,PIND lsr r25 lsr r25 andi r25,$0C cpi r25,$0C brcc COUNTER_END ldi zl,low(OP0_COUNTER) ldi zh,high(OP0_COUNTER) add zl,r25 ldi r25,$00 adc zh,r25 rcall INC_DWORD COUNTER_END: rjmp TASK_RESTART ;**************************************************** INC_DWORD: push zl push zh rcall INC_WORD brcc INC_DWORD_COMP rcall INC_WORD INC_DWORD_COMP: pop zh pop zl ret ;---------------------------------- INC_WORD: push xl push xh ld xl,Z ldd xh,Z+1 adiw xh:xl,1 st Z+,xl st Z+,xh pop xh pop xl ret ;**************************************************** ;обработчик команды 05h - чтение счетчиков COMM_05h: push xl push xh CALL GetSysReceiveBuffer ;получить адрес приемного буфера по UART adiw xh:xl,1 ;указать на длину пакета ld r25,X cpi r25,3 ;проверить длину brne COMM_ERROR adiw xh:xl,2 ;указать OpCode ld r25,X cpi r25,3 ;проверить OpCode brcc COMM_ERROR lsl r25 lsl r25 push r24 push r25 ;ФОРМИРОВАНИЕ ОТВЕТНОГО ПАКЕТА CALL GetSysSendBuffer ;получить адрес буфера передачи ldi r25,10 ;длина ответного пакета st X+,r25 ldi r25,$06 ;ACK st X+,r25 ;копирование счетчика времени ldi zl,low(WORK_TIME) ldi zh,high(WORK_TIME) ldi r24,4 ;длина счетчика COMM_05h_1: ld r25,Z+ st X+,r25 dec r24 brne COMM_05h_1 pop r25 ;копирование счетчика указанной операции add zl,r25 adc zh,r24 ldi r24,4 ;длина счетчика COMM_05h_2: ld r25,Z+ st X+,r25 dec r24 brne COMM_05h_2 pop r24 COMM_05h_EXIT: pop xh pop xl ret ;**************************************************** ;ФОРМИРОВАНИЕ ОТВЕТНОГО ПАКЕТА ;[Len][15h][ChSum] COMM_ERROR: CALL GetSysSendBuffer ;получить адрес буфера передачи ldi r25,$02 ;Len st X+,r25 ldi r25,$15 ;NACK st X+,r25 rjmp COMM_05h_EXIT ;**************************************************** ;обработчик команды 06h - сбросить счетчики COMM_06h: push xl push xh CALL GetSysReceiveBuffer ;получить адрес приемного буфера по UART adiw xh:xl,1 ;указать на длину пакета ld r25,X cpi r25,2 ;проверить длину brne COMM_ERROR ;ВЫПОЛНЕНИЕ КОМАНДЫ push r24 clr r25 ldi xl,low(WORK_TIME) ldi xh,high(WORK_TIME) ldi r24,(Clr_End-WORK_TIME) COMM_06h_1: st X+,r25 dec r24 brne COMM_06h_1 pop r24 ;ФОРМИРОВАНИЕ ОТВЕТНОГО ПАКЕТА [Length] [06h] [ChSum] CALL GetSysSendBuffer ;получить адрес буфера передачи ldi r25,2 ;длина ответного пакета st X+,r25 ldi r25,$06 ;ACK st X+,r25 pop xh pop xl ret ;**************************************************** .DSEG .org SRAM_ADDRESS RET_ADDRESS: .byte 2 ;адрес возврата из обработчика CA-722 TIME_DIV: .byte 1 ;делитель частоты в 100 Hz SEC_DIV: .byte 1 ;делитель частоты в 1 Hz Clr_Begin: TASK_WAIT: .byte 2 ;счетчик паузы TASK_PHASE: .byte 1 ;фаза выполнения задачи ;переменные для ведения учета WORK_TIME: .byte 4 ;время работы (сек) OP0_COUNTER: .byte 4 ;счетчик операций 0 OP1_COUNTER: .byte 4 ;счетчик операций 1 OP2_COUNTER: .byte 4 ;счетчик операций 2 Clr_End: .equ Clr_Len=Clr_End-Clr_Begin