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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование фазовой регулировки мощности нагрузки в сети 220 вольт


Исследование фазовой регулировки мощности нагрузки в сети 220 вольт

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

1

Исследование фазовой регулировки мощности нагрузки в сети 220 вольт, с помощью МК и симисторов

0

2

За основу взяты статьи:  здесь, здесь и здесь.

Спасибо пользователю этого форума Александру Малышу, ховается за ником - "Skull", за тестирование в железе!!!

Все вопросы по поводу работы в железе, пока к нему.

http://s7.uploads.ru/t/Gcn2U.jpg http://s6.uploads.ru/t/SXTRK.jpg
http://s7.uploads.ru/t/TlZNI.jpg http://s6.uploads.ru/t/zjQ4B.jpg
http://s6.uploads.ru/t/VdqA6.jpg http://s6.uploads.ru/t/u2IMh.jpg
http://s6.uploads.ru/t/zjQ4B.jpg  http://s6.uploads.ru/t/aYNe6.jpg

Симуляция в Протеус 7.10 + исходники (Attiny13A, Attiny45A, Atmega328P)  -  скачать

+2

3

Задача- привести в чувство хлебопекарную печь )
Выглядит где-то так :
http://www.impex.kr.ua/files/product/ovens-rotation-musson-rotor-77e-elektricheskaya.jpg
Вся электроника умерла, даже шлейфы сплавились. Нужно придумать все заново. В данный момент мучаем стабилизацию температуры, а конкретно- управлялку ТЭНами ))


Ну, начнем по железу :
Оборудование для тестов- 3 макетки - 2 меги (16,32) и платка с оптосимистором.
Выглядит вот так (о, ужос)
http://s6.uploads.ru/t/HpPiy.jpg
Схема подключения немного нестандартная для MOC3023 :

http://s7.uploads.ru/t/DbxWj.jpg

Ну, и сам модуль тиристоров в сборе на радиаторе :
http://s7.uploads.ru/t/lTwk9.jpg

Ну, и видео работы всего этого безобразия на экране осциллографа :
http://yadi.sk/d/Y4Snv8v8FqcQA
Кроме телефона снимать нечем, так что как есть...

0

4

В симуляции задейсвован МК Attiny2313A (управляет симистором) + 3 кнопки + озвучка кнопок + USART !

Снимки экрана:

http://s6.uploads.ru/t/C03ah.jpg http://s6.uploads.ru/t/NiS50.jpg

http://s6.uploads.ru/t/0u2Ix.jpg http://s7.uploads.ru/t/yXvqj.jpg

Симуляция "Протеус 7.10" + исходники для Attiny13A; Attiny45A; Attiny2313A; Atmega328P написаны в среде компилятора "Bascom 2.0.7.1"  -  скачать

0

5

Вариант для 1 фазы - здесь

Спасибо пользователю этого форума Александру Малышу, ховается за ником - "Skull", за тестирование в железе!!!

Все вопросы по поводу работы в железе, пока к нему.

Снимки экрана.

http://s6.uploads.ru/t/rJkRv.jpg http://s6.uploads.ru/t/iKqGb.jpg
http://s6.uploads.ru/t/tkz4X.jpg http://s6.uploads.ru/t/cxGh1.jpg
http://s6.uploads.ru/t/Dio0O.jpg http://s6.uploads.ru/t/5vysW.jpg
http://s6.uploads.ru/t/zvfuq.jpg http://s6.uploads.ru/t/aLojJ.jpg
http://s6.uploads.ru/t/upzgO.jpg http://s7.uploads.ru/t/M6rFW.jpg
http://s6.uploads.ru/t/Ees5D.jpg http://s6.uploads.ru/t/S0VYe.jpg
http://s7.uploads.ru/t/jXYb5.jpg http://s7.uploads.ru/t/ExvOz.jpg
http://s6.uploads.ru/t/3bqBw.jpg http://s7.uploads.ru/t/6Sdxy.jpg
http://s6.uploads.ru/t/Hp7De.jpg http://s7.uploads.ru/t/YW2XE.jpg
http://s7.uploads.ru/t/aR92Z.jpg

Симуляция в "Протеус 7.10" + исходники, написаны в среде компилятора "Bascom 2.0.7.1" -  скачать

0

6

По мотивам этой ветки форума.


Исходник написал Аксакал нашего форума Сергей Шилов (MrShilov), БОЛЬШОЕ СПАСИБО, за проявленное участие, больше-бы таких людей !!!


Алгоритм работы:

Кратковременное нажатие "Выключателя" - включается.
Последующее нажатие (не ранее чем через 2 секунды) - выключается.

Два хлопка - включение.
Еще два хлопка через паузу > 2 сек - выключение

Удержание кнопки пульта > 2 секунд - вкл.
Через > 5 сек то же самое - выключение.


Вопреки скепсису некоторых участников форума, Сергею удалось поместить весь алгоритм в козявку Attiny13A, используя 45% памяти МК, при этом не затрагивая вывод "Reset", для возможности последующих манипуляций с МК.


Ниже выложены варианты для МК: Attiny13A; Attiny45A; Attiny85A. Необходима проверка в железе, для корректировки задержек.

Симуляция в Протеус 7.10 + исходники Bascom 2.0.7.1, для всех перечисленных вариантов  -  скачать

Обратите внимание! Работающий МК выбирается в свойствах последнего, путём вкл. / откл. моделирования модели!

http://s8.uploads.ru/t/zgR3l.jpg


Ждём от Тимура проверки в железе, если кто проверит раньше, отпишитесь


Снимки экрана, обратите внимание на отмеченную область!!!
http://s8.uploads.ru/t/Dy7Qj.jpg http://s8.uploads.ru/t/I0MG3.jpg

+1

7

Регулировка мощности нагрузки в сети 220V, методом пропусков периодов.

При окончательном тестировании варианта приведённого здесь, обнаружился большой уровень помех выдаваемых устройством в сеть, при подключении более 1 печи. Было решено воспользоваться другим методом регулирования мощности. 


Схема и прошивка протестированы в реальном железе, с помощью безотказного (в плане что-нибудь спалить...) пользователя этого форума Александра Малыша (Skull)

Для управления тиристорами использована схема от производителя тиристоров (показала лучшие результаты):

http://s9.uploads.ru/t/QNhEp.jpg


Для уменьшения нагрузки на ЦП компьютера и соответственно проведение симуляции в реальном времени, симуляция в Протеусе цифровая, т.е., с помошью цифровых примитивов.

