Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование PPM кодировки


Исследование PPM кодировки

Сообщений 1 страница 4 из 4

1

Исследование PPM кодировки

К сожалению, яндекс диск заглючил, залить всё не получается. Кому надо, пишите, закину на мыло.

0

2

Для пробы залил на Google диск, симуляция (можно покрутить и посмотреть)   -  скачать

Исходник силами Bascom

$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 Nosave

  Adcsra.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 Byte

  Dim 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 = 10

  Config 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 = Output

  Dim 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 , 2

          Servo(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_adc

   Save_data_adc_0:
    !sts {Data_adc_word(1)} , R26
    !sts {Data_adc_word(1) + 1} , R27
    !ldi R30 , Channel_adc_1
    !rjmp Change_channel_adc

   Save_data_adc_1:
    !sts {Data_adc_word(2)} , R26
    !sts {Data_adc_word(2) + 1} , R27
    !ldi R30 , Channel_adc_2
    !rjmp Change_channel_adc

   Save_data_adc_2:
    !sts {Data_adc_word(3)} , R26
    !sts {Data_adc_word(3) + 1} , R27
    !ldi R30 , Channel_adc_3
    !rjmp Change_channel_adc

   Save_data_adc_3:
    !sts {Data_adc_word(4)} , R26
    !sts {Data_adc_word(4) + 1} , R27
    !ldi R30 , Channel_adc_4
    !rjmp Change_channel_adc

   Save_data_adc_4:
    !sts {Data_adc_word(5)} , R26
    !sts {Data_adc_word(5) + 1} , R27
    !ldi R30 , Channel_adc_5
    !rjmp Change_channel_adc

   Save_data_adc_5:
    !sts {Data_adc_word(6)} , R26
    !sts {Data_adc_word(6) + 1} , R27
    !ldi R30 , Channel_adc_6
    !rjmp Change_channel_adc

   Save_data_adc_6:
    !sts {Data_adc_word(7)} , R26
    !sts {Data_adc_word(7) + 1} , R27
    !ldi R30 , Channel_adc_7
    !rjmp Change_channel_adc

   Save_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
'===============================================================================

Исходник на ASM

'!!!   ВНИМАНИЕ   !!!
  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 Nosave

  Adcsra.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 Byte

  Dim 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

  Config 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_isr

  Config 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 Byte

  Dim 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 , 2

          Temp_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 R31

    Loadadr 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_compare0a

   Reload_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_compare0a

   Used_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_pin

   Used_servo_2:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_3
    !cbi Servo_2_port , Servo_2_pin

   Used_servo_3:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_4
    !cbi Servo_3_port , Servo_3_pin

   Used_servo_4:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_5
    !cbi Servo_4_port , Servo_4_pin

   Used_servo_5:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_6
    !cbi Servo_5_port , Servo_5_pin

   Used_servo_6:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_7
    !cbi Servo_6_port , Servo_6_pin

   Used_servo_7:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_8
    !cbi Servo_7_port , Servo_7_pin

   Used_servo_8:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Exit_isr_compare0a
    !cbi Servo_8_port , Servo_8_pin

   Exit_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_adc

   Save_data_adc_0:
    !sts {Data_adc_word(1)} , R26
    !sts {Data_adc_word(1) + 1} , R27
    !ldi R30 , Channel_adc_1
    !rjmp Change_channel_adc

   Save_data_adc_1:
    !sts {Data_adc_word(2)} , R26
    !sts {Data_adc_word(2) + 1} , R27
    !ldi R30 , Channel_adc_2
    !rjmp Change_channel_adc

   Save_data_adc_2:
    !sts {Data_adc_word(3)} , R26
    !sts {Data_adc_word(3) + 1} , R27
    !ldi R30 , Channel_adc_3
    !rjmp Change_channel_adc

   Save_data_adc_3:
    !sts {Data_adc_word(4)} , R26
    !sts {Data_adc_word(4) + 1} , R27
    !ldi R30 , Channel_adc_4
    !rjmp Change_channel_adc

   Save_data_adc_4:
    !sts {Data_adc_word(5)} , R26
    !sts {Data_adc_word(5) + 1} , R27
    !ldi R30 , Channel_adc_5
    !rjmp Change_channel_adc

   Save_data_adc_5:
    !sts {Data_adc_word(6)} , R26
    !sts {Data_adc_word(6) + 1} , R27
    !ldi R30 , Channel_adc_6
    !rjmp Change_channel_adc

   Save_data_adc_6:
    !sts {Data_adc_word(7)} , R26
    !sts {Data_adc_word(7) + 1} , R27
    !ldi R30 , Channel_adc_7
    !rjmp Change_channel_adc

   Save_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
'===============================================================================

http://sd.uploads.ru/t/r4KbF.jpg

0

3

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 Nosave

  Adcsra.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 Byte

  Dim 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 5

  Config 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_isr

  Config 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 = 12

  Dim Count_servo As Word
  Dim Data_servo(amount_servo_channels) As Byte

  Dim 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 , 2

          Temp_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 R31

    Loadadr 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_compare0a

   Reload_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_compare0a

   Used_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_pin

   Used_servo_2:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_3
    !cbi Servo_2_port , Servo_2_pin

   Used_servo_3:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_4
    !cbi Servo_3_port , Servo_3_pin

   Used_servo_4:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_5
    !cbi Servo_4_port , Servo_4_pin

   Used_servo_5:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_6
    !cbi Servo_5_port , Servo_5_pin

   Used_servo_6:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_7
    !cbi Servo_6_port , Servo_6_pin

   Used_servo_7:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_8
    !cbi Servo_7_port , Servo_7_pin

   Used_servo_8:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_9
    !cbi Servo_8_port , Servo_8_pin

   Used_servo_9:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_10
    !cbi Servo_9_port , Servo_9_pin

   Used_servo_10:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_11
    !cbi Servo_10_port , Servo_10_pin

   Used_servo_11:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_12
    !cbi Servo_11_port , Servo_11_pin

   Used_servo_12:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Exit_isr_compare0a
    !cbi Servo_12_port , Servo_12_pin

   Exit_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_adc

   Save_data_adc_0:
    !sts {Data_adc_word(1)} , R26
    !sts {Data_adc_word(1) + 1} , R27
    !ldi R30 , Channel_adc_1
    !rjmp Change_channel_adc

   Save_data_adc_1:
    !sts {Data_adc_word(2)} , R26
    !sts {Data_adc_word(2) + 1} , R27
    !ldi R30 , Channel_adc_2
    !rjmp Change_channel_adc

   Save_data_adc_2:
    !sts {Data_adc_word(3)} , R26
    !sts {Data_adc_word(3) + 1} , R27
    !ldi R30 , Channel_adc_3
    !rjmp Change_channel_adc

   Save_data_adc_3:
    !sts {Data_adc_word(4)} , R26
    !sts {Data_adc_word(4) + 1} , R27
    !ldi R30 , Channel_adc_4
    !rjmp Change_channel_adc

   Save_data_adc_4:
    !sts {Data_adc_word(5)} , R26
    !sts {Data_adc_word(5) + 1} , R27
    !ldi R30 , Channel_adc_5
    !rjmp Change_channel_adc

   Save_data_adc_5:
    !sts {Data_adc_word(6)} , R26
    !sts {Data_adc_word(6) + 1} , R27
    !ldi R30 , Channel_adc_6
    !rjmp Change_channel_adc

   Save_data_adc_6:
    !sts {Data_adc_word(7)} , R26
    !sts {Data_adc_word(7) + 1} , R27
    !ldi R30 , Channel_adc_7
    !rjmp Change_channel_adc

   Save_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
'===============================================================================

http://sg.uploads.ru/t/PEk2g.jpg

+2

4

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 Nosave

  Adcsra.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 Byte

  Dim 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 7

  Config 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_isr

  Const Const_compare0b_isr =((_xtal / 1000000) / Const_div_timer0 * Const_time_compare0b_isr ) + 0.5
  Ocr0b = Const_compare0b_isr

  Config 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 Nosave

  Stop Timer0
  Timer0 = 0

'---- Эти переменные должны распологаться именно в таком порядке ---------------
  Const Amount_servo_1_channels = 8
  Const Amount_servo_2_channels = 8

  Dim Count_servo_1 As Word
  Dim Data_servo_1(amount_servo_1_channels) As Byte

  Dim 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 Byte

  Dim Flag_ready_data_servo_2 As Byte
  Dim Temp_data_servo_2(amount_servo_2_channels) As Byte

  Dim 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 , 2

          Temp_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 R31

    Loadadr 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_compare0b

   Reload_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_compare0b

   Used_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_pin

   Used_servo_1_10:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_11
    !cbi Servo_10_port , Servo_10_pin

   Used_servo_1_11:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_12
    !cbi Servo_11_port , Servo_11_pin

   Used_servo_1_12:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_13
    !cbi Servo_12_port , Servo_12_pin

   Used_servo_1_13:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_14
    !cbi Servo_13_port , Servo_13_pin

   Used_servo_1_14:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_15
    !cbi Servo_14_port , Servo_14_pin

   Used_servo_1_15:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_16
    !cbi Servo_15_port , Servo_15_pin

   Used_servo_1_16:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Exit_isr_compare0b
    !cbi Servo_16_port , Servo_16_pin

   Exit_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 R31

    Loadadr 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_compare0a

   Reload_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_compare0a

   Used_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_pin

   Used_servo_1_2:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_3
    !cbi Servo_2_port , Servo_2_pin

   Used_servo_1_3:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_4
    !cbi Servo_3_port , Servo_3_pin

   Used_servo_1_4:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_5
    !cbi Servo_4_port , Servo_4_pin

   Used_servo_1_5:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_6
    !cbi Servo_5_port , Servo_5_pin

   Used_servo_1_6:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_7
    !cbi Servo_6_port , Servo_6_pin

   Used_servo_1_7:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Used_servo_1_8
    !cbi Servo_7_port , Servo_7_pin

   Used_servo_1_8:
    !ld R31 , X+
    !cp R30 , R31
    !brcs Exit_isr_compare0a
    !cbi Servo_8_port , Servo_8_pin

   Exit_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_adc

   Save_data_adc_0:
    !sts {Data_adc_word(1)} , R26
    !sts {Data_adc_word(1) + 1} , R27
    !ldi R30 , Channel_adc_1
    !rjmp Change_channel_adc

   Save_data_adc_1:
    !sts {Data_adc_word(2)} , R26
    !sts {Data_adc_word(2) + 1} , R27
    !ldi R30 , Channel_adc_2
    !rjmp Change_channel_adc

   Save_data_adc_2:
    !sts {Data_adc_word(3)} , R26
    !sts {Data_adc_word(3) + 1} , R27
    !ldi R30 , Channel_adc_3
    !rjmp Change_channel_adc

   Save_data_adc_3:
    !sts {Data_adc_word(4)} , R26
    !sts {Data_adc_word(4) + 1} , R27
    !ldi R30 , Channel_adc_4
    !rjmp Change_channel_adc

   Save_data_adc_4:
    !sts {Data_adc_word(5)} , R26
    !sts {Data_adc_word(5) + 1} , R27
    !ldi R30 , Channel_adc_5
    !rjmp Change_channel_adc

   Save_data_adc_5:
    !sts {Data_adc_word(6)} , R26
    !sts {Data_adc_word(6) + 1} , R27
    !ldi R30 , Channel_adc_6
    !rjmp Change_channel_adc

   Save_data_adc_6:
    !sts {Data_adc_word(7)} , R26
    !sts {Data_adc_word(7) + 1} , R27
    !ldi R30 , Channel_adc_7
    !rjmp Change_channel_adc

   Save_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
'===============================================================================

http://s5.uploads.ru/t/Y4PlZ.jpg

+1


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование PPM кодировки