Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.03.2015, 17:48   #1
OldStile
Новичок
Джуниор
 
Регистрация: 20.03.2015
Сообщений: 4
Печаль Деление, умножение, суммирование, хэлпа нужна очень... почти готов код

Код:
 ; Программа управления температурой 
 .NOLIST 
 .INCLUDE "8535def.inc" 
 .LIST  
 ; определить символические имена 
 .DEF  templ = r16   
 .DEF  temph = r17   
 .DEF  saveF = r4   
 .DEF  counT = r18
 .DEF  rcnt = r19
 .EQU Mind = 0x100 ;RAM для кодов индикации 
 .EQU Madc = 0x090 ;RAM для кода АЦП 
 .CSEG  

 ; вектора прерываний 
 .ORG $000   
 rjmp  init    ; прерывание по reset   
 rjmp  key_cnt   ; прерывание int0
.ORG $009   
  
 rjmp  adc_cmt  ; прерывание АЦП 
 .ORG $011 

.ORG $01E
RETI ; (EE_RDY) EEPROM Ready

 ;инициализация 
 init:  
 ldi  templ,low(RAMEND)   
 ldi  temph,high(RAMEND)   
 out  SPH, temph    
 out  SPL, templ  ;определить в указателе стека адрес RAMEND  
 ;порты ввода-вывода   
 ldi  templ, 0b11000000   
 clr  temph   
 out  PORTA, temph      
 out  DDRA, templ      
 ser templ    
 out  PORTB, templ      
 out  DDRB,  templ  ; порт B на вывод   
 out  PORTD, templ      
 out  DDRD, temph  ; порт D на ввод  
 ;внешнее прерывание INT0   
 ldi  templ, (1<<ISC01)|(0<<ISC00)   
 out  MCUCR, templ  ; INT0 по падающему фронту    
 ldi  templ, (1<<INT0)   
 out  GIMSK, templ  ; разрешение INT0  
 ;прерывание таймера 0   
 ldi  templ, (1<<TOIE0)     
 out  TIMSK, templ    ;параметры SPI   
 ldi  templ, 0b11011001   
 out  SPCR, templ    ;параметры АЦП   
 clr templ   
 out  ADMUX, templ ;канал РА0 для АЦП    
 ldi  templ, 0b10001101   
 out  ADCSR, templ    
 sei      ; общее разрешение прерываний   
 rcall  ind_off  ; выключение индикации 

 ; бессодержательный бесконечный цикл, может быть заменен любой программой 
 main: nop   
 rjmp  main  

 ind_off:  ;вывод нулевых байтов в SPI для отключения индикации   
 clr templ   
 ldi  XL, low(Mind)   
 ldi  XH, high(Mind) ;начальный адрес RAM для кодов SPI   
 st   X+,  templ   
 st   X+,  templ   
 st   X+,  templ   
 ldi  XL, low(Mind) ;восстановление в Х начального адреса   
 ret  

 ;INT0, кнопки управления 
 key_cnt:  ;сохранение в стеке регистров и флагов   
 push  templ    
 push  temph    
 push  saveF    
 in  saveF, SREG   

 ;обработка сигналов "Стоп", "Пуск"   
 in    templ, PINB     
 sbrs  templ, PB2  ; контроль сигнала СТОП   
 rjmp  cnt_off   ; перейти к процедуре СТОП   
 sbrs  templ, PB1  ; контроль сигнала ПУСК  
 rjmp  cnt_on   ; перейти к процедуре ПУСК 

 ;если оба сигнала в 1, завершить без изменения режима  

 key_out:  ; завершение с восстановлением из стека флагов и регистров    
 out  SREG, saveF    
 pop  saveF    
 pop  temph    
 pop  templ    
 reti     

 cnt_on:  ;переход в режим ПУСК   
 tst  rcnt     
 brne key_out  ;завершить по признаку режима ПУСК   
 sbr  rcnt, 0x80 ;установить признак режима ПУСК в rcnt   
 ldi  temph, 0x05    
 out  TCCR0, temph  ;запуск таймера циклов контроля   
 clr  counT  ;сброс счетчика для формирования цикла   
 out  ADMUX, counT ;канал РА0 для АЦП   
 sbi  ADCSR, ADSC  ;запуск АЦП для 1 цикла контроля   
 rjmp  key_out   ;завершение процедуры  

 cnt_off:  ;переход в режим СТОП   
 tst   rcnt     
 breq  key_out  ;завершить по признаку режима СТОП   
 clr   rcnt  ;сбросить признаки режима ПУСК в rcnt   
 clr   temph     
 out   TCCR0, temph  ;останов таймера циклов контроля   
 out   TCNT0, temph  ;сброс таймера циклов контроля   
 clr   counT  ;сброс счетчика для формирования цикла    

 wait_spi:   
 cpi   XL, low(Mind) ;контроль вывода байтов индикации 
 breq  cnt_end  ;продолжение процедуры, если вывод завершен   
 sei  ;разрешить прерывания при ожидании   
 rjmp  wait_spi ;возврат к контролю завершения цикла вывода  
 
 cnt_end:   
 rcall  ind_off  ;выключить индикацию для СТОП   
 rjmp   key_out   ;завершение процедуры  
 ;периодический запуск цикла управления в режиме ПУСК 

 cycle:   
 push  saveF    
 in    saveF, SREG    
 tst   rcnt  ;контроль режима ПУСК  
 breq  cyc_out  ;завершить без запуска для СТОП   
 cpi   counT, 15  ;контроль количества прерываний таймера 0   
 breq  cyc_do  ;запуск цикла по 16 прерыванию   
 inc   counT   ;инкремент количества прерываний  
 rjmp  cyc_out  ;завершить без запуска (<16)  
 
 cyc_do:   
 clr   counT   ;очистка счетчика прерываний   
 out   ADMUX, counT ;канал РА0 для АЦП   
 sbi   ADCSR, ADSC  ;запуск АЦП, начало цикла контроля  
 ;завершение с восстановлением флагов 
 
 cyc_out:   
 out  SREG, saveF    
 pop  saveF    
 reti     