Фрагменты отвечающие за обработку прерываний, написаны в двух вариантах: Bascom и ASM AVR, вариант обработки выбирается константой в начале исходника.

Симуляция (Протеус 7.10) + исходник (Bascom 2.0.7.1) + снимки экрана  -  скачать


http://s8.uploads.ru/t/DL5tj.jpg http://s8.uploads.ru/t/pfTiM.jpg

http://s9.uploads.ru/t/WzUgA.jpg http://s9.uploads.ru/t/Zo8F6.jpg

http://s9.uploads.ru/t/OJnDV.jpg http://s8.uploads.ru/t/OwE60.jpg

http://s8.uploads.ru/t/LZtBS.jpg http://s9.uploads.ru/t/mNAX6.jpg

http://s9.uploads.ru/t/nY7ry.jpg http://s9.uploads.ru/t/wUVtD.jpg

+1

8

Вариант симуляции с изменённой схемой управления тиристорами.

Симуляция (Протеус 7.10) + исходник (Bascom 2.0.7.1)  -  скачать

http://s8.uploads.ru/t/Bw6v3.jpg http://s8.uploads.ru/t/hB3Qy.jpg

+1

9

Вариант фазовой регулировки на прерываниях

Симуляция ( Протеус 7.10 ) + исходник ( Bascom 2.0.7.1 )   -  скачать

http://s9.uploads.ru/t/EpgGP.jpg

+3

10

Софтовый вариант фазовой регулировки на прерываниях

Одним архивом 8 и 16 Мгц, (вариант на Bascom (только 8 каналов, больше не успевает) + вариант на ASM (8 и 16 каналов ) + симуляции):

Скачать с яндекса

Скачать с google

Bascom 8 каналов 8 МГц

'===============================================================================

  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 8000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '39      '40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1
  On Compare0a Isr_compare0a

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от зеро кросс
'===============================================================================
  Config Int0 = Rising

  Config Pind.2 = Input : Portd.2 = 0

  On Int0 Isr_int0

'===============================================================================
'                     Конфигурация АЦП
'===============================================================================
'Одиночные измерения с частотой АЦП = f_МК / Prescaler (8 МГц / 128 = 62 500)
  Config Adc = Single , Prescaler = 128 , Reference = Avcc

  Dim Data_adc_0_word As Word
  Dim Data_adc_1_word As Word
  Dim Data_adc_2_word As Word
  Dim Data_adc_3_word As Word
  Dim Data_adc_4_word As Word
  Dim Data_adc_5_word As Word
  Dim Data_adc_6_word As Word
  Dim Data_adc_7_word As Word

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Angle_on(10) As Byte

  Triac_1 Alias Portb.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Portb.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Portb.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Portb.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Portb.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Portb.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Portb.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Portb.7 : Config Triac_8 = Output : Triac_8 = 0

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare1a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

       Data_adc_0_word = Getadc(0) : Shift Data_adc_0_word , Right , 2 : Angle_on(1) = 255 - Data_adc_0_word
       Data_adc_1_word = Getadc(1) : Shift Data_adc_1_word , Right , 2 : Angle_on(2) = 255 - Data_adc_1_word
       Data_adc_2_word = Getadc(2) : Shift Data_adc_2_word , Right , 2 : Angle_on(3) = 255 - Data_adc_2_word
       Data_adc_3_word = Getadc(3) : Shift Data_adc_3_word , Right , 2 : Angle_on(4) = 255 - Data_adc_3_word
       Data_adc_4_word = Getadc(4) : Shift Data_adc_4_word , Right , 2 : Angle_on(5) = 255 - Data_adc_4_word
       Data_adc_5_word = Getadc(5) : Shift Data_adc_5_word , Right , 2 : Angle_on(6) = 255 - Data_adc_5_word
       Data_adc_6_word = Getadc(6) : Shift Data_adc_6_word , Right , 2 : Angle_on(7) = 255 - Data_adc_6_word
       Data_adc_7_word = Getadc(7) : Shift Data_adc_7_word , Right , 2 : Angle_on(8) = 255 - Data_adc_7_word


'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    Count_zero = 0
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    Incr Count_zero

    If Count_zero > 250 Then
        Count_zero = 250
    End If

    If Count_zero > Angle_on(1) Then
        Triac_1 = 1
      Else
        Triac_1 = 0
    End If

    If Count_zero > Angle_on(2) Then
        Triac_2 = 1
      Else
        Triac_2 = 0
    End If

    If Count_zero > Angle_on(3) Then
        Triac_3 = 1
      Else
        Triac_3 = 0
    End If

    If Count_zero > Angle_on(4) Then
        Triac_4 = 1
      Else
        Triac_4 = 0
    End If

    If Count_zero > Angle_on(5) Then
        Triac_5 = 1
      Else
        Triac_5 = 0
    End If

    If Count_zero > Angle_on(6) Then
        Triac_6 = 1
      Else
        Triac_6 = 0
    End If

    If Count_zero > Angle_on(7) Then
        Triac_7 = 1
      Else
        Triac_7 = 0
    End If

    If Count_zero > Angle_on(8) Then
        Triac_8 = 1
      Else
        Triac_8 = 0
    End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

ASM AVR 8 каналов 8 МГц

'===============================================================================

  $map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 8000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

'===============================================================================
            'Подключенные модули
