Исследование PPM кодировки
К сожалению, яндекс диск заглючил, залить всё не получается. Кому надо, пишите, закину на мыло.
Программирование ATMEL в BASCOM. |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование PPM кодировки
Исследование PPM кодировки
К сожалению, яндекс диск заглючил, залить всё не получается. Кому надо, пишите, закину на мыло.
Для пробы залил на Google диск, симуляция (можно покрутить и посмотреть) - скачать
$map
$regfile = "m328pdef.dat"
$crystal = 18432000
$framesize = 128
$hwstack = 128
$swstack = 128'===============================================================================
' Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (8 МГц / 128 = 62 500)
Config Adc = Single , Prescaler = 128 , Reference = Avcc'Ссылка на подпрограмму обработчика прерывания АЦП
On Adc Interrupt_processing_adc NosaveAdcsra.aden = 1 'Включаем АЦП
Waitms 10 'Ждём когда всё запустится и выйдет на рабочие уровни'Номера каналов АЦП
Channel_adc_0 Alias &B_0100_0000 'Опорное Avcc , 0 канал
Channel_adc_1 Alias &B_0100_0001 'Опорное Avcc , 1 канал
Channel_adc_2 Alias &B_0100_0010 'Опорное Avcc , 2 канал
Channel_adc_3 Alias &B_0100_0011 'Опорное Avcc , 3 канал
Channel_adc_4 Alias &B_0100_0100 'Опорное Avcc , 4 канал
Channel_adc_5 Alias &B_0100_0101 'Опорное Avcc , 5 канал
Channel_adc_6 Alias &B_0100_0110 'Опорное Avcc , 6 канал
Channel_adc_7 Alias &B_0100_0111 'Опорное Avcc , 7 каналDim Count_adc As Byte
Dim Sum_data_adc As Word
Dim Skip_1_measurement As Byte
Dim Flag_data_adc_ready As ByteDim Data_adc_word(8) As Word
'===============================================================================
' Конфигурация Servo
'===============================================================================
Config Servos = 8 , Servo1 = Portb.0 , Servo2 = Portb.1 , Servo3 = Portb.2 , Servo4 = Portb.3 , Servo5 = Portb.4 , Servo6 = Portb.5 , Servo7 = Portd.6 , Servo8 = Portd.7 , Reload = 10Config Portb.0 = Output : Config Portb.1 = Output : Config Portb.2 = Output : Config Portb.3 = Output : Config Portb.4 = Output : Config Portb.5 = Output
Config Portd.6 = Output : Config Portd.7 = OutputDim Byte_data_servo(8) As Byte
Dim Word_data_servo(8) As Word'-------------- Разрешаем работу необходимых прерываний ----------------------
Adcsra.adif = 1 'Сброс флага прерывания
Adcsra.adsc = 1 'Запуск измерения
Enable Adc 'Разрешение прерываний АЦП
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Flag_data_adc_ready > 0 Then
Word_data_servo(1) = Data_adc_word(1)
Word_data_servo(2) = Data_adc_word(2)
Word_data_servo(3) = Data_adc_word(3)
Word_data_servo(4) = Data_adc_word(4)
Word_data_servo(5) = Data_adc_word(5)
Word_data_servo(6) = Data_adc_word(6)
Word_data_servo(7) = Data_adc_word(7)
Word_data_servo(8) = Data_adc_word(8)Shift Word_data_servo(1) , Right , 2
Shift Word_data_servo(2) , Right , 2
Shift Word_data_servo(3) , Right , 2
Shift Word_data_servo(4) , Right , 2
Shift Word_data_servo(5) , Right , 2
Shift Word_data_servo(6) , Right , 2
Shift Word_data_servo(7) , Right , 2
Shift Word_data_servo(8) , Right , 2Servo(1) = Word_data_servo(1)
Servo(2) = Word_data_servo(2)
Servo(3) = Word_data_servo(3)
Servo(4) = Word_data_servo(4)
Servo(5) = Word_data_servo(5)
Servo(6) = Word_data_servo(6)
Servo(7) = Word_data_servo(7)
Servo(8) = Word_data_servo(8)Flag_data_adc_ready = 0
Goto Главный_цикл
End If' Power Idle ' Отправляем МК на тихий час
'===============================================================================
Goto Главный_цикл
End
'===============================================================================
' П О Д К Л Ю Ч Е Н И Е Р А Б О Ч И Х М О Д У Л Е Й
'==============================================================================='===============================================================================
Interrupt_processing_adc_1:
'-------------------------------------------------------------------------------
!clr R26
!sts {Skip_1_measurement} , R26
!rjmp Start_measurement_adc
'===============================================================================
Interrupt_processing_adc:
'-------------------------------------------------------------------------------
'Сохраняем регистры
'Т.к., используются логические операции, обязательно сохраняем SREG
!push R26
!in R26 , sreg
!push R26
!push R27'Если сменили канал, пропускаем первое измерение
!lds R26 , {Skip_1_measurement}
!tst R26
!brne Interrupt_processing_adc_1'Набираем сумму из 16 измерений, для усреднения показаний
!lds R26 , {Sum_data_adc}
!in R27 , adcl
!add R26 , R27
!sts {Sum_data_adc} , R26!lds R26 , {Sum_data_adc + 1}
!in R27 , adch
!adc R26 , R27
!sts {Sum_data_adc + 1} , R26'Считаем количество измерений
!lds R26 , {count_adc}
!inc R26
!sts {count_adc} , R26
'Если набрали 16 измерения
!cpi R26 , 16
!BREQ Mean
!rjmp Start_measurement_adc'Усреднение из 16 измерений
Mean:
!push R16
!push R17
!Push R30
!Push R31!ldi R30 , 4
!lds R26 , {Sum_data_adc}
!lds R27 , {Sum_data_adc + 1}
'Сдвиг вправо на 4 бита, или деление на 16
More_shift:
!lsr R27
!ror R26
!dec R30
!brne More_shift'Читаем текущий номер канала АЦП
!lds R16 , admux
!andi R16 , &B_0001_1111'13 тактов МК, самый быстрый вариант (аналог Goto Переменная Label)
!clr R17
!ldi R30 , low(_Save_data_adc_0)
!ldi R31 , high(_Save_data_adc_0)
!add R30 , R16
!adc R31 , R17
!ijmp_save_data_adc_0:
!rjmp Save_data_adc_0
_save_data_adc_1:
!rjmp Save_data_adc_1
_save_data_adc_2:
!rjmp Save_data_adc_2
_save_data_adc_3:
!rjmp Save_data_adc_3
_save_data_adc_4:
!rjmp Save_data_adc_4
_save_data_adc_5:
!rjmp Save_data_adc_5
_save_data_adc_6:
!rjmp Save_data_adc_6
_save_data_adc_7:
!rjmp Save_data_adc_7!ldi R30 , Channel_adc_0
!rjmp Change_channel_adcSave_data_adc_0:
!sts {Data_adc_word(1)} , R26
!sts {Data_adc_word(1) + 1} , R27
!ldi R30 , Channel_adc_1
!rjmp Change_channel_adcSave_data_adc_1:
!sts {Data_adc_word(2)} , R26
!sts {Data_adc_word(2) + 1} , R27
!ldi R30 , Channel_adc_2
!rjmp Change_channel_adcSave_data_adc_2:
!sts {Data_adc_word(3)} , R26
!sts {Data_adc_word(3) + 1} , R27
!ldi R30 , Channel_adc_3
!rjmp Change_channel_adcSave_data_adc_3:
!sts {Data_adc_word(4)} , R26
!sts {Data_adc_word(4) + 1} , R27
!ldi R30 , Channel_adc_4
!rjmp Change_channel_adcSave_data_adc_4:
!sts {Data_adc_word(5)} , R26
!sts {Data_adc_word(5) + 1} , R27
!ldi R30 , Channel_adc_5
!rjmp Change_channel_adcSave_data_adc_5:
!sts {Data_adc_word(6)} , R26
!sts {Data_adc_word(6) + 1} , R27
!ldi R30 , Channel_adc_6
!rjmp Change_channel_adcSave_data_adc_6:
!sts {Data_adc_word(7)} , R26
!sts {Data_adc_word(7) + 1} , R27
!ldi R30 , Channel_adc_7
!rjmp Change_channel_adcSave_data_adc_7:
!sts {Data_adc_word(8)} , R26
!sts {Data_adc_word(8) + 1} , R27
!ldi R30 , Channel_adc_0!ldi R26 , 1
!sts {Flag_data_adc_ready} , R26
'!rjmp Change_channel_adc'Переключаем канал АЦП
Change_channel_adc:
!sts admux , R30!pop R31
!pop R30
!pop R17
!pop R16'Обнуляем переменные для следующего измерения
!ldi R26 , 0
!ldi R27 , 1
!sts {Count_adc} , R26
!sts {Sum_data_adc} , R26
!sts {Sum_data_adc + 1} , R26
'Подымаем флаг смены канала, что бы пропустить первое измерение
!sts {Skip_1_measurement} , R27'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
Start_measurement_adc:
!lds R26 , ADCSRA
!ori R26 , &B_0100_0000
!sts ADCSRA , R26'Восстанавливаем регистры и SREG
Exit_interrupt_adc:
!pop R27
!pop R26
!out sreg , R26
!pop R26!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
'!!! ВНИМАНИЕ !!!
Const Availability_jitter = 0 'Если = 0, разрешаем прерывания в прерывании
'!!! ВНИМАНИЕ !!!$map
$regfile = "m328pdef.dat"
$crystal = 18432000
$framesize = 128
$hwstack = 128
$swstack = 128'===============================================================================
' Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (8 МГц / 128 = 62 500)
Config Adc = Single , Prescaler = 128 , Reference = Avcc'Ссылка на подпрограмму обработчика прерывания АЦП
On Adc Interrupt_processing_adc NosaveAdcsra.aden = 1 'Включаем АЦП
Waitms 10 'Ждём когда всё запустится и выйдет на рабочие уровни'Номера каналов АЦП
Channel_adc_0 Alias &B_0100_0000 'Опорное Avcc , 0 канал
Channel_adc_1 Alias &B_0100_0001 'Опорное Avcc , 1 канал
Channel_adc_2 Alias &B_0100_0010 'Опорное Avcc , 2 канал
Channel_adc_3 Alias &B_0100_0011 'Опорное Avcc , 3 канал
Channel_adc_4 Alias &B_0100_0100 'Опорное Avcc , 4 канал
Channel_adc_5 Alias &B_0100_0101 'Опорное Avcc , 5 канал
Channel_adc_6 Alias &B_0100_0110 'Опорное Avcc , 6 канал
Channel_adc_7 Alias &B_0100_0111 'Опорное Avcc , 7 каналDim Count_adc As Byte
Dim Sum_data_adc As Word
Dim Skip_1_measurement As Byte
Dim Flag_data_adc_ready As ByteDim Data_adc_word(8) As Word
'===============================================================================
' Конфигурация Servo
'===============================================================================
Servo_1_port Alias Portb : Servo_1_pin Alias 0
Servo_2_port Alias Portb : Servo_2_pin Alias 1
Servo_3_port Alias Portb : Servo_3_pin Alias 2
Servo_4_port Alias Portb : Servo_4_pin Alias 3
Servo_5_port Alias Portb : Servo_5_pin Alias 4
Servo_6_port Alias Portb : Servo_6_pin Alias 5
Servo_7_port Alias Portd : Servo_7_pin Alias 6
Servo_8_port Alias Portd : Servo_8_pin Alias 7Config Servo_1_port.servo_1_pin = Output
Config Servo_2_port.servo_2_pin = Output
Config Servo_3_port.servo_3_pin = Output
Config Servo_4_port.servo_4_pin = Output
Config Servo_5_port.servo_5_pin = Output
Config Servo_6_port.servo_6_pin = Output
Config Servo_7_port.servo_7_pin = Output
Config Servo_8_port.servo_8_pin = Output'===============================================================================
'Настройка TIMER0
'===============================================================================
Const Const_time_isr = 8 'Период прерываний в мксConst Const_div_timer0 = 1 'Аппаратный делитель используемого таймера
Const Const_compare0a_isr =((_xtal / 1000000) / Const_div_timer0 * Const_time_isr ) + 0.5
Compare0a = Const_compare0a_isrConfig Timer0 = Counter , Prescale = Const_div_timer0 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
On Compare0a Used_isr_compare0a Nosave
Stop Timer0
Timer0 = 0'---- Эти переменные должны распологаться именно в таком порядке ---------------
Dim Count_servo As Word
Dim Data_servo(8) As Byte
'-------------------------------------------------------------------------------Dim Flag_ready_data_servo As Byte
Dim Temp_data_servo(8) As ByteDim Byte_data_servo(8) As Byte
Dim Word_data_servo(8) As Word'-------------- Разрешаем работу необходимых прерываний ----------------------
Adcsra.adif = 1 'Сброс флага прерывания
Adcsra.adsc = 1 'Запуск измерения
Enable Adc 'Разрешение прерываний АЦПStart Timer0
Enable Compare0a'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Flag_data_adc_ready > 0 Then
Word_data_servo(1) = Data_adc_word(1)
Word_data_servo(2) = Data_adc_word(2)
Word_data_servo(3) = Data_adc_word(3)
Word_data_servo(4) = Data_adc_word(4)
Word_data_servo(5) = Data_adc_word(5)
Word_data_servo(6) = Data_adc_word(6)
Word_data_servo(7) = Data_adc_word(7)
Word_data_servo(8) = Data_adc_word(8)Shift Word_data_servo(1) , Right , 2
Shift Word_data_servo(2) , Right , 2
Shift Word_data_servo(3) , Right , 2
Shift Word_data_servo(4) , Right , 2
Shift Word_data_servo(5) , Right , 2
Shift Word_data_servo(6) , Right , 2
Shift Word_data_servo(7) , Right , 2
Shift Word_data_servo(8) , Right , 2Temp_data_servo(1) = Word_data_servo(1)
Temp_data_servo(2) = Word_data_servo(2)
Temp_data_servo(3) = Word_data_servo(3)
Temp_data_servo(4) = Word_data_servo(4)
Temp_data_servo(5) = Word_data_servo(5)
Temp_data_servo(6) = Word_data_servo(6)
Temp_data_servo(7) = Word_data_servo(7)
Temp_data_servo(8) = Word_data_servo(8)Flag_ready_data_servo = 1
Flag_data_adc_ready = 0
Goto Главный_цикл
End If' Power Idle ' Отправляем МК на тихий час
'===============================================================================
Goto Главный_цикл
End
'===============================================================================
' П О Д К Л Ю Ч Е Н И Е Р А Б О Ч И Х М О Д У Л Е Й
'==============================================================================='===============================================================================
Used_isr_compare0a:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R26
!push R27
!push R30
!push R31Loadadr Count_servo , X
!ld R30 , X+
!ld R31 , X
!adiw R30 , 1 'Сложить константу и слово
!st X , R31
!st -X , R30!clr R16
!cpi R30 , 1
!cpc R31 , R16
!brne Used_isr_compare0a_0 'Перейти если не равно!sbi Servo_1_port , Servo_1_pin
!sbi Servo_2_port , Servo_2_pin
!sbi Servo_3_port , Servo_3_pin
!sbi Servo_4_port , Servo_4_pin
!sbi Servo_5_port , Servo_5_pin
!sbi Servo_6_port , Servo_6_pin
!sbi Servo_7_port , Servo_7_pin
!sbi Servo_8_port , Servo_8_pin!lds R16 , {Flag_ready_data_servo}
!tst R16
!BRNE Reload_data_servo 'Перейти если не равно
!rjmp Exit_isr_compare0aReload_data_servo:
Loadadr Temp_data_servo(1) , X
Loadadr Data_servo(1) , Z!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16!clr R16
!sts {Flag_ready_data_servo} , R16
!rjmp Exit_isr_compare0aUsed_isr_compare0a_0:
!cpi R31 , 0
!breq Used_isr_compare0a_1!ldi R16 , 7
!cpc R31 , R16
!brcs Exit_isr_compare0a!clr R16
!st X+ , R16
!st X , R16!rjmp Exit_isr_compare0a
Used_isr_compare0a_1:
!adiw R26 , 2 'Сложить константу и словоUsed_servo_1:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_2
!cbi Servo_1_port , Servo_1_pinUsed_servo_2:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_3
!cbi Servo_2_port , Servo_2_pinUsed_servo_3:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_4
!cbi Servo_3_port , Servo_3_pinUsed_servo_4:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_5
!cbi Servo_4_port , Servo_4_pinUsed_servo_5:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_6
!cbi Servo_5_port , Servo_5_pinUsed_servo_6:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_7
!cbi Servo_6_port , Servo_6_pinUsed_servo_7:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_8
!cbi Servo_7_port , Servo_7_pinUsed_servo_8:
!ld R31 , X+
!cp R30 , R31
!brcs Exit_isr_compare0a
!cbi Servo_8_port , Servo_8_pinExit_isr_compare0a:
!pop R31
!pop R30
!pop R27
!pop R26
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Interrupt_processing_adc_1:
'-------------------------------------------------------------------------------
!clr R26
!sts {Skip_1_measurement} , R26
!rjmp Start_measurement_adc
'===============================================================================
Interrupt_processing_adc:
'-------------------------------------------------------------------------------
'!!! ВНИМАНИЕ !!!
#if Availability_jitter = 0
!sei 'Разрешаем прерывания в прерывании
#endif
'!!! ВНИМАНИЕ !!!'Сохраняем регистры
'Т.к., используются логические операции, обязательно сохраняем SREG
!push R26
!in R26 , sreg
!push R26
!push R27'Если сменили канал, пропускаем первое измерение
!lds R26 , {Skip_1_measurement}
!tst R26
!brne Interrupt_processing_adc_1'Набираем сумму из 16 измерений, для усреднения показаний
!lds R26 , {Sum_data_adc}
!in R27 , adcl
!add R26 , R27
!sts {Sum_data_adc} , R26!lds R26 , {Sum_data_adc + 1}
!in R27 , adch
!adc R26 , R27
!sts {Sum_data_adc + 1} , R26'Считаем количество измерений
!lds R26 , {count_adc}
!inc R26
!sts {count_adc} , R26
'Если набрали 16 измерения
!cpi R26 , 16
!BREQ Mean
!rjmp Start_measurement_adc'Усреднение из 16 измерений
Mean:
!push R16
!push R17
!Push R30
!Push R31!ldi R30 , 4
!lds R26 , {Sum_data_adc}
!lds R27 , {Sum_data_adc + 1}
'Сдвиг вправо на 4 бита, или деление на 16
More_shift:
!lsr R27
!ror R26
!dec R30
!brne More_shift'Читаем текущий номер канала АЦП
!lds R16 , admux
!andi R16 , &B_0001_1111'13 тактов МК, самый быстрый вариант (аналог Goto Переменная Label)
!clr R17
!ldi R30 , low(_Save_data_adc_0)
!ldi R31 , high(_Save_data_adc_0)
!add R30 , R16
!adc R31 , R17
!ijmp_save_data_adc_0:
!rjmp Save_data_adc_0
_save_data_adc_1:
!rjmp Save_data_adc_1
_save_data_adc_2:
!rjmp Save_data_adc_2
_save_data_adc_3:
!rjmp Save_data_adc_3
_save_data_adc_4:
!rjmp Save_data_adc_4
_save_data_adc_5:
!rjmp Save_data_adc_5
_save_data_adc_6:
!rjmp Save_data_adc_6
_save_data_adc_7:
!rjmp Save_data_adc_7!ldi R30 , Channel_adc_0
!rjmp Change_channel_adcSave_data_adc_0:
!sts {Data_adc_word(1)} , R26
!sts {Data_adc_word(1) + 1} , R27
!ldi R30 , Channel_adc_1
!rjmp Change_channel_adcSave_data_adc_1:
!sts {Data_adc_word(2)} , R26
!sts {Data_adc_word(2) + 1} , R27
!ldi R30 , Channel_adc_2
!rjmp Change_channel_adcSave_data_adc_2:
!sts {Data_adc_word(3)} , R26
!sts {Data_adc_word(3) + 1} , R27
!ldi R30 , Channel_adc_3
!rjmp Change_channel_adcSave_data_adc_3:
!sts {Data_adc_word(4)} , R26
!sts {Data_adc_word(4) + 1} , R27
!ldi R30 , Channel_adc_4
!rjmp Change_channel_adcSave_data_adc_4:
!sts {Data_adc_word(5)} , R26
!sts {Data_adc_word(5) + 1} , R27
!ldi R30 , Channel_adc_5
!rjmp Change_channel_adcSave_data_adc_5:
!sts {Data_adc_word(6)} , R26
!sts {Data_adc_word(6) + 1} , R27
!ldi R30 , Channel_adc_6
!rjmp Change_channel_adcSave_data_adc_6:
!sts {Data_adc_word(7)} , R26
!sts {Data_adc_word(7) + 1} , R27
!ldi R30 , Channel_adc_7
!rjmp Change_channel_adcSave_data_adc_7:
!sts {Data_adc_word(8)} , R26
!sts {Data_adc_word(8) + 1} , R27
!ldi R30 , Channel_adc_0!ldi R26 , 1
!sts {Flag_data_adc_ready} , R26
'!rjmp Change_channel_adc'Переключаем канал АЦП
Change_channel_adc:
!sts admux , R30!pop R31
!pop R30
!pop R17
!pop R16'Обнуляем переменные для следующего измерения
!ldi R26 , 0
!ldi R27 , 1
!sts {Count_adc} , R26
!sts {Sum_data_adc} , R26
!sts {Sum_data_adc + 1} , R26
'Подымаем флаг смены канала, что бы пропустить первое измерение
!sts {Skip_1_measurement} , R27'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
Start_measurement_adc:
!lds R26 , ADCSRA
!ori R26 , &B_0100_0000
!sts ADCSRA , R26'Восстанавливаем регистры и SREG
Exit_interrupt_adc:
!pop R27
!pop R26
!out sreg , R26
!pop R26!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
12 каналов, ASM AVR
! ВНИМАНИЕ !
Для устранения джиттинга, разрешаются прерывания в прерывании'===============================================================================
Interrupt_processing_adc:
'-------------------------------------------------------------------------------
'!!! ВНИМАНИЕ !!!
!sei 'Разрешаем прерывания в прерывании
'!!! ВНИМАНИЕ !!!'Сохраняем регистры
'Т.к., используются логические операции, обязательно сохраняем SREG
!push R26
!in R26 , sreg
!push R26
!push R27
$map
$regfile = "m328pdef.dat"
$crystal = 18432000
$framesize = 128
$hwstack = 128
$swstack = 128'===============================================================================
' Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (8 МГц / 128 = 62 500)
Config Adc = Single , Prescaler = 128 , Reference = Avcc'Ссылка на подпрограмму обработчика прерывания АЦП
On Adc Interrupt_processing_adc NosaveAdcsra.aden = 1 'Включаем АЦП
Waitms 10 'Ждём когда всё запустится и выйдет на рабочие уровни'Номера каналов АЦП
Channel_adc_0 Alias &B_0100_0000 'Опорное Avcc , 0 канал
Channel_adc_1 Alias &B_0100_0001 'Опорное Avcc , 1 канал
Channel_adc_2 Alias &B_0100_0010 'Опорное Avcc , 2 канал
Channel_adc_3 Alias &B_0100_0011 'Опорное Avcc , 3 канал
Channel_adc_4 Alias &B_0100_0100 'Опорное Avcc , 4 канал
Channel_adc_5 Alias &B_0100_0101 'Опорное Avcc , 5 канал
Channel_adc_6 Alias &B_0100_0110 'Опорное Avcc , 6 канал
Channel_adc_7 Alias &B_0100_0111 'Опорное Avcc , 7 каналDim Count_adc As Byte
Dim Sum_data_adc As Word
Dim Skip_1_measurement As Byte
Dim Flag_data_adc_ready As ByteDim Data_adc_word(8) As Word
'===============================================================================
' Конфигурация Servo
'===============================================================================
Servo_1_port Alias Portb : Servo_1_pin Alias 0
Servo_2_port Alias Portb : Servo_2_pin Alias 1
Servo_3_port Alias Portb : Servo_3_pin Alias 2
Servo_4_port Alias Portb : Servo_4_pin Alias 3
Servo_5_port Alias Portb : Servo_5_pin Alias 4
Servo_6_port Alias Portb : Servo_6_pin Alias 5
Servo_7_port Alias Portd : Servo_7_pin Alias 6
Servo_8_port Alias Portd : Servo_8_pin Alias 7
Servo_9_port Alias Portd : Servo_9_pin Alias 2
Servo_10_port Alias Portd : Servo_10_pin Alias 3
Servo_11_port Alias Portd : Servo_11_pin Alias 4
Servo_12_port Alias Portd : Servo_12_pin Alias 5Config Servo_1_port.servo_1_pin = Output
Config Servo_2_port.servo_2_pin = Output
Config Servo_3_port.servo_3_pin = Output
Config Servo_4_port.servo_4_pin = Output
Config Servo_5_port.servo_5_pin = Output
Config Servo_6_port.servo_6_pin = Output
Config Servo_7_port.servo_7_pin = Output
Config Servo_8_port.servo_8_pin = Output
Config Servo_9_port.servo_9_pin = Output
Config Servo_10_port.servo_10_pin = Output
Config Servo_11_port.servo_11_pin = Output
Config Servo_12_port.servo_12_pin = Output'===============================================================================
'Настройка TIMER0
'===============================================================================
Const Const_time_isr = 8 'Период прерываний в мксConst Const_div_timer0 = 1 'Аппаратный делитель используемого таймера
Const Const_compare0a_isr =((_xtal / 1000000) / Const_div_timer0 * Const_time_isr ) + 0.5
Compare0a = Const_compare0a_isrConfig Timer0 = Counter , Prescale = Const_div_timer0 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
On Compare0a Used_isr_compare0a Nosave
Stop Timer0
Timer0 = 0'---- Эти переменные должны распологаться именно в таком порядке ---------------
Const Amount_servo_channels = 12Dim Count_servo As Word
Dim Data_servo(amount_servo_channels) As ByteDim Flag_ready_data_servo As Byte
Dim Temp_data_servo(amount_servo_channels) As Byte'-------------------------------------------------------------------------------
Dim Word_data_servo(amount_servo_channels) As Word
'-------------- Разрешаем работу необходимых прерываний ----------------------
Adcsra.adif = 1 'Сброс флага прерывания
Adcsra.adsc = 1 'Запуск измерения
Enable Adc 'Разрешение прерываний АЦПStart Timer0
Enable Compare0a'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Flag_data_adc_ready > 0 Then
Word_data_servo(1) = Data_adc_word(1)
Word_data_servo(2) = Data_adc_word(2)
Word_data_servo(3) = Data_adc_word(3)
Word_data_servo(4) = Data_adc_word(4)
Word_data_servo(5) = Data_adc_word(5)
Word_data_servo(6) = Data_adc_word(6)
Word_data_servo(7) = Data_adc_word(7)
Word_data_servo(8) = Data_adc_word(8)Shift Word_data_servo(1) , Right , 2
Shift Word_data_servo(2) , Right , 2
Shift Word_data_servo(3) , Right , 2
Shift Word_data_servo(4) , Right , 2
Shift Word_data_servo(5) , Right , 2
Shift Word_data_servo(6) , Right , 2
Shift Word_data_servo(7) , Right , 2
Shift Word_data_servo(8) , Right , 2Temp_data_servo(1) = Word_data_servo(1)
Temp_data_servo(2) = Word_data_servo(2)
Temp_data_servo(3) = Word_data_servo(3)
Temp_data_servo(4) = Word_data_servo(4)
Temp_data_servo(5) = Word_data_servo(5)
Temp_data_servo(6) = Word_data_servo(6)
Temp_data_servo(7) = Word_data_servo(7)
Temp_data_servo(8) = Word_data_servo(8)Temp_data_servo(9) = Word_data_servo(1)
Temp_data_servo(10) = Word_data_servo(2)
Temp_data_servo(11) = Word_data_servo(3)
Temp_data_servo(12) = Word_data_servo(4)Flag_ready_data_servo = 1
Flag_data_adc_ready = 0
Goto Главный_цикл
End If' Power Idle ' Отправляем МК на тихий час
'===============================================================================
Goto Главный_цикл
End
'===============================================================================
' П О Д К Л Ю Ч Е Н И Е Р А Б О Ч И Х М О Д У Л Е Й
'==============================================================================='===============================================================================
Used_isr_compare0a:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R26
!push R27
!push R30
!push R31Loadadr Count_servo , X
!ld R30 , X+
!ld R31 , X
!adiw R30 , 1 'Сложить константу и слово
!st X , R31
!st -X , R30!clr R16
!cpi R30 , 1
!cpc R31 , R16
!brne Used_isr_compare0a_0 'Перейти если не равно!sbi Servo_1_port , Servo_1_pin
!sbi Servo_2_port , Servo_2_pin
!sbi Servo_3_port , Servo_3_pin
!sbi Servo_4_port , Servo_4_pin
!sbi Servo_5_port , Servo_5_pin
!sbi Servo_6_port , Servo_6_pin
!sbi Servo_7_port , Servo_7_pin
!sbi Servo_8_port , Servo_8_pin
!sbi Servo_9_port , Servo_9_pin
!sbi Servo_10_port , Servo_10_pin
!sbi Servo_11_port , Servo_11_pin
!sbi Servo_12_port , Servo_12_pin!lds R16 , {Flag_ready_data_servo}
!tst R16
!BRNE Reload_data_servo 'Перейти если не равно
!rjmp Exit_isr_compare0aReload_data_servo:
Loadadr Temp_data_servo(1) , X
Loadadr Data_servo(1) , Z!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z , R16!clr R16
!sts {Flag_ready_data_servo} , R16
!rjmp Exit_isr_compare0aUsed_isr_compare0a_0:
!cpi R31 , 0
!breq Used_isr_compare0a_1!ldi R16 , 7
!cpc R31 , R16
!brcs Exit_isr_compare0a!clr R16
!st X+ , R16
!st X , R16!rjmp Exit_isr_compare0a
Used_isr_compare0a_1:
!adiw R26 , 2 'Сложить константу и словоUsed_servo_1:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_2
!cbi Servo_1_port , Servo_1_pinUsed_servo_2:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_3
!cbi Servo_2_port , Servo_2_pinUsed_servo_3:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_4
!cbi Servo_3_port , Servo_3_pinUsed_servo_4:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_5
!cbi Servo_4_port , Servo_4_pinUsed_servo_5:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_6
!cbi Servo_5_port , Servo_5_pinUsed_servo_6:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_7
!cbi Servo_6_port , Servo_6_pinUsed_servo_7:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_8
!cbi Servo_7_port , Servo_7_pinUsed_servo_8:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_9
!cbi Servo_8_port , Servo_8_pinUsed_servo_9:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_10
!cbi Servo_9_port , Servo_9_pinUsed_servo_10:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_11
!cbi Servo_10_port , Servo_10_pinUsed_servo_11:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_12
!cbi Servo_11_port , Servo_11_pinUsed_servo_12:
!ld R31 , X+
!cp R30 , R31
!brcs Exit_isr_compare0a
!cbi Servo_12_port , Servo_12_pinExit_isr_compare0a:
!pop R31
!pop R30
!pop R27
!pop R26
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Interrupt_processing_adc_1:
'-------------------------------------------------------------------------------
!clr R26
!sts {Skip_1_measurement} , R26
!rjmp Start_measurement_adc
'===============================================================================
Interrupt_processing_adc:
'-------------------------------------------------------------------------------
'!!! ВНИМАНИЕ !!!
!sei 'Разрешаем прерывания в прерывании
'!!! ВНИМАНИЕ !!!'Сохраняем регистры
'Т.к., используются логические операции, обязательно сохраняем SREG
!push R26
!in R26 , sreg
!push R26
!push R27'Если сменили канал, пропускаем первое измерение
!lds R26 , {Skip_1_measurement}
!tst R26
!brne Interrupt_processing_adc_1'Набираем сумму из 16 измерений, для усреднения показаний
!lds R26 , {Sum_data_adc}
!in R27 , adcl
!add R26 , R27
!sts {Sum_data_adc} , R26!lds R26 , {Sum_data_adc + 1}
!in R27 , adch
!adc R26 , R27
!sts {Sum_data_adc + 1} , R26'Считаем количество измерений
!lds R26 , {count_adc}
!inc R26
!sts {count_adc} , R26
'Если набрали 16 измерения
!cpi R26 , 16
!BREQ Mean
!rjmp Start_measurement_adc'Усреднение из 16 измерений
Mean:
!push R16
!push R17
!Push R30
!Push R31!ldi R30 , 4
!lds R26 , {Sum_data_adc}
!lds R27 , {Sum_data_adc + 1}
'Сдвиг вправо на 4 бита, или деление на 16
More_shift:
!lsr R27
!ror R26
!dec R30
!brne More_shift'Читаем текущий номер канала АЦП
!lds R16 , admux
!andi R16 , &B_0001_1111'13 тактов МК, самый быстрый вариант (аналог Goto Переменная Label)
!clr R17
!ldi R30 , low(_Save_data_adc_0)
!ldi R31 , high(_Save_data_adc_0)
!add R30 , R16
!adc R31 , R17
!ijmp_save_data_adc_0:
!rjmp Save_data_adc_0
_save_data_adc_1:
!rjmp Save_data_adc_1
_save_data_adc_2:
!rjmp Save_data_adc_2
_save_data_adc_3:
!rjmp Save_data_adc_3
_save_data_adc_4:
!rjmp Save_data_adc_4
_save_data_adc_5:
!rjmp Save_data_adc_5
_save_data_adc_6:
!rjmp Save_data_adc_6
_save_data_adc_7:
!rjmp Save_data_adc_7!ldi R30 , Channel_adc_0
!rjmp Change_channel_adcSave_data_adc_0:
!sts {Data_adc_word(1)} , R26
!sts {Data_adc_word(1) + 1} , R27
!ldi R30 , Channel_adc_1
!rjmp Change_channel_adcSave_data_adc_1:
!sts {Data_adc_word(2)} , R26
!sts {Data_adc_word(2) + 1} , R27
!ldi R30 , Channel_adc_2
!rjmp Change_channel_adcSave_data_adc_2:
!sts {Data_adc_word(3)} , R26
!sts {Data_adc_word(3) + 1} , R27
!ldi R30 , Channel_adc_3
!rjmp Change_channel_adcSave_data_adc_3:
!sts {Data_adc_word(4)} , R26
!sts {Data_adc_word(4) + 1} , R27
!ldi R30 , Channel_adc_4
!rjmp Change_channel_adcSave_data_adc_4:
!sts {Data_adc_word(5)} , R26
!sts {Data_adc_word(5) + 1} , R27
!ldi R30 , Channel_adc_5
!rjmp Change_channel_adcSave_data_adc_5:
!sts {Data_adc_word(6)} , R26
!sts {Data_adc_word(6) + 1} , R27
!ldi R30 , Channel_adc_6
!rjmp Change_channel_adcSave_data_adc_6:
!sts {Data_adc_word(7)} , R26
!sts {Data_adc_word(7) + 1} , R27
!ldi R30 , Channel_adc_7
!rjmp Change_channel_adcSave_data_adc_7:
!sts {Data_adc_word(8)} , R26
!sts {Data_adc_word(8) + 1} , R27
!ldi R30 , Channel_adc_0!ldi R26 , 1
!sts {Flag_data_adc_ready} , R26
'!rjmp Change_channel_adc'Переключаем канал АЦП
Change_channel_adc:
!sts admux , R30!pop R31
!pop R30
!pop R17
!pop R16'Обнуляем переменные для следующего измерения
!ldi R26 , 0
!ldi R27 , 1
!sts {Count_adc} , R26
!sts {Sum_data_adc} , R26
!sts {Sum_data_adc + 1} , R26
'Подымаем флаг смены канала, что бы пропустить первое измерение
!sts {Skip_1_measurement} , R27'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
Start_measurement_adc:
!lds R26 , ADCSRA
!ori R26 , &B_0100_0000
!sts ADCSRA , R26'Восстанавливаем регистры и SREG
Exit_interrupt_adc:
!pop R27
!pop R26
!out sreg , R26
!pop R26!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
16 каналов разделённые на 2 прерывания compare0a и compare0b
$map
$regfile = "m2561def.dat"
$crystal = 18432000
$framesize = 128
$hwstack = 128
$swstack = 128'===============================================================================
' Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (8 МГц / 128 = 62 500)
Config Adc = Single , Prescaler = 128 , Reference = Avcc'Ссылка на подпрограмму обработчика прерывания АЦП
On Adc Interrupt_processing_adc NosaveAdcsra.aden = 1 'Включаем АЦП
Waitms 10 'Ждём когда всё запустится и выйдет на рабочие уровни'Номера каналов АЦП
Channel_adc_0 Alias &B_0100_0000 'Опорное Avcc , 0 канал
Channel_adc_1 Alias &B_0100_0001 'Опорное Avcc , 1 канал
Channel_adc_2 Alias &B_0100_0010 'Опорное Avcc , 2 канал
Channel_adc_3 Alias &B_0100_0011 'Опорное Avcc , 3 канал
Channel_adc_4 Alias &B_0100_0100 'Опорное Avcc , 4 канал
Channel_adc_5 Alias &B_0100_0101 'Опорное Avcc , 5 канал
Channel_adc_6 Alias &B_0100_0110 'Опорное Avcc , 6 канал
Channel_adc_7 Alias &B_0100_0111 'Опорное Avcc , 7 каналDim Count_adc As Byte
Dim Sum_data_adc As Word
Dim Skip_1_measurement As Byte
Dim Flag_data_adc_ready As ByteDim Data_adc_word(8) As Word
'===============================================================================
' Конфигурация Servo
'===============================================================================
Servo_1_port Alias Portb : Servo_1_pin Alias 0
Servo_2_port Alias Portb : Servo_2_pin Alias 1
Servo_3_port Alias Portb : Servo_3_pin Alias 2
Servo_4_port Alias Portb : Servo_4_pin Alias 3
Servo_5_port Alias Portb : Servo_5_pin Alias 4
Servo_6_port Alias Portb : Servo_6_pin Alias 5
Servo_7_port Alias Portb : Servo_7_pin Alias 6
Servo_8_port Alias Portb : Servo_8_pin Alias 7
Servo_9_port Alias Porte : Servo_9_pin Alias 0
Servo_10_port Alias Porte : Servo_10_pin Alias 1
Servo_11_port Alias Porte : Servo_11_pin Alias 2
Servo_12_port Alias Porte : Servo_12_pin Alias 3
Servo_13_port Alias Porte : Servo_13_pin Alias 4
Servo_14_port Alias Porte : Servo_14_pin Alias 5
Servo_15_port Alias Porte : Servo_15_pin Alias 6
Servo_16_port Alias Porte : Servo_16_pin Alias 7Config Servo_1_port.servo_1_pin = Output
Config Servo_2_port.servo_2_pin = Output
Config Servo_3_port.servo_3_pin = Output
Config Servo_4_port.servo_4_pin = Output
Config Servo_5_port.servo_5_pin = Output
Config Servo_6_port.servo_6_pin = Output
Config Servo_7_port.servo_7_pin = Output
Config Servo_8_port.servo_8_pin = Output
Config Servo_9_port.servo_9_pin = Output
Config Servo_10_port.servo_10_pin = Output
Config Servo_11_port.servo_11_pin = Output
Config Servo_12_port.servo_12_pin = Output
Config Servo_13_port.servo_13_pin = Output
Config Servo_14_port.servo_14_pin = Output
Config Servo_15_port.servo_15_pin = Output
Config Servo_16_port.servo_16_pin = Output'===============================================================================
'Настройка TIMER0
'===============================================================================
Const Const_time_compare0a_isr = 10 'Период прерываний в мкс
Const Const_time_compare0b_isr = 10 'Период прерываний в мксConst Const_div_timer0 = 1 'Аппаратный делитель используемого таймера
Const Const_compare0a_isr =((_xtal / 1000000) / Const_div_timer0 * Const_time_compare0a_isr ) + 0.5
Ocr0a = Const_compare0a_isrConst Const_compare0b_isr =((_xtal / 1000000) / Const_div_timer0 * Const_time_compare0b_isr ) + 0.5
Ocr0b = Const_compare0b_isrConfig Timer0 = Counter , Prescale = Const_div_timer0 , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
On Compare0a Used_isr_compare0a Nosave
On Compare0b Used_isr_compare0b NosaveStop Timer0
Timer0 = 0'---- Эти переменные должны распологаться именно в таком порядке ---------------
Const Amount_servo_1_channels = 8
Const Amount_servo_2_channels = 8Dim Count_servo_1 As Word
Dim Data_servo_1(amount_servo_1_channels) As ByteDim Count_servo_2 As Word
Dim Data_servo_2(amount_servo_2_channels) As Byte'-------------------------------------------------------------------------------
Dim Flag_ready_data_servo_1 As Byte
Dim Temp_data_servo_1(amount_servo_1_channels) As ByteDim Flag_ready_data_servo_2 As Byte
Dim Temp_data_servo_2(amount_servo_2_channels) As ByteDim Word_data_servo(12) As Word
'-------------- Разрешаем работу необходимых прерываний ----------------------
Adcsra.adif = 1 'Сброс флага прерывания
Adcsra.adsc = 1 'Запуск измерения
Enable Adc 'Разрешение прерываний АЦПStart Timer0
Enable Compare0a
Enable Compare0b'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'===============================================================================' Г Л А В Н Ы Й Ц И К Л
Главный_цикл:
'===============================================================================If Flag_data_adc_ready > 0 Then
Word_data_servo(1) = Data_adc_word(1)
Word_data_servo(2) = Data_adc_word(2)
Word_data_servo(3) = Data_adc_word(3)
Word_data_servo(4) = Data_adc_word(4)
Word_data_servo(5) = Data_adc_word(5)
Word_data_servo(6) = Data_adc_word(6)
Word_data_servo(7) = Data_adc_word(7)
Word_data_servo(8) = Data_adc_word(8)Shift Word_data_servo(1) , Right , 2
Shift Word_data_servo(2) , Right , 2
Shift Word_data_servo(3) , Right , 2
Shift Word_data_servo(4) , Right , 2
Shift Word_data_servo(5) , Right , 2
Shift Word_data_servo(6) , Right , 2
Shift Word_data_servo(7) , Right , 2
Shift Word_data_servo(8) , Right , 2Temp_data_servo_1(1) = Word_data_servo(1)
Temp_data_servo_1(2) = Word_data_servo(2)
Temp_data_servo_1(3) = Word_data_servo(3)
Temp_data_servo_1(4) = Word_data_servo(4)
Temp_data_servo_1(5) = Word_data_servo(5)
Temp_data_servo_1(6) = Word_data_servo(6)
Temp_data_servo_1(7) = Word_data_servo(7)
Temp_data_servo_1(8) = Word_data_servo(8)Temp_data_servo_2(1) = Word_data_servo(1)
Temp_data_servo_2(2) = Word_data_servo(2)
Temp_data_servo_2(3) = Word_data_servo(3)
Temp_data_servo_2(4) = Word_data_servo(4)
Temp_data_servo_2(5) = Word_data_servo(5)
Temp_data_servo_2(6) = Word_data_servo(6)
Temp_data_servo_2(7) = Word_data_servo(7)
Temp_data_servo_2(8) = Word_data_servo(8)Flag_ready_data_servo_1 = 1
Flag_ready_data_servo_2 = 1
Flag_data_adc_ready = 0
Goto Главный_цикл
End If' Power Idle ' Отправляем МК на тихий час
'===============================================================================
Goto Главный_цикл
End
'===============================================================================
' П О Д К Л Ю Ч Е Н И Е Р А Б О Ч И Х М О Д У Л Е Й
'===============================================================================' ===============================================================================
Used_isr_compare0b:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R26
!push R27
!push R30
!push R31Loadadr Count_servo_2 , X
!ld R30 , X+
!ld R31 , X
!adiw R30 , 1 'Сложить константу и слово
!st X , R31
!st -X , R30!clr R16
!cpi R30 , 1
!cpc R31 , R16
!brne Used_isr_compare0b_0 'Перейти если не равно!sbi Servo_9_port , Servo_9_pin
!sbi Servo_10_port , Servo_10_pin
!sbi Servo_11_port , Servo_11_pin
!sbi Servo_12_port , Servo_12_pin
!sbi Servo_13_port , Servo_13_pin
!sbi Servo_14_port , Servo_14_pin
!sbi Servo_15_port , Servo_15_pin
!sbi Servo_16_port , Servo_16_pin!lds R16 , {Flag_ready_data_servo_2}
!tst R16
!BRNE Reload_data_servo_2 'Перейти если не равно
!jmp Exit_isr_compare0bReload_data_servo_2:
Loadadr Temp_data_servo_2(1) , X
Loadadr Data_servo_2(1) , Z!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z , R16!clr R16
!sts {Flag_ready_data_servo_2} , R16
!rjmp Exit_isr_compare0bUsed_isr_compare0b_0:
!cpi R31 , 0
!breq Used_isr_compare0b_1!ldi R16 , 7
!cpc R31 , R16
!brcs Exit_isr_compare0b!clr R16
!st X+ , R16
!st X , R16!rjmp Exit_isr_compare0b
Used_isr_compare0b_1:
!adiw R26 , 2 'Сложить константу и словоUsed_servo_1_9:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_10
!cbi Servo_9_port , Servo_9_pinUsed_servo_1_10:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_11
!cbi Servo_10_port , Servo_10_pinUsed_servo_1_11:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_12
!cbi Servo_11_port , Servo_11_pinUsed_servo_1_12:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_13
!cbi Servo_12_port , Servo_12_pinUsed_servo_1_13:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_14
!cbi Servo_13_port , Servo_13_pinUsed_servo_1_14:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_15
!cbi Servo_14_port , Servo_14_pinUsed_servo_1_15:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_16
!cbi Servo_15_port , Servo_15_pinUsed_servo_1_16:
!ld R31 , X+
!cp R30 , R31
!brcs Exit_isr_compare0b
!cbi Servo_16_port , Servo_16_pinExit_isr_compare0b:
!pop R31
!pop R30
!pop R27
!pop R26
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================' ===============================================================================
Used_isr_compare0a:
'-------------------------------------------------------------------------------
!push R16
!in R16 , sreg
!push R16
!push R26
!push R27
!push R30
!push R31Loadadr Count_servo_1 , X
!ld R30 , X+
!ld R31 , X
!adiw R30 , 1 'Сложить константу и слово
!st X , R31
!st -X , R30!clr R16
!cpi R30 , 1
!cpc R31 , R16
!brne Used_isr_compare0a_0 'Перейти если не равно!sbi Servo_1_port , Servo_1_pin
!sbi Servo_2_port , Servo_2_pin
!sbi Servo_3_port , Servo_3_pin
!sbi Servo_4_port , Servo_4_pin
!sbi Servo_5_port , Servo_5_pin
!sbi Servo_6_port , Servo_6_pin
!sbi Servo_7_port , Servo_7_pin
!sbi Servo_8_port , Servo_8_pin!lds R16 , {Flag_ready_data_servo_1}
!tst R16
!BRNE Reload_data_servo_1 'Перейти если не равно
!jmp Exit_isr_compare0aReload_data_servo_1:
Loadadr Temp_data_servo_1(1) , X
Loadadr Data_servo_1(1) , Z!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z+ , R16
!ld R16 , X+
!st Z , R16!clr R16
!sts {Flag_ready_data_servo_1} , R16
!rjmp Exit_isr_compare0aUsed_isr_compare0a_0:
!cpi R31 , 0
!breq Used_isr_compare0a_1!ldi R16 , 7
!cpc R31 , R16
!brcs Exit_isr_compare0a!clr R16
!st X+ , R16
!st X , R16!rjmp Exit_isr_compare0a
Used_isr_compare0a_1:
!adiw R26 , 2 'Сложить константу и словоUsed_servo_1_1:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_2
!cbi Servo_1_port , Servo_1_pinUsed_servo_1_2:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_3
!cbi Servo_2_port , Servo_2_pinUsed_servo_1_3:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_4
!cbi Servo_3_port , Servo_3_pinUsed_servo_1_4:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_5
!cbi Servo_4_port , Servo_4_pinUsed_servo_1_5:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_6
!cbi Servo_5_port , Servo_5_pinUsed_servo_1_6:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_7
!cbi Servo_6_port , Servo_6_pinUsed_servo_1_7:
!ld R31 , X+
!cp R30 , R31
!brcs Used_servo_1_8
!cbi Servo_7_port , Servo_7_pinUsed_servo_1_8:
!ld R31 , X+
!cp R30 , R31
!brcs Exit_isr_compare0a
!cbi Servo_8_port , Servo_8_pinExit_isr_compare0a:
!pop R31
!pop R30
!pop R27
!pop R26
!pop R16
!out sreg , R16
!pop R16!reti
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Interrupt_processing_adc_1:
'-------------------------------------------------------------------------------
!clr R26
!sts {Skip_1_measurement} , R26
!rjmp Start_measurement_adc
'===============================================================================
Interrupt_processing_adc:
'-------------------------------------------------------------------------------
'!!! ВНИМАНИЕ !!!
!sei 'Разрешаем прерывания в прерывании
'!!! ВНИМАНИЕ !!!'Сохраняем регистры
'Т.к., используются логические операции, обязательно сохраняем SREG
!push R26
!in R26 , sreg
!push R26
!push R27'Если сменили канал, пропускаем первое измерение
!lds R26 , {Skip_1_measurement}
!tst R26
!brne Interrupt_processing_adc_1'Набираем сумму из 16 измерений, для усреднения показаний
!lds R26 , {Sum_data_adc}
!in R27 , adcl
!add R26 , R27
!sts {Sum_data_adc} , R26!lds R26 , {Sum_data_adc + 1}
!in R27 , adch
!adc R26 , R27
!sts {Sum_data_adc + 1} , R26'Считаем количество измерений
!lds R26 , {count_adc}
!inc R26
!sts {count_adc} , R26
'Если набрали 16 измерения
!cpi R26 , 16
!BREQ Mean
!rjmp Start_measurement_adc'Усреднение из 16 измерений
Mean:
!push R16
!push R17
!Push R30
!Push R31!ldi R30 , 4
!lds R26 , {Sum_data_adc}
!lds R27 , {Sum_data_adc + 1}
'Сдвиг вправо на 4 бита, или деление на 16
More_shift:
!lsr R27
!ror R26
!dec R30
!brne More_shift'Читаем текущий номер канала АЦП
!lds R16 , admux
!andi R16 , &B_0001_1111'13 тактов МК, самый быстрый вариант (аналог Goto Переменная Label)
!clr R17
!ldi R30 , low(_Save_data_adc_0)
!ldi R31 , high(_Save_data_adc_0)
!add R30 , R16
!adc R31 , R17
!ijmp_save_data_adc_0:
!rjmp Save_data_adc_0
_save_data_adc_1:
!rjmp Save_data_adc_1
_save_data_adc_2:
!rjmp Save_data_adc_2
_save_data_adc_3:
!rjmp Save_data_adc_3
_save_data_adc_4:
!rjmp Save_data_adc_4
_save_data_adc_5:
!rjmp Save_data_adc_5
_save_data_adc_6:
!rjmp Save_data_adc_6
_save_data_adc_7:
!rjmp Save_data_adc_7!ldi R30 , Channel_adc_0
!rjmp Change_channel_adcSave_data_adc_0:
!sts {Data_adc_word(1)} , R26
!sts {Data_adc_word(1) + 1} , R27
!ldi R30 , Channel_adc_1
!rjmp Change_channel_adcSave_data_adc_1:
!sts {Data_adc_word(2)} , R26
!sts {Data_adc_word(2) + 1} , R27
!ldi R30 , Channel_adc_2
!rjmp Change_channel_adcSave_data_adc_2:
!sts {Data_adc_word(3)} , R26
!sts {Data_adc_word(3) + 1} , R27
!ldi R30 , Channel_adc_3
!rjmp Change_channel_adcSave_data_adc_3:
!sts {Data_adc_word(4)} , R26
!sts {Data_adc_word(4) + 1} , R27
!ldi R30 , Channel_adc_4
!rjmp Change_channel_adcSave_data_adc_4:
!sts {Data_adc_word(5)} , R26
!sts {Data_adc_word(5) + 1} , R27
!ldi R30 , Channel_adc_5
!rjmp Change_channel_adcSave_data_adc_5:
!sts {Data_adc_word(6)} , R26
!sts {Data_adc_word(6) + 1} , R27
!ldi R30 , Channel_adc_6
!rjmp Change_channel_adcSave_data_adc_6:
!sts {Data_adc_word(7)} , R26
!sts {Data_adc_word(7) + 1} , R27
!ldi R30 , Channel_adc_7
!rjmp Change_channel_adcSave_data_adc_7:
!sts {Data_adc_word(8)} , R26
!sts {Data_adc_word(8) + 1} , R27
!ldi R30 , Channel_adc_0!ldi R26 , 1
!sts {Flag_data_adc_ready} , R26
'!rjmp Change_channel_adc'Переключаем канал АЦП
Change_channel_adc:
!sts admux , R30!pop R31
!pop R30
!pop R17
!pop R16'Обнуляем переменные для следующего измерения
!ldi R26 , 0
!ldi R27 , 1
!sts {Count_adc} , R26
!sts {Sum_data_adc} , R26
!sts {Sum_data_adc + 1} , R26
'Подымаем флаг смены канала, что бы пропустить первое измерение
!sts {Skip_1_measurement} , R27'Запускаем следующее измерение, режиму "Free" нужен спящий режим "Idle" или "Power Adcnoise"
Start_measurement_adc:
!lds R26 , ADCSRA
!ori R26 , &B_0100_0000
!sts ADCSRA , R26'Восстанавливаем регистры и SREG
Exit_interrupt_adc:
!pop R27
!pop R26
!out sreg , R26
!pop R26!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование PPM кодировки