;прерывание по завершению преобразования АЦП 
 adc_cmt:   
 push  templ    
 push  temph    
 push  saveF    
 in    saveF, SREG    
 tst   rcnt     
 brne  make1

Последний раз редактировалось OldStile; 20.03.2015 в 18:26.
OldStile вне форума Ответить с цитированием
Старый 20.03.2015, 17:49   #2
OldStile
Новичок
Джуниор
 
Регистрация: 20.03.2015
Сообщений: 4
По умолчанию

Код:
 make1: ;прием кода    
 in   templ, ADCL  ; младший байт кода АЦП    
 in   temph, ADCH  ; старший байт кода АЦП    
 lsr  temph   
 ror  templ    
 lsr  temph  ; двукратный сдвиг вправо с переносом    
 ror  templ  ; для преобразования в 8-битовый формат   
 in   temph, ADMUX ;номер канала ?   
 tst  temph   ;   
 brne tmtr   ;перейти к обработке 
 sbi  ADMUX, MUX0 ;установить канал РА1   
 sbi  ADCSR, ADSC  ; запустить преобразование в АЦП   
 sts  Madc, templ  ; сохранить код канала РА0

 EEwrite:
	sbic EECR, EEWE ; ждем готовности памяти к записи, крутимся в цикле
	rjmp EEWrite    ; до тех пор пока не очистится флаг EEWE

	cli ; затем запрещаем прерывания
	out EEARL,R16 ; загружаем адресс нужной ячейки
	out EEARH, R17 ; старший и младший байт адресса
	out EEDR, R21 ; и сами данные 

	sbi EECR, EEMWE ; взводим предохранитель
	sbi EECR. EEWE ; записываем байт

	sei ; разрешаем прерывания
	reti ; вовзрат из процедуры

 EERead:
	sbic EECR,EEWE ; ждем пока будет завершена прошлая запись
	rjmp EEread ; также крутимся в цикле
	out EEARL, r16 ; загружаем адресс нужной ячейки
	out EEARH, r17 ; его старшие и младшие байты
	sbi EECR, EERE ; выставляем бит чтения
	in r21, EEDR ; забираем из регистра данных результат
	reti 

 tmtr:  ; 
 lds  temph, Madc  
 ;считать из RAM код PA0
 sub  temph, templ ;вычесть коды РА0 и РА1, получив ошибку 
 rol  temph  ;сдвинуть влево с переносом вычитания 
 ldi r18,32 ; загружаем константу 32 в регистр 18
 mul r17,r18 ; умножаем ошибку которая находится в регистре r17 на константу хранящуюся в регистре r18
 mul r17,EEDR; умножаем полученное выражение на число хранящимся в EEPROM
 mul r17, temph
 EEDR * temph/800


  ;анализ кода температуры   
 cpi templ, 28  ; допустимый порог    
 brcs  thresh1  ;перейти к следующему порогу, если <   
 rcall  Pump1  ;включить насос1   
 rjmp  bcdt  ;завершить анализ  


 thresh1:   
 cpi templ, 25  ; порог выключения Pump1  
 brcc bcdt  ; завершить анализ, если >  

 thresh2:   
 cpi templ, 23  ; порог включения pump2      
 rcall  Pump2  ;включить подогрев   
 rjmp  bcdt  ;завершить анализ   
  
 ;включение Pump1   
 Pump1:   
 sbis  PINA, PA7  ;пропустить, если включено    
 sbi  PORTA, PA7 ;включить    
 ret  ;возврат   
 ;включение Pump2
 Pump2:   
 sbis  PINA, PA6  ;пропустить, если включено   
 sbi  PORTA, PA6 ;включить подогрев   
 ret  ;  
 ;выключение Pump1 и Pump2   
 
 offch:   
 sbic  PINA, PA7  ; пропустить, если выключено  
 cbi  PORTA, PA7 ; выключить охлаждение   
 sbic  PINA, PA6  ; пропустить, если выключено   
 cbi  PORTA, PA6 ; выключить подогрев   
 ret  ;  
 ;преобразование кода в bcd формат для индикации  
 
 bcdt:   
 clr  temph  ;очистка регистра для десятичной цифры   
 hunst:    ;определение цифры сотен   
 cpi  templ, 100 ;   
 brcs  hunout  ;перейти к сохранению сотен для SPI  
 subi  templ, 100 ;вычесть 100   
 inc  temph  ;инкремент сотен   
 rjmp  hunst  ;повторить цикл вычислений  
 hunout:  ; код индикации и запись в RAM для SPI  
 rcall  code_ind  
 decst:   clr  temph  ; очистка регистра для десятичной цифры   
 cpi  templ, 10 ; определение цифры десятков   
 brcs  decout  ; перейти к сохранению сотен для SPI   
 subi  templ, 10 ; вычесть 10   
 inc  temph  ; инкремент десятков   
 rjmp  decst  ; повторить цикл вычислений  
 decout:   ; код индикации и запись в RAM для SPI десятков   
 rcall  code_ind  
  
 ; код индикации и запись в RAM для SPI десятков   
 mov  temph, templ ;передать цифру единиц   
 rcall  code_ind ;   
 rjmp  str_spi  ;перейти к старту SPI  
 code_ind:  
 ldi  ZL, low(cdind*2) ;  
 ldi  ZH, high(cdind*2) ; адрес FLASH для кодов индикации   
 add  ZL, temph ;смещение адреса по цифре в  temph   
 lpm     
 ;прочитать код индикации для цифры из temph   
 st  -X, r0  ;сохранить код индикации в RAM для SPI   
 ret     ;возврат  
 ;старт SPI для передачи кодов индикации  

 str_spi:   
 ldi  XL, low(Mind)   
 ldi  XH, high(Mind) ;начальный адрес RAM для кодов SPI   
 rcall  spi_stc  ;старт передачи байтов индикации  

 adc_out:  ; завершение с восстановлением из стека флагов и регистров    
 out  SREG, saveF    
 pop  saveF    
 pop  templ    
 reti     
 ;передача кодов управления индикацией 

 spi_stc:   
 push  templ    
 push  temph   
 push  saveF    
 in  saveF, SREG   
 cpi XL, low(Mind+3) ;   
 breq  load  ;   
 ld  templ, X+ ;  
 cpi XL, low(Mind+2) ;   
 brne  skip   ;   
 sbr  templ, 0x80  ;   
 skip:  
 out  SPDR, templ ; 
  
 spi_out:  ; завершение с восстановлением из стека флагов и регистров    
 out  SREG, saveF    
 pop  saveF    
 pop  templ    
 reti     
 load:   
 cbi  PORTB, PB0   
 nop   
 nop   
 nop    ;   
 sbi  PORTB, PB0 ;   
 rjmp  spi_out  ;  

 .ORG 0x0800 cdind:  ;коды индикации цифр, начиная с нуля 
 .dB     0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f  
 ;end of file