'===============================================================================

  $include "Config_work USART_0.bas"

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '=39 => 40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

  On Compare0a Isr_compare0a Nosave

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от ZeroCross
'===============================================================================
  Config Int0 = Rising

  Config Pind.2 = Input : Portd.2 = 0

  On Int0 Isr_int0 Nosave

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Angle_on(8) As Byte

  Triac_1 Alias Portb.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Portb.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Portb.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Portb.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Portb.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Portb.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Portb.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Portb.7 : Config Triac_8 = Output : Triac_8 = 0

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================
  Gosub Usart_0_clearing_buffer_receive

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare0a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

      If Usart_0_flag_data_input > 0 Then

          If Left(usart_0_input_buffer_str , 3) = "SET" Then
              Gosub Set_data_angle
          End If

          Gosub Usart_0_clearing_buffer_receive
      End If

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Set_data_angle:
'-------------------------------------------------------------------------------
    Count_split_usart = Split(usart_0_input_buffer_str , Split_usart_str(1) , ",")

    Angle_on(1) = Val(split_usart_str(2))
    Angle_on(2) = Val(split_usart_str(3))
    Angle_on(3) = Val(split_usart_str(4))
    Angle_on(4) = Val(split_usart_str(5))
    Angle_on(5) = Val(split_usart_str(6))
    Angle_on(6) = Val(split_usart_str(7))
    Angle_on(7) = Val(split_usart_str(8))
    Angle_on(8) = Val(split_usart_str(9))
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !clr R16
    !sts {Count_zero} , R16
    !pop R16

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R17
    !push R30
    !push R31

    !lds R17 , {Count_zero}
    !cpi R17 , 250
    !BREQ Not_count_zero       'Перейти если равно
   Count_count_zero:
    !inc R17
    !sts {Count_zero} , R17
   Not_count_zero:

  Next_triac_1:
   Loadadr Angle_on(1) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_1_set       'Перейти если равно или больше
   Triac_1_reset:
    Triac_1 = 0
    !rjmp Next_Triac_2
   Triac_1_set:
    Triac_1 = 1

  Next_triac_2:
   Loadadr Angle_on(2) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_2_set       'Перейти если равно или больше
   Triac_2_reset:
    Triac_2 = 0
    !rjmp Next_Triac_3
   Triac_2_set:
    Triac_2 = 1

  Next_triac_3:
   Loadadr Angle_on(3) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_3_set       'Перейти если равно или больше
   Triac_3_reset:
    Triac_3 = 0
    !rjmp Next_Triac_4
   Triac_3_set:
    Triac_3 = 1

  Next_triac_4:
   Loadadr Angle_on(4) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_4_set       'Перейти если равно или больше
   Triac_4_reset:
    Triac_4 = 0
    !rjmp Next_Triac_5
   Triac_4_set:
    Triac_4 = 1

  Next_triac_5:
   Loadadr Angle_on(5) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_5_set       'Перейти если равно или больше
   Triac_5_reset:
    Triac_5 = 0
    !rjmp Next_Triac_6
   Triac_5_set:
    Triac_5 = 1

  Next_triac_6:
   Loadadr Angle_on(6) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_6_set       'Перейти если равно или больше
   Triac_6_reset:
    Triac_6 = 0
    !rjmp Next_Triac_7
   Triac_6_set:
    Triac_6 = 1

  Next_triac_7:
   Loadadr Angle_on(7) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_7_set       'Перейти если равно или больше
   Triac_7_reset:
    Triac_7 = 0
    !rjmp Next_Triac_8
   Triac_7_set:
    Triac_7 = 1

  Next_triac_8:
   Loadadr Angle_on(8) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_8_set       'Перейти если равно или больше
   Triac_8_reset:
    Triac_8 = 0
    !rjmp Exit_isr_compare0a
   Triac_8_set:
    Triac_8 = 1

   Exit_isr_compare0a:
    !pop R31
    !pop R30
    !pop R17

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

ASM AVR 16 каналов 8 МГц

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 8000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

  $include "Config_work USART_0.bas"

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '=39 => 40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

  On Compare0a Isr_compare0a Nosave

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от ZeroCross
'===============================================================================
  Config Int0 = Rising

  Config Pind.2 = Input : Portd.2 = 0

  On Int0 Isr_int0 Nosave

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Angle_on(16) As Byte

  Triac_1 Alias Portb.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Portb.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Portb.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Portb.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Portb.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Portb.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Portb.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Portb.7 : Config Triac_8 = Output : Triac_8 = 0

  Triac_9 Alias Portc.0 : Config Triac_9 = Output : Triac_9 = 0
  Triac_10 Alias Portc.1 : Config Triac_10 = Output : Triac_10 = 0
  Triac_11 Alias Portc.2 : Config Triac_11 = Output : Triac_11 = 0
  Triac_12 Alias Portd.3 : Config Triac_12 = Output : Triac_12 = 0
  Triac_13 Alias Portd.4 : Config Triac_13 = Output : Triac_13 = 0
  Triac_14 Alias Portd.5 : Config Triac_14 = Output : Triac_14 = 0
  Triac_15 Alias Portd.6 : Config Triac_15 = Output : Triac_15 = 0
  Triac_16 Alias Portd.7 : Config Triac_16 = Output : Triac_16 = 0

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================
  Gosub Usart_0_clearing_buffer_receive

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare0a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

      If Usart_0_flag_data_input > 0 Then

          If Left(usart_0_input_buffer_str , 3) = "SET" Then
              Gosub Set_data_angle
          End If

          Gosub Usart_0_clearing_buffer_receive
      End If

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Set_data_angle:
'-------------------------------------------------------------------------------
    Count_split_usart = Split(usart_0_input_buffer_str , Split_usart_str(1) , ",")

    Angle_on(1) = Val(split_usart_str(2))
    Angle_on(2) = Val(split_usart_str(3))
    Angle_on(3) = Val(split_usart_str(4))
    Angle_on(4) = Val(split_usart_str(5))
    Angle_on(5) = Val(split_usart_str(6))
    Angle_on(6) = Val(split_usart_str(7))
    Angle_on(7) = Val(split_usart_str(8))
    Angle_on(8) = Val(split_usart_str(9))

    Angle_on(9) = Val(split_usart_str(2))
    Angle_on(10) = Val(split_usart_str(3))
    Angle_on(11) = Val(split_usart_str(4))
    Angle_on(12) = Val(split_usart_str(5))
    Angle_on(13) = Val(split_usart_str(6))
    Angle_on(14) = Val(split_usart_str(7))
    Angle_on(15) = Val(split_usart_str(8))
    Angle_on(16) = Val(split_usart_str(9))
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !clr R16
    !sts {Count_zero} , R16
    !pop R16

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R17
    !push R30
    !push R31

    !lds R17 , {Count_zero}
    !cpi R17 , 250
    !BREQ Not_count_zero       'Перейти если равно
   Count_count_zero:
    !inc R17
    !sts {Count_zero} , R17
   Not_count_zero:

  Next_triac_1:
   Loadadr Angle_on(1) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_1_set       'Перейти если равно или больше
   Triac_1_reset:
    Triac_1 = 0
    !rjmp Next_Triac_2
   Triac_1_set:
    Triac_1 = 1

  Next_triac_2:
   Loadadr Angle_on(2) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_2_set       'Перейти если равно или больше
   Triac_2_reset:
    Triac_2 = 0
    !rjmp Next_Triac_3
   Triac_2_set:
    Triac_2 = 1

  Next_triac_3:
   Loadadr Angle_on(3) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_3_set       'Перейти если равно или больше
   Triac_3_reset:
    Triac_3 = 0
    !rjmp Next_Triac_4
   Triac_3_set:
    Triac_3 = 1

  Next_triac_4:
   Loadadr Angle_on(4) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_4_set       'Перейти если равно или больше
   Triac_4_reset:
    Triac_4 = 0
    !rjmp Next_Triac_5
   Triac_4_set:
    Triac_4 = 1

  Next_triac_5:
   Loadadr Angle_on(5) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_5_set       'Перейти если равно или больше
   Triac_5_reset:
    Triac_5 = 0
    !rjmp Next_Triac_6
   Triac_5_set:
    Triac_5 = 1

  Next_triac_6:
   Loadadr Angle_on(6) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_6_set       'Перейти если равно или больше
   Triac_6_reset:
    Triac_6 = 0
    !rjmp Next_Triac_7
   Triac_6_set:
    Triac_6 = 1

  Next_triac_7:
   Loadadr Angle_on(7) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_7_set       'Перейти если равно или больше
   Triac_7_reset:
    Triac_7 = 0
    !rjmp Next_Triac_8
   Triac_7_set:
    Triac_7 = 1

  Next_triac_8:
   Loadadr Angle_on(8) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_8_set       'Перейти если равно или больше
   Triac_8_reset:
    Triac_8 = 0
    !rjmp Next_Triac_9
   Triac_8_set:
    Triac_8 = 1

  Next_triac_9:
   Loadadr Angle_on(9) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_9_set       'Перейти если равно или больше
   Triac_9_reset:
    Triac_9 = 0
    !rjmp Next_triac_10
   Triac_9_set:
    Triac_9 = 1

  Next_triac_10:
   Loadadr Angle_on(10) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_10_set       'Перейти если равно или больше
   Triac_10_reset:
    Triac_10 = 0
    !rjmp Next_triac_11
   Triac_10_set:
    Triac_10 = 1

  Next_triac_11:
   Loadadr Angle_on(11) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_11_set       'Перейти если равно или больше
   Triac_11_reset:
    Triac_11 = 0
    !rjmp Next_triac_12
   Triac_11_set:
    Triac_11 = 1

  Next_triac_12:
   Loadadr Angle_on(12) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_12_set       'Перейти если равно или больше
   Triac_12_reset:
    Triac_12 = 0
    !rjmp Next_triac_13
   Triac_12_set:
    Triac_12 = 1

  Next_triac_13:
   Loadadr Angle_on(13) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_13_set       'Перейти если равно или больше
   Triac_13_reset:
    Triac_13 = 0
    !rjmp Next_triac_14
   Triac_13_set:
    Triac_13 = 1

  Next_triac_14:
   Loadadr Angle_on(14) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_14_set       'Перейти если равно или больше
   Triac_14_reset:
    Triac_14 = 0
    !rjmp Next_triac_15
   Triac_14_set:
    Triac_14 = 1

  Next_triac_15:
   Loadadr Angle_on(15) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_15_set       'Перейти если равно или больше
   Triac_15_reset:
    Triac_15 = 0
    !rjmp Next_triac_16
   Triac_15_set:
    Triac_15 = 1

  Next_triac_16:
   Loadadr Angle_on(16) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_16_set       'Перейти если равно или больше
   Triac_16_reset:
    Triac_16 = 0
    !rjmp Exit_isr_compare0a
   Triac_16_set:
    Triac_16 = 1

   Exit_isr_compare0a:
    !pop R31
    !pop R30
    !pop R17

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

ASM AVR 8 каналов 16 МГц

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 16000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

  $include "Config_work USART_0.bas"

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '=39 => 40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

  On Compare0a Isr_compare0a Nosave

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от ZeroCross
'===============================================================================
  Config Int0 = Rising

  Config Pind.2 = Input : Portd.2 = 0

  On Int0 Isr_int0 Nosave

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Angle_on(8) As Byte

  Triac_1 Alias Portb.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Portb.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Portb.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Portb.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Portb.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Portb.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Portb.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Portb.7 : Config Triac_8 = Output : Triac_8 = 0

  Angle_on(1) = 0
  Angle_on(2) = 0
  Angle_on(3) = 0
  Angle_on(4) = 0
  Angle_on(5) = 0
  Angle_on(6) = 0
  Angle_on(7) = 0
  Angle_on(8) = 0

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================
  Gosub Usart_0_clearing_buffer_receive

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare0a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

      If Usart_0_flag_data_input > 0 Then

          If Left(usart_0_input_buffer_str , 3) = "SET" Then
              Gosub Set_data_angle
          End If

          Gosub Usart_0_clearing_buffer_receive
      End If

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Set_data_angle:
'-------------------------------------------------------------------------------
    Count_split_usart = Split(usart_0_input_buffer_str , Split_usart_str(1) , ",")

    Angle_on(1) = Val(split_usart_str(2))
    Angle_on(2) = Val(split_usart_str(3))
    Angle_on(3) = Val(split_usart_str(4))
    Angle_on(4) = Val(split_usart_str(5))
    Angle_on(5) = Val(split_usart_str(6))
    Angle_on(6) = Val(split_usart_str(7))
    Angle_on(7) = Val(split_usart_str(8))
    Angle_on(8) = Val(split_usart_str(9))
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !clr R16
    !sts {Count_zero} , R16
    !pop R16

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R17
    !push R30
    !push R31

    !lds R17 , {Count_zero}
    !cpi R17 , 250
    !BREQ Not_count_zero       'Перейти если равно
   Count_count_zero:
    !inc R17
    !sts {Count_zero} , R17
   Not_count_zero:

  Next_triac_1:
   Loadadr Angle_on(1) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_1_set       'Перейти если равно или больше
   Triac_1_reset:
    Triac_1 = 0
    !rjmp Next_Triac_2
   Triac_1_set:
    Triac_1 = 1

  Next_triac_2:
   Loadadr Angle_on(2) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_2_set       'Перейти если равно или больше
   Triac_2_reset:
    Triac_2 = 0
    !rjmp Next_Triac_3
   Triac_2_set:
    Triac_2 = 1

  Next_triac_3:
   Loadadr Angle_on(3) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_3_set       'Перейти если равно или больше
   Triac_3_reset:
    Triac_3 = 0
    !rjmp Next_Triac_4
   Triac_3_set:
    Triac_3 = 1

  Next_triac_4:
   Loadadr Angle_on(4) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_4_set       'Перейти если равно или больше
   Triac_4_reset:
    Triac_4 = 0
    !rjmp Next_Triac_5
   Triac_4_set:
    Triac_4 = 1

  Next_triac_5:
   Loadadr Angle_on(5) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_5_set       'Перейти если равно или больше
   Triac_5_reset:
    Triac_5 = 0
    !rjmp Next_Triac_6
   Triac_5_set:
    Triac_5 = 1

  Next_triac_6:
   Loadadr Angle_on(6) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_6_set       'Перейти если равно или больше
   Triac_6_reset:
    Triac_6 = 0
    !rjmp Next_Triac_7
   Triac_6_set:
    Triac_6 = 1

  Next_triac_7:
   Loadadr Angle_on(7) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_7_set       'Перейти если равно или больше
   Triac_7_reset:
    Triac_7 = 0
    !rjmp Next_Triac_8
   Triac_7_set:
    Triac_7 = 1

  Next_triac_8:
   Loadadr Angle_on(8) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_8_set       'Перейти если равно или больше
   Triac_8_reset:
    Triac_8 = 0
    !rjmp Exit_isr_compare0a
   Triac_8_set:
    Triac_8 = 1

   Exit_isr_compare0a:
    !pop R31
    !pop R30
    !pop R17

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