Последний раз редактировалось OldStile; 20.03.2015 в 17:52.
OldStile вне форума Ответить с цитированием
Старый 20.03.2015, 17:52   #3
OldStile
Новичок
Джуниор
 
Регистрация: 20.03.2015
Сообщений: 4
По умолчанию

Застрял, с делением и умножением...
Код:
EEwrite:
	sbic EECR, EEWE ; ждем готовности памяти к записи, крутимся в цикле
	rjmp EEWrite    ; до тех пор пока не очистится флаг EEWE

	cli ; затем запрещаем прерывания
	out EEARL,R16 ; загружаем адресс нужной ячейки
	out EEARH, R17 ; старший и младший байт адресса
	out EEDR, R21 ; и сами данные 

	sbi EECR, EEMWE ; взводим предохранитель
	sbi EECR. EEWE ; записываем байт

	sei ; разрешаем прерывания
	reti ; вовзрат из процедуры

 EERead:
	sbic EECR,EEWE ; ждем пока будет завершена прошлая запись
	rjmp EEread ; также крутимся в цикле
	out EEARL, r16 ; загружаем адресс нужной ячейки
	out EEARH, r17 ; его старшие и младшие байты
	sbi EECR, EERE ; выставляем бит чтения
	in r21, EEDR ; забираем из регистра данных результат
	reti 

 tmtr:  ; 
 lds  temph, Madc  
 ;считать из RAM код PA0
 sub  temph, templ ;вычесть коды РА0 и РА1, получив ошибку 
 rol  temph  ;сдвинуть влево с переносом вычитания 
 ldi r18,32 ; загружаем константу 32 в регистр 18
 mul r17,r18 ; умножаем ошибку которая находится в регистре r17 на константу хранящуюся в регистре r18
 mul r17,EEDR; умножаем полученное выражение на число хранящимся в EEPROM
 mul r17, temph
 EEDR * temph/800
вот тут если что непонятно спрашивайте, постараюсь ответить

Последний раз редактировалось OldStile; 20.03.2015 в 18:28.
OldStile вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Умножение и деление danil123 Общие вопросы Delphi 7 03.02.2013 13:41
Переменные и массивы; умножение и деление kjrjgsnjd Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 22.10.2012 21:32
Нужно исправить код. Он готов, но нужна проверка и доработка. Forbesii Фриланс 2 24.12.2010 23:09
ВЫчитание, умножение и деление массивов на С++ Flood Помощь студентам 2 15.05.2010 16:54
Умножение и деление StiTch_Parazit Помощь студентам 10 20.05.2008 14:32