ASM AVR 16 каналов 16 МГц

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 16000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

  $include "Config_work USART_0.bas"

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '=39 => 40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

  On Compare0a Isr_compare0a Nosave

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от ZeroCross
'===============================================================================
  Config Int0 = Rising

  Config Pind.2 = Input : Portd.2 = 0

  On Int0 Isr_int0 Nosave

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Angle_on(16) As Byte

  Triac_1 Alias Portb.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Portb.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Portb.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Portb.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Portb.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Portb.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Portb.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Portb.7 : Config Triac_8 = Output : Triac_8 = 0

  Triac_9 Alias Portc.0 : Config Triac_9 = Output : Triac_9 = 0
  Triac_10 Alias Portc.1 : Config Triac_10 = Output : Triac_10 = 0
  Triac_11 Alias Portc.2 : Config Triac_11 = Output : Triac_11 = 0
  Triac_12 Alias Portd.3 : Config Triac_12 = Output : Triac_12 = 0
  Triac_13 Alias Portd.4 : Config Triac_13 = Output : Triac_13 = 0
  Triac_14 Alias Portd.5 : Config Triac_14 = Output : Triac_14 = 0
  Triac_15 Alias Portd.6 : Config Triac_15 = Output : Triac_15 = 0
  Triac_16 Alias Portd.7 : Config Triac_16 = Output : Triac_16 = 0

  Angle_on(1) = 0
  Angle_on(2) = 0
  Angle_on(3) = 0
  Angle_on(4) = 0
  Angle_on(5) = 0
  Angle_on(6) = 0
  Angle_on(7) = 0
  Angle_on(8) = 0

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================
  Gosub Usart_0_clearing_buffer_receive

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare0a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

      If Usart_0_flag_data_input > 0 Then

          If Left(usart_0_input_buffer_str , 3) = "SET" Then
              Gosub Set_data_angle
          End If

          Gosub Usart_0_clearing_buffer_receive
      End If

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Set_data_angle:
'-------------------------------------------------------------------------------
    Count_split_usart = Split(usart_0_input_buffer_str , Split_usart_str(1) , ",")

    Angle_on(1) = Val(split_usart_str(2))
    Angle_on(2) = Val(split_usart_str(3))
    Angle_on(3) = Val(split_usart_str(4))
    Angle_on(4) = Val(split_usart_str(5))
    Angle_on(5) = Val(split_usart_str(6))
    Angle_on(6) = Val(split_usart_str(7))
    Angle_on(7) = Val(split_usart_str(8))
    Angle_on(8) = Val(split_usart_str(9))

    Angle_on(9) = Val(split_usart_str(2))
    Angle_on(10) = Val(split_usart_str(3))
    Angle_on(11) = Val(split_usart_str(4))
    Angle_on(12) = Val(split_usart_str(5))
    Angle_on(13) = Val(split_usart_str(6))
    Angle_on(14) = Val(split_usart_str(7))
    Angle_on(15) = Val(split_usart_str(8))
    Angle_on(16) = Val(split_usart_str(9))
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !clr R16
    !sts {Count_zero} , R16
    !pop R16

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R17
    !push R30
    !push R31

    !lds R17 , {Count_zero}
    !cpi R17 , 250
    !BREQ Not_count_zero       'Перейти если равно
   Count_count_zero:
    !inc R17
    !sts {Count_zero} , R17
   Not_count_zero:

  Next_triac_1:
   Loadadr Angle_on(1) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_1_set       'Перейти если равно или больше
   Triac_1_reset:
    Triac_1 = 0
    !rjmp Next_Triac_2
   Triac_1_set:
    Triac_1 = 1

  Next_triac_2:
   Loadadr Angle_on(2) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_2_set       'Перейти если равно или больше
   Triac_2_reset:
    Triac_2 = 0
    !rjmp Next_Triac_3
   Triac_2_set:
    Triac_2 = 1

  Next_triac_3:
   Loadadr Angle_on(3) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_3_set       'Перейти если равно или больше
   Triac_3_reset:
    Triac_3 = 0
    !rjmp Next_Triac_4
   Triac_3_set:
    Triac_3 = 1

  Next_triac_4:
   Loadadr Angle_on(4) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_4_set       'Перейти если равно или больше
   Triac_4_reset:
    Triac_4 = 0
    !rjmp Next_Triac_5
   Triac_4_set:
    Triac_4 = 1

  Next_triac_5:
   Loadadr Angle_on(5) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_5_set       'Перейти если равно или больше
   Triac_5_reset:
    Triac_5 = 0
    !rjmp Next_Triac_6
   Triac_5_set:
    Triac_5 = 1

  Next_triac_6:
   Loadadr Angle_on(6) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_6_set       'Перейти если равно или больше
   Triac_6_reset:
    Triac_6 = 0
    !rjmp Next_Triac_7
   Triac_6_set:
    Triac_6 = 1

  Next_triac_7:
   Loadadr Angle_on(7) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_7_set       'Перейти если равно или больше
   Triac_7_reset:
    Triac_7 = 0
    !rjmp Next_Triac_8
   Triac_7_set:
    Triac_7 = 1

  Next_triac_8:
   Loadadr Angle_on(8) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_8_set       'Перейти если равно или больше
   Triac_8_reset:
    Triac_8 = 0
    !rjmp Next_Triac_9
   Triac_8_set:
    Triac_8 = 1

  Next_triac_9:
   Loadadr Angle_on(9) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_9_set       'Перейти если равно или больше
   Triac_9_reset:
    Triac_9 = 0
    !rjmp Next_triac_10
   Triac_9_set:
    Triac_9 = 1

  Next_triac_10:
   Loadadr Angle_on(10) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_10_set       'Перейти если равно или больше
   Triac_10_reset:
    Triac_10 = 0
    !rjmp Next_triac_11
   Triac_10_set:
    Triac_10 = 1

  Next_triac_11:
   Loadadr Angle_on(11) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_11_set       'Перейти если равно или больше
   Triac_11_reset:
    Triac_11 = 0
    !rjmp Next_triac_12
   Triac_11_set:
    Triac_11 = 1

  Next_triac_12:
   Loadadr Angle_on(12) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_12_set       'Перейти если равно или больше
   Triac_12_reset:
    Triac_12 = 0
    !rjmp Next_triac_13
   Triac_12_set:
    Triac_12 = 1

  Next_triac_13:
   Loadadr Angle_on(13) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_13_set       'Перейти если равно или больше
   Triac_13_reset:
    Triac_13 = 0
    !rjmp Next_triac_14
   Triac_13_set:
    Triac_13 = 1

  Next_triac_14:
   Loadadr Angle_on(14) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_14_set       'Перейти если равно или больше
   Triac_14_reset:
    Triac_14 = 0
    !rjmp Next_triac_15
   Triac_14_set:
    Triac_14 = 1

  Next_triac_15:
   Loadadr Angle_on(15) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_15_set       'Перейти если равно или больше
   Triac_15_reset:
    Triac_15 = 0
    !rjmp Next_triac_16
   Triac_15_set:
    Triac_15 = 1

  Next_triac_16:
   Loadadr Angle_on(16) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_16_set       'Перейти если равно или больше
   Triac_16_reset:
    Triac_16 = 0
    !rjmp Exit_isr_compare0a
   Triac_16_set:
    Triac_16 = 1

   Exit_isr_compare0a:
    !pop R31
    !pop R30
    !pop R17

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

http://s3.uploads.ru/t/YFoLl.jpg

+5

11

32 канала, софтовый вариант фазовой регулировки на прерываниях

Исходник + симуляция  -  скачать с google

32 канала исходник

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m2561def.dat"       'Документация Atmel - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 16000000
  $framesize = 256       ' Размер области используемой и необходимой для преобразований
  $hwstack = 256       ' Размер аппаратного стека
  $swstack = 256       ' Размер программного стека

  $include "Config_work USART_0.bas"

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Const Const_t_sys = 40       'Период прерываний в мкс
  Const Const_div_sys_timer = 8       'Аппаратный делитель используемого таймера
  Const Const_time_sys =((_xtal / 1000000) * Const_t_sys / Const_div_sys_timer) - 1

  Compare0a = Const_time_sys       '=39 => 40 uS
'  Compare0a = 39       '40 uS

  Config Timer0 = Counter , Prescale = Const_div_sys_timer , Compare A = Disconnect , Compare B = Disconnect , Clear Timer = 1

  On Compare0a Isr_compare0a Nosave

  Dim Count_zero As Byte

'===============================================================================
'                     Конфигурация прерывания от ZeroCross
'===============================================================================
  Config Int0 = Rising

  Config Pind.0 = Input : Portd.0 = 0

  On Int0 Isr_int0 Nosave

'===============================================================================
'           Конфигурация МК для коммутации симисторов
'===============================================================================

  Dim Count_angle As Byte
  Dim Angle_on(32) As Byte

  Triac_1 Alias Porta.0 : Config Triac_1 = Output : Triac_1 = 0
  Triac_2 Alias Porta.1 : Config Triac_2 = Output : Triac_2 = 0
  Triac_3 Alias Porta.2 : Config Triac_3 = Output : Triac_3 = 0
  Triac_4 Alias Porta.3 : Config Triac_4 = Output : Triac_4 = 0
  Triac_5 Alias Porta.4 : Config Triac_5 = Output : Triac_5 = 0
  Triac_6 Alias Porta.5 : Config Triac_6 = Output : Triac_6 = 0
  Triac_7 Alias Porta.6 : Config Triac_7 = Output : Triac_7 = 0
  Triac_8 Alias Porta.7 : Config Triac_8 = Output : Triac_8 = 0

  Triac_9 Alias Portb.0 : Config Triac_9 = Output : Triac_9 = 0
  Triac_10 Alias Portb.1 : Config Triac_10 = Output : Triac_10 = 0
  Triac_11 Alias Portb.2 : Config Triac_11 = Output : Triac_11 = 0
  Triac_12 Alias Portb.3 : Config Triac_12 = Output : Triac_12 = 0
  Triac_13 Alias Portb.4 : Config Triac_13 = Output : Triac_13 = 0
  Triac_14 Alias Portb.5 : Config Triac_14 = Output : Triac_14 = 0
  Triac_15 Alias Portb.6 : Config Triac_15 = Output : Triac_15 = 0
  Triac_16 Alias Portb.7 : Config Triac_16 = Output : Triac_16 = 0

  Triac_17 Alias Portc.0 : Config Triac_17 = Output : Triac_17 = 0
  Triac_18 Alias Portc.1 : Config Triac_18 = Output : Triac_18 = 0
  Triac_19 Alias Portc.2 : Config Triac_19 = Output : Triac_19 = 0
  Triac_20 Alias Portc.3 : Config Triac_20 = Output : Triac_20 = 0
  Triac_21 Alias Portc.4 : Config Triac_21 = Output : Triac_21 = 0
  Triac_22 Alias Portc.5 : Config Triac_22 = Output : Triac_22 = 0
  Triac_23 Alias Portc.6 : Config Triac_23 = Output : Triac_23 = 0
  Triac_24 Alias Portc.7 : Config Triac_24 = Output : Triac_24 = 0

  Triac_25 Alias Portf.0 : Config Triac_25 = Output : Triac_25 = 0
  Triac_26 Alias Portf.1 : Config Triac_26 = Output : Triac_26 = 0
  Triac_27 Alias Portf.2 : Config Triac_27 = Output : Triac_27 = 0
  Triac_28 Alias Portf.3 : Config Triac_28 = Output : Triac_28 = 0
  Triac_29 Alias Portf.4 : Config Triac_29 = Output : Triac_29 = 0
  Triac_30 Alias Portf.5 : Config Triac_30 = Output : Triac_30 = 0
  Triac_31 Alias Portf.6 : Config Triac_31 = Output : Triac_31 = 0
  Triac_32 Alias Portf.7 : Config Triac_31 = Output : Triac_32 = 0

  For Count_angle = 1 To 32
      Angle_on(count_angle) = 250
  Next Count_angle

'===============================================================================
'              Разрешаем работу необходимых прерываний
'===============================================================================
  Gosub Usart_0_clearing_buffer_receive

  Enable Int0

  Enable Compare0a       'Разрешаем прерывания от Compare0a

'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:

'===============================================================================

      If Usart_0_flag_data_input > 0 Then

          If Left(usart_0_input_buffer_str , 3) = "SET" Then
              Gosub Set_data_angle
          End If

          Gosub Usart_0_clearing_buffer_receive
      End If

   Idle
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================

'===============================================================================
  Set_data_angle:
'-------------------------------------------------------------------------------
    Count_split_usart = Split(usart_0_input_buffer_str , Split_usart_str(1) , ",")

    Angle_on(1) = Val(split_usart_str(2))
    Angle_on(2) = Val(split_usart_str(3))
    Angle_on(3) = Val(split_usart_str(4))
    Angle_on(4) = Val(split_usart_str(5))
    Angle_on(5) = Val(split_usart_str(6))
    Angle_on(6) = Val(split_usart_str(7))
    Angle_on(7) = Val(split_usart_str(8))
    Angle_on(8) = Val(split_usart_str(9))

    Angle_on(9) = Val(split_usart_str(10))
    Angle_on(10) = Val(split_usart_str(11))
    Angle_on(11) = Val(split_usart_str(12))
    Angle_on(12) = Val(split_usart_str(13))
    Angle_on(13) = Val(split_usart_str(14))
    Angle_on(14) = Val(split_usart_str(15))
    Angle_on(15) = Val(split_usart_str(16))
    Angle_on(16) = Val(split_usart_str(17))

    Angle_on(17) = Val(split_usart_str(18))
    Angle_on(18) = Val(split_usart_str(19))
    Angle_on(19) = Val(split_usart_str(20))
    Angle_on(20) = Val(split_usart_str(21))
    Angle_on(21) = Val(split_usart_str(22))
    Angle_on(22) = Val(split_usart_str(23))
    Angle_on(23) = Val(split_usart_str(24))
    Angle_on(24) = Val(split_usart_str(25))

    Angle_on(25) = Val(split_usart_str(26))
    Angle_on(26) = Val(split_usart_str(27))
    Angle_on(27) = Val(split_usart_str(28))
    Angle_on(28) = Val(split_usart_str(29))
    Angle_on(29) = Val(split_usart_str(30))
    Angle_on(30) = Val(split_usart_str(31))
    Angle_on(31) = Val(split_usart_str(32))
    Angle_on(32) = Val(split_usart_str(33))

'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_int0:
'-------------------------------------------------------------------------------
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !clr R16
    !sts {Count_zero} , R16
    !pop R16

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Isr_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    #if _romsize > 65000
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R17
    !push R30
    !push R31

    !lds R17 , {Count_zero}
    !cpi R17 , 250
    !BREQ Not_count_zero       'Перейти если равно
   Count_count_zero:
    !inc R17
    !sts {Count_zero} , R17
   Not_count_zero:

  Next_triac_1:
   Loadadr Angle_on(1) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_1_set       'Перейти если равно или больше
   Triac_1_reset:
    Triac_1 = 0
    !rjmp Next_Triac_2
   Triac_1_set:
    Triac_1 = 1

  Next_triac_2:
   Loadadr Angle_on(2) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_2_set       'Перейти если равно или больше
   Triac_2_reset:
    Triac_2 = 0
    !rjmp Next_Triac_3
   Triac_2_set:
    Triac_2 = 1

  Next_triac_3:
   Loadadr Angle_on(3) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_3_set       'Перейти если равно или больше
   Triac_3_reset:
    Triac_3 = 0
    !rjmp Next_Triac_4
   Triac_3_set:
    Triac_3 = 1

  Next_triac_4:
   Loadadr Angle_on(4) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_4_set       'Перейти если равно или больше
   Triac_4_reset:
    Triac_4 = 0
    !rjmp Next_Triac_5
   Triac_4_set:
    Triac_4 = 1

  Next_triac_5:
   Loadadr Angle_on(5) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_5_set       'Перейти если равно или больше
   Triac_5_reset:
    Triac_5 = 0
    !rjmp Next_Triac_6
   Triac_5_set:
    Triac_5 = 1

  Next_triac_6:
   Loadadr Angle_on(6) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_6_set       'Перейти если равно или больше
   Triac_6_reset:
    Triac_6 = 0
    !rjmp Next_Triac_7
   Triac_6_set:
    Triac_6 = 1

  Next_triac_7:
   Loadadr Angle_on(7) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_7_set       'Перейти если равно или больше
   Triac_7_reset:
    Triac_7 = 0
    !rjmp Next_Triac_8
   Triac_7_set:
    Triac_7 = 1

  Next_triac_8:
   Loadadr Angle_on(8) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_8_set       'Перейти если равно или больше
   Triac_8_reset:
    Triac_8 = 0
    !rjmp Next_Triac_9
   Triac_8_set:
    Triac_8 = 1

  Next_triac_9:
   Loadadr Angle_on(9) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_9_set       'Перейти если равно или больше
   Triac_9_reset:
    Triac_9 = 0
    !rjmp Next_triac_10
   Triac_9_set:
    Triac_9 = 1

  Next_triac_10:
   Loadadr Angle_on(10) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_10_set       'Перейти если равно или больше
   Triac_10_reset:
    Triac_10 = 0
    !rjmp Next_triac_11
   Triac_10_set:
    Triac_10 = 1

  Next_triac_11:
   Loadadr Angle_on(11) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_11_set       'Перейти если равно или больше
   Triac_11_reset:
    Triac_11 = 0
    !rjmp Next_triac_12
   Triac_11_set:
    Triac_11 = 1

  Next_triac_12:
   Loadadr Angle_on(12) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_12_set       'Перейти если равно или больше
   Triac_12_reset:
    Triac_12 = 0
    !rjmp Next_triac_13
   Triac_12_set:
    Triac_12 = 1

  Next_triac_13:
   Loadadr Angle_on(13) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_13_set       'Перейти если равно или больше
   Triac_13_reset:
    Triac_13 = 0
    !rjmp Next_triac_14
   Triac_13_set:
    Triac_13 = 1

  Next_triac_14:
   Loadadr Angle_on(14) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_14_set       'Перейти если равно или больше
   Triac_14_reset:
    Triac_14 = 0
    !rjmp Next_triac_15
   Triac_14_set:
    Triac_14 = 1

  Next_triac_15:
   Loadadr Angle_on(15) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_15_set       'Перейти если равно или больше
   Triac_15_reset:
    Triac_15 = 0
    !rjmp Next_triac_16
   Triac_15_set:
    Triac_15 = 1

  Next_triac_16:
   Loadadr Angle_on(16) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_16_set       'Перейти если равно или больше
   Triac_16_reset:
    Triac_16 = 0
    !rjmp Next_triac_17
   Triac_16_set:
    Triac_16 = 1

  Next_triac_17:
   Loadadr Angle_on(17) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_17_set       'Перейти если равно или больше
   Triac_17_reset:
    Triac_17 = 0
    !rjmp Next_triac_18
   Triac_17_set:
    Triac_17 = 1

  Next_triac_18:
   Loadadr Angle_on(18) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_18_set       'Перейти если равно или больше
   Triac_18_reset:
    Triac_18 = 0
    !rjmp Next_triac_19
   Triac_18_set:
    Triac_18 = 1

  Next_triac_19:
   Loadadr Angle_on(19) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_19_set       'Перейти если равно или больше
   Triac_19_reset:
    Triac_19 = 0
    !rjmp Next_triac_20
   Triac_19_set:
    Triac_19 = 1

  Next_triac_20:
   Loadadr Angle_on(20) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_20_set       'Перейти если равно или больше
   Triac_20_reset:
    Triac_20 = 0
    !rjmp Next_triac_21
   Triac_20_set:
    Triac_20 = 1

  Next_triac_21:
   Loadadr Angle_on(21) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_21_set       'Перейти если равно или больше
   Triac_21_reset:
    Triac_21 = 0
    !rjmp Next_triac_22
   Triac_21_set:
    Triac_21 = 1

  Next_triac_22:
   Loadadr Angle_on(22) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_22_set       'Перейти если равно или больше
   Triac_22_reset:
    Triac_22 = 0
    !rjmp Next_triac_23
   Triac_22_set:
    Triac_22 = 1

  Next_triac_23:
   Loadadr Angle_on(23) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_23_set       'Перейти если равно или больше
   Triac_23_reset:
    Triac_23 = 0
    !rjmp Next_triac_24
   Triac_23_set:
    Triac_23 = 1

  Next_triac_24:
   Loadadr Angle_on(24) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_24_set       'Перейти если равно или больше
   Triac_24_reset:
    Triac_24 = 0
    !rjmp Next_triac_25
   Triac_24_set:
    Triac_24 = 1

  Next_triac_25:
   Loadadr Angle_on(25) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_25_set       'Перейти если равно или больше
   Triac_25_reset:
    Triac_25 = 0
    !rjmp Next_triac_26
   Triac_25_set:
    Triac_25 = 1

  Next_triac_26:
   Loadadr Angle_on(26) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_26_set       'Перейти если равно или больше
   Triac_26_reset:
    Triac_26 = 0
    !rjmp Next_triac_27
   Triac_26_set:
    Triac_26 = 1

  Next_triac_27:
   Loadadr Angle_on(27) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_27_set       'Перейти если равно или больше
   Triac_27_reset:
    Triac_27 = 0
    !rjmp Next_triac_28
   Triac_27_set:
    Triac_27 = 1

  Next_triac_28:
   Loadadr Angle_on(28) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_28_set       'Перейти если равно или больше
   Triac_28_reset:
    Triac_28 = 0
    !rjmp Next_triac_29
   Triac_28_set:
    Triac_28 = 1

  Next_triac_29:
   Loadadr Angle_on(29) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_29_set       'Перейти если равно или больше
   Triac_29_reset:
    Triac_29 = 0
    !rjmp Next_triac_30
   Triac_29_set:
    Triac_29 = 1

  Next_triac_30:
   Loadadr Angle_on(30) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_30_set       'Перейти если равно или больше
   Triac_30_reset:
    Triac_30 = 0
    !rjmp Next_triac_31
   Triac_30_set:
    Triac_30 = 1

  Next_triac_31:
   Loadadr Angle_on(31) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_31_set       'Перейти если равно или больше
   Triac_31_reset:
    Triac_31 = 0
    !rjmp Next_triac_32
   Triac_31_set:
    Triac_31 = 1

  Next_triac_32:
   Loadadr Angle_on(32) , Z
    !ld R16 , Z
    !cp R17 , R16
    !BRSH Triac_32_set       'Перейти если равно или больше
   Triac_32_reset:
    Triac_32 = 0
    !rjmp Exit_isr_compare0a
   Triac_32_set:
    Triac_32 = 1

   Exit_isr_compare0a:
    !pop R31
    !pop R30
    !pop R17

    #if _romsize > 65000
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

http://sh.uploads.ru/t/sK9oV.jpg

+6

12

Предел для Atmega, если надо что-то ещё успевать делать.

Добавил проверку контрольной суммы

слямзил у формата NMEA

NMEA – это формат передачи сообщений между корабельными приборами. Он включает в себя систему сообщений для обмена информацией между навигационными GPS приёмниками и потребителями навигационной информации. Все команды и сообщения передаются в текстовом ASCII виде, относящиеся к GPS приёмникам начинаются с $GP, в конце строки сообщения должны быть символы <CR><LF>. В последнем поле сообщения может быть указана контрольная сумма текущего сообщения, начинающаяся с разделителя *. Контрольная сумма 8 – ми битная (исключающая ИЛИ) всех символов сообщения, включая пробелы, расположенных между разделителями $ и *, не включая последних. Шестнадцатеричный результат переводится в два ASCII символа (0-9, A-F).

56 каналов, софтовый вариант фазовой регулировки на прерываниях

Исходник + симуляция  -  скачать с google

http://s7.uploads.ru/t/1SZAc.jpg

+3

13

Ни х..... себе, на столько интересная тема, я в шоке.!

И кто куда её применяет ?

0


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование фазовой регулировки мощности нагрузки в сети 220 вольт