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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » NEC протокол. Прием и передача


NEC протокол. Прием и передача

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

1

1. Прием команд NEC протокола. На LCD вывод 2-х байт адреса и 2-х байт команды. Проверка целостности данных только для байт команды, тк у меня пульты выдают 16 бит адреса(основа с сайта Bascom).

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 32
$swstack = 24
$framesize = 24


'-------------------------------------------------------------------------------
' Конфигурация LCD
'-------------------------------------------------------------------------------
  Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5
'-------------------------------------------------------------------------------
  Config Lcd = 16 * 2                                       ' Используемый LCD
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
  Initlcd                                                   ' Инициализируем LCD
  Waitms 50                                                 ' Ждем пока все запустится
  Cursor Off Noblink                                        ' Выключаем неморгающий курсор
  Cls                                                       ' Очистка экрана
'-------------------------------------------------------------------------------
'       Конфигурация портов
'-------------------------------------------------------------------------------

Led Alias Portb.5                                           ' Индикатор приема пульта
Ir_in Alias Pind.2                                          ' Вход от IR датчика

Config Ir_in = Input
Set Ir_in

Config Led = Output
Reset Led

'-------------------------------------------------------------------------------
' Конфигурация таймеров
'-------------------------------------------------------------------------------

'Config Timer0 = Timer , Prescale = 256                                         ' 16000000/256 = 62500
'Tccr0b.cs02 = 1                                                                ' Запуск таймера с Prescale = 256




'-------------------------------------------------------------------------------
' Настройка прерываний
'-------------------------------------------------------------------------------

Config Int0 = Falling                                       'Прерывание по спаду
On Timer0 Tikers                                            'работа по таймеру
On Int0 Infrared                                            'работа по прерыванию

'-------------------------------------------------------------------------------
' Запуск прерываний
'-------------------------------------------------------------------------------

Enable Timer0                                               'разрешаем работу таймера0
Enable Int0                                                 'разрешаем работу прерывания0
Enable Interrupts                                           'Разрешаем прерывания

'-------------------------------------------------------------------------------
' Опеределение переменных
'-------------------------------------------------------------------------------

Dim Tik As Word                                             'счётчик тиков таймера
Dim Byt As Byte                                             'счётчик принятых бит
Dim Repeat_flag As Bit                                      'флаг повтора
Dim Start_flag As Bit                                       'флаг стартового условия
Dim Address As Byte                                         'байт адреса
Dim Address_inv As Byte                                     'байт адреса инверт
Dim Command As Byte                                         'байт команды
Dim Command_inv As Byte                                     'байт команды инверт
Dim Address_1 As Byte                                       'прямой байт адреса
Dim Command_1 As Byte                                       'прямой байт команды
Dim Address_0 As Byte                                       'инверсный байт адреса
Dim Command_0 As Byte                                       'инверсный байт команды
Dim Checked_flag As Bit                                  'флаг успешного приема команды
Dim Summa As Word
Dim S1 As String * 10
Dim S2 As String * 10
'-------------------------------------------------------------------------------


Set Led
Waitms 2000
Reset Led

Set Checked_flag                                            ' Для первоначального вывода на LCD

Do
    If Checked_flag = 1 Then

        Locate 1 , 1
        Lcd "Add:" ; Format(s1 , "       ")
        Locate 2 , 1
        Lcd "Com:" ; Format(s2 , "       ")

        Reset Checked_flag
    End If

    If Repeat_flag = 1 Then                                 ' Индикация NEC повтора
        Locate 2 , 13
        Lcd "R"
    Else
         Locate 2 , 13
        Lcd " "
    End If

Loop
End

'*******************************************************************************

 Tikers:                                                    'работа по таймеру

 Timer0 = 250                                               '62500/(256-250)=10416,66 Hz (96 мкс)
                                                             '252 - TV SAMSUNG, 250 - DVD SAMSUNG и другие NEC
 Incr Tik
 If Tik >= 1200 Then                                        'если время паузы (без сигнала) больше 110 мс, то прекращаем прием данных
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 0
 Command_1 = 0
 Address_0 = 0
 Command_0 = 0
 Reset Led
 Stop Timer0                                                'останавливаем таймер
 End If

  Return
'*******************************************************************************

 Infrared:                                                  'работа по прерыванию

  Tccr0b.cs02 = 1                                           'Start Timer0  'запускаем таймер
  Set Led
  If Tik >= 139 And Tik < 150 Then                          'если случилось от 139 до 150 тиков - "СТАРТ"
      Address = 1
      Repeat_flag = 0
      Start_flag = 1
      Address_1 = 0
      Command_1 = 0
      Address_0 = 0
      Command_0 = 0
  End If

  If Tik >= 116 And Tik < 139 Then                          'если случилось от 116 до 138 тиков - "ПОВТОР"
      Repeat_flag = 1
      Start_flag = 0
  End If

  If Tik >= 22 And Tik < 116 And Start_flag = 1 Then        'если случилось от 22 до 115 тиков - приняли "1"
   Incr Byt

    If Byt < 9 Then
     Shift Address_0 , Right
     Address_0.7 = 1
    End If

    If Byt >= 9 And Byt < 17 Then
     Shift Address_1 , Right
     Address_1.7 = 1
    End If

    If Byt >= 17 And Byt < 25 Then
     Shift Command_0 , Right
     Command_0.7 = 1
    End If

    If Byt >= 25 Then
     Shift Command_1 , Right
     Command_1.7 = 1
    End If
  End If

  If Tik >= 10 And Tik < 22 And Start_flag = 1 Then         'если случилось от 10 до 21 тика - приняли "0"
   Incr Byt

    If Byt < 9 Then
     Shift Address_0 , Right
    End If

    If Byt >= 9 And Byt < 17 Then
     Shift Address_1 , Right
    End If

    If Byt >= 17 And Byt < 25 Then
     Shift Command_0 , Right
    End If

    If Byt >= 25 Then
     Shift Command_1 , Right
    End If
  End If

 Tik = 0

  If Byt = 32 Then                                          'если приняли 4 байта, проверяем правильность приёма команды
                                                             'если адрес 16-ричный, проверка не проходит
    Address = Address_0
    Address_inv = Address_1
    S1 = Str(address)
    S1 = S1 + " "
    S1 = S1 + Str(address_inv)

    Summa = Command_0 + Command_1
        If Summa = 255 Then                                 ' Если сумма байт команды дает 255, значит данные приняты корректно
            Command = Command_0
            Command_inv = Command_1
            S2 = Str(command)
            S2 = S2 + " "
            S2 = S2 + Str(command_inv)
            Set Checked_flag
        Else
            Command = 0
            Command_inv = 0
            S2 = "err"
        End If

  Byt = 0
  Repeat_flag = 0
  Start_flag = 0
  Stop Timer0                                               'останавливаем таймер
  End If
 Return

0

2

2. Передача NEC команд (эмуляция пульта). ИК диод на ноге PORTD.6 напрямую (без ключа). Кнопка на PIND.0 на массу - собственно эмуляция пульта. Байты адреса и команды заданы переменными стационарно.

Код:
$regfile = "m328pdef.dat"                                   '
$crystal = 16000000                                         '
$hwstack = 32
$swstack = 24
$framesize = 24

'-------------------------------------------------------------------------------
'       Конфигурация портов
'-------------------------------------------------------------------------------                                                 '
Set Ddrd.6                                                  ' Настройка пина PORTD.6 на выход
Set Ddrb.5                                                  ' Настройка пина PORTB.5 на выход
Reset Ddrd.0                                                ' Настройка пина PORTD.0 на вход
Portd.0 = 1

Led Alias Portb.5                                           ' Светодиод индикации
Button Alias Pind.0                                         ' Кнопка - режим передачи данных NEC

'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
' Конфигурация таймеров
'-------------------------------------------------------------------------------
Tccr0a.wgm01 = 1                                            ' Задаем режим ШИМ  CTC на TIMER0
'Tccr0a.com0a0 = 1                                           ' Подключение выхода ШИМ на PORTD.6
Tccr0b.cs00 = 1                                             ' Запуск таймера с   Prescale = 1

Ocr0a = 209                                                 ' Настройка частоты ШИМ F = 160000/2*Prescale*(1+Ocr0a)  = 38095 Гц


Tccr2a.wgm21 = 1                                            ' Задаем режим ШИМ  CTC на TIMER2
Tccr2b.cs21 = 1                                             ' Запуск таймера с   Prescale = 8

Ocr2a = 225                                                 ' Настройка частоты прерываний от TIMER2 F=16000000/Prescale*Ocr2a = 8888,88 Гц  = 112,5 мкс

Config Timer1 = Timer , Prescale = 64                       ' Настройка таймера1 на переполнение каждые Т= Prescale * 65536/F = 64*65536/16000000= 0.262144 сек
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
' Настройка прерываний
'-------------------------------------------------------------------------------
Timsk2.ocie2a = 1                                           ' Разрешаем прерывание по совпадению Compare Match A для TIMER2

Enable Timer1                                               ' Разрешаем прерывание по переполнению TIMER1
Start Timer1                                                ' Запуск TIMER1
Enable Interrupts                                           ' Разрешаем прерывания
On Compare2a Time_counter_nec                               ' Прерывания по совпадению для TIMER2. Для отсчета временных интервалов NEC протокола
On Timer1 Timer1_int                                        ' ПП обработки прерываний от TIMER1
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
' Опеределение переменных
'-------------------------------------------------------------------------------
Const Preset_110ms = 977                                    ' Предустановка счетчика на 110 мс
Const Preset_40ms = 360                                     ' Предустановка счетчика на 40 мс    для повтора
Const Preset_9ms = 80                                       ' Предустановка счетчика на 9 мс
Const Preset_4_5ms = 40                                     ' Предустановка счетчика на 4,5 мс
Const Preset_2_25ms = 20                                    ' Предустановка счетчика на 2,25 мс
Const Preset_1_6875ms = 15                                  ' Предустановка счетчика на 1,6875 мс
Const Preset_562_5us = 5                                    ' Предустановка счетчика на 562,5 мкс

Dim Count_110ms As Word                                     ' Cчетчик на 110 мс
Dim Count_40ms As Word                                      ' Cчетчик на 40 мс
Dim Count_9ms As Byte                                       ' Cчетчик на 9 мс
Dim Count_4_5ms As Byte                                     ' Cчетчик на 4,5 мс
Dim Count_2_25ms As Byte                                    ' Cчетчик на 2,25 мс
Dim Count_1_6875ms As Byte                                  ' Cчетчик на 1,6875 мс
Dim Count_562_5us As Byte                                   ' Cчетчик на 562,5 мкс

Dim Flag_110ms As Bit                                       ' Флаг запуска отрезка времени 110 мс
Dim Flag_40ms As Bit                                        ' Флаг запуска отрезка времени 40 мс
Dim Flag_9ms As Bit                                         ' Флаг запуска отрезка времени 9 мс
Dim Flag_4_5ms As Bit                                       ' Флаг запуска отрезка времени 4,5 мс
Dim Flag_2_25ms As Bit                                      ' Флаг запуска отрезка времени 2,25 мс
Dim Flag_1_6875ms As Bit                                    ' Флаг запуска отрезка времени 1,6875 мс
Dim Flag_562_5us As Bit                                     ' Флаг запуска отрезка времени 562,5 мкс

Dim Nec_bit_send As Byte                                    ' Кол-во отправленных бит
Dim Send_byte As Byte                                       ' Отправляемый байт
Dim Start_send_flag As Bit                                  ' Команда на отправку данных NEC
Dim Nec_repeat_flag As Bit                                  ' Флаг повтора передачи данных

Dim Address(2) As Byte                                      ' Адресс NEC устройства
Dim Command(2) As Byte                                      ' Команда NEC устройства

'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
' Опеределение подпрограмм
'-------------------------------------------------------------------------------
Declare Sub Nec_send_command(nec_add0 As Byte , Nec_add1 As Byte , Nec_cmd0 As Byte , Nec_cmd1 As Byte)
Declare Sub Nec_send_repeat()
'-------------------------------------------------------------------------------


Address(1) = 97
Address(2) = 214
Command(1) = 9
Command(2) = 246

Do

    If Start_send_flag = 1 Then
        If Nec_repeat_flag = 0 Then Call Nec_send_command(address(1) , Address(2) , Command(1) , Command(2))       ' Вызов ПП отправки NEC данных
        If Nec_repeat_flag = 1 Then Call Nec_send_repeat()  ' Вызов ПП повторной отправки NEC данных
    End If
Loop

End

'-------------------------------------------------------------------------------
' Прерывание от TIMER2 каждые 112,5 мкс
'-------------------------------------------------------------------------------
Time_counter_nec:

    If Flag_9ms = 1 Then                                    ' 9мс для начала пакета. Модуляция
        Incr Count_9ms
        If Count_9ms = Preset_9ms Then
            Count_9ms = 0
            Reset Flag_9ms
            Tccr0a.com0a0 = 0                               ' Выключение модуляции
        End If
    End If

    If Flag_4_5ms = 1 Then                                  ' Пауза 4,5 мс в начале пакета
        Incr Count_4_5ms
        If Count_4_5ms = Preset_4_5ms Then
            Count_4_5ms = 0
            Reset Flag_4_5ms
        End If
    End If

    If Flag_1_6875ms = 1 Then                               ' Пауза. лог. 1 = 2,25 мс = 562,5 мкс + 1,6875 мс
        Incr Count_1_6875ms
        If Count_1_6875ms = Preset_1_6875ms Then
            Count_1_6875ms = 0
            Reset Flag_1_6875ms
        End If
    End If

    If Flag_562_5us = 1 Then                                ' начало бита даннных и оно же равно паузе в лог. 0
        Incr Count_562_5us
        If Count_562_5us = Preset_562_5us Then
            Count_562_5us = 0
            Reset Flag_562_5us
            Tccr0a.com0a0 = 0                               ' Выключение модуляции
        End If
    End If

    If Flag_40ms = 1 Then                                   ' Пауза. 40мс для окончания пакета
        Incr Count_40ms
        If Count_40ms = Preset_40ms Then
            Count_40ms = 0
            Reset Flag_40ms
        End If
    End If

    If Flag_2_25ms = 1 Then                                 ' 2,25мс пауза
        Incr Count_2_25ms
        If Count_2_25ms = Preset_2_25ms Then
            Count_2_25ms = 0
            Reset Flag_2_25ms
        End If
    End If

    If Flag_110ms = 1 Then                                  ' Длина пакета на повторе
        Incr Count_110ms
        If Count_110ms = Preset_110ms Then
            Count_110ms = 0
            Reset Flag_110ms
        End If
    End If


Return



'-------------------------------------------------------------------------------
' Обработка подпрограммы
'-------------------------------------------------------------------------------
Sub Nec_send_command(nec_add0 As Byte , Nec_add1 As Byte , Nec_cmd0 As Byte , Nec_cmd1 As Byte)       ' Отрпавка кода NEC

    Set Nec_repeat_flag                                     ' Сразу разрешаем повтор отправки NEC данных, пока нажата кнопка

    Set Flag_9ms                                            ' Начало отсчета 9 мс
    Tccr0a.com0a0 = 1                                       ' Включение модуляции
    Do                                                      ' Ждем окончания отрезка времени
    Loop Until Flag_9ms = 0

    Set Flag_4_5ms                                          ' Начало отсчета 4,5 мс
    Do                                                      ' Ждем окончания отрезка времени
    Loop Until Flag_4_5ms = 0

    Nec_bit_send = 0                                        ' Обнуляем кол-во отправленных бит
    Do                                                      ' Отправка бит данных
        Incr Nec_bit_send                                   ' Считаем количество бит отправленных данных
        Select Case Nec_bit_send                            ' Определение отправляемого байта
            Case 1
                Send_byte = Nec_add0
            Case 9
                Send_byte = Nec_add1
            Case 17
                Send_byte = Nec_cmd0
            Case 25
                Send_byte = Nec_cmd1
        End Select

        Set Flag_562_5us                                    ' Начало отсчета 562,5 мкс. Передача данных
        Tccr0a.com0a0 = 1                                   ' Включение модуляции
        Do
        Loop Until Flag_562_5us = 0

        If Send_byte.0 = 1 Then Set Flag_1_6875ms Else Set Flag_562_5us       ' В зависимости от значения передаваемого бита устанавливается длина паузы
        Shift Send_byte , Right                             ' Сдвиг битов вправо
        Do
        Loop Until Flag_562_5us = 0 And Flag_1_6875ms = 0   ' Ждем окончания отрезка времени
    Loop Until Nec_bit_send = 32

    Set Flag_562_5us                                        ' Начало отсчета 562,5 мкс. Обозначим окончание передачи последнего бита данных
    Tccr0a.com0a0 = 1                                       ' Включение модуляции
    Do
    Loop Until Flag_562_5us = 0

    Set Flag_40ms                                           ' Начало отсчета 40 мс   - окончание посылки для повтора
    Do                                                      ' Ждем окончания отрезка времени
    Loop Until Flag_40ms = 0
End Sub

'-------------------------------------------------------------------------------
' Обработка подпрограммы
'-------------------------------------------------------------------------------
Sub Nec_send_repeat()                                       ' Повтор отправки NEC
    Set Flag_110ms                                          ' Начало отсчета 110 мс
    Set Flag_9ms                                            ' Начало отсчета 9 мс
    Tccr0a.com0a0 = 1                                       ' Включение модуляции
    Do                                                      ' Ждем окончания отрезка времени
    Loop Until Flag_9ms = 0
    Set Flag_2_25ms                                         ' Начало отсчета 2,25 мс
    Do                                                      ' Ждем окончания отрезка времени
    Loop Until Flag_2_25ms = 0
    Set Flag_562_5us                                        ' Начало отсчета 562,5 мкс. Модуляция
    Tccr0a.com0a0 = 1                                       ' Включение модуляции
    Do
    Loop Until Flag_562_5us = 0
    Do
    Loop Until Flag_110ms = 0
End Sub


'-------------------------------------------------------------------------------
' Прерывание от TIMER1 каждые 0.262144 сек
'-------------------------------------------------------------------------------
Timer1_int:
    If Button = 0 Then
        Set Start_send_flag                                 ' Разрешаем отправки NEC данных
        Set Led                                             ' Индикация
    Else
        Reset Start_send_flag                               ' Останавливаем отправку NEC данных
        Reset Nec_repeat_flag                               ' Сбрасываем флаг повтора
        Reset Led                                           ' Индикация
    End If

Return

Настройка таймеров напрямую регистрами.
http://s3.uploads.ru/t/m5BKY.jpg
http://sd.uploads.ru/t/mMvdt.jpg
http://sf.uploads.ru/t/LAD6K.jpg
http://s1.uploads.ru/t/6yvLR.jpg
http://s6.uploads.ru/t/EOkqN.jpg

Управление таймером2 аналогичное.

Отредактировано MACTEPok (2016-05-13 15:44:14)

0

3

Mrshilov, спасибо. А есть такое же для передачи?

0

4

задача в лучших традициях извращенства. Устройство должно запомнить команды от нескольких пультов. Затем на это устройство через ардуиновский шилд Ehternet  будут приходить задания воспроизводить NEC команды.
Начальник хочет управлять TV приставкой и сопутствующими приблудами. Приставка одна, теликов 2. Задача переключать каналы на приставке, находясь у телика (телик №2 находится в другом помещении и этаже)

Отредактировано MACTEPok (2016-05-13 20:41:38)

0

5

Классный подход, мне понравился. На асме перепишу для себя, штоб побыстрее работало.

0

6

Пробовал разные варианты но никак не могу принять коммандыс пульта-что нетак не пойму,что может быть не так?

Код:
$regfile = "m328pdef.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 24
$framesize = 24

'-------------------------------------------------------------------------------
' Конфигурация LCD
'-------------------------------------------------------------------------------
Config Lcdpin = Pin , Rs = Portd.4 , E = Portb.6 , Db4 = Portb.7 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7
Config Lcd = 16 * 2       'используем дисплей на 2 строчки по 16 знакомест в каждой
lcd_led alias portb.1 : config lcd_led = output : lcd_led = 1
Irrec_pwr alias portd.1 : config Irrec_pwr = output : Irrec_pwr = 1
'-------------------------------------------------------------------------------
  Initlcd                                                   ' Инициализируем LCD
  Waitms 50                                                 ' Ждем пока все запустится
  Cursor Off Noblink                                        ' Выключаем неморгающий курсор
  Cls                                                       ' Очистка экрана
'-------------------------------------------------------------------------------
'       Конфигурация портов
'-------------------------------------------------------------------------------
Led Alias Portb.5                                           ' Индикатор приема пульта
Ir_in Alias Pind.2                                          ' Вход от IR датчика
Config Ir_in = Input
Set Ir_in
Config Led = Output
Reset Led
'-------------------------------------------------------------------------------
' Конфигурация таймеров
'-------------------------------------------------------------------------------
'Config Timer0 = Timer , Prescale = 256                                         ' 16000000/256 = 62500
'Tccr0b.cs02 = 1                                                                ' Запуск таймера с Prescale = 256


'-------------------------------------------------------------------------------
' Настройка прерываний
'-------------------------------------------------------------------------------
Config Int0 = Falling                                       'Прерывание по спаду
On Timer0 Tikers                                            'работа по таймеру
On Int0 Infrared                                            'работа по прерыванию
'-------------------------------------------------------------------------------
' Запуск прерываний
'-------------------------------------------------------------------------------
Enable Timer0                                               'разрешаем работу таймера0
Enable Int0                                                 'разрешаем работу прерывания0
Enable Interrupts                                           'Разрешаем прерывания
'-------------------------------------------------------------------------------
' Опеределение переменных
'-------------------------------------------------------------------------------
Dim Tik As Word                                             'счётчик тиков таймера
Dim Byt As Byte                                             'счётчик принятых бит
Dim Repeat_flag As Bit                                      'флаг повтора
Dim Start_flag As Bit                                       'флаг стартового условия
Dim Address As Byte                                         'байт адреса
Dim Address_inv As Byte                                     'байт адреса инверт
Dim Command As Byte                                         'байт команды
Dim Command_inv As Byte                                     'байт команды инверт
Dim Address_1 As Byte                                       'прямой байт адреса
Dim Command_1 As Byte                                       'прямой байт команды
Dim Address_0 As Byte                                       'инверсный байт адреса
Dim Command_0 As Byte                                       'инверсный байт команды
Dim Checked_flag As Bit                                  'флаг успешного приема команды
Dim Summa As Word
Dim S1 As String * 10
Dim S2 As String * 10
'-------------------------------------------------------------------------------

Set Led
Waitms 2000
Reset Led
Set Checked_flag                                            ' Для первоначального вывода на LCD
Do
    If Checked_flag = 1 Then
        Locate 1 , 1
        Lcd "Add:" ; Format(s1 , "       ")
        Locate 2 , 1
        Lcd "Com:" ; Format(s2 , "       ")
        Reset Checked_flag
    End If
    If Repeat_flag = 1 Then                                 ' Индикация NEC повтора
        Locate 2 , 13
        Lcd "R"
    Else
         Locate 2 , 13
        Lcd " "
    End If
Loop
End
'*******************************************************************************
 Tikers:                                                    'работа по таймеру
 Timer0 = 253       '62500/(256-250)=10416,66 Hz (96 мкс)
                                                             '252 - TV SAMSUNG, 250 - DVD SAMSUNG и другие NEC
 Incr Tik
 If Tik >= 1200 Then                                        'если время паузы (без сигнала) больше 110 мс, то прекращаем прием данных
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 0
 Command_1 = 0
 Address_0 = 0
 Command_0 = 0
 Reset Led
 Stop Timer0                                                'останавливаем таймер
 End If
  Return
'*******************************************************************************
 Infrared:                                                  'работа по прерыванию
  Tccr0b.cs02 = 1                                           'Start Timer0  'запускаем таймер
  Set Led
  If Tik >= 139 And Tik < 150 Then                          'если случилось от 139 до 150 тиков - "СТАРТ"
      Address = 1
      Repeat_flag = 0
      Start_flag = 1
      Address_1 = 0
      Command_1 = 0
      Address_0 = 0
      Command_0 = 0
  End If
  If Tik >= 116 And Tik < 139 Then                          'если случилось от 116 до 138 тиков - "ПОВТОР"
      Repeat_flag = 1
      Start_flag = 0
  End If
  If Tik >= 22 And Tik < 116 And Start_flag = 1 Then        'если случилось от 22 до 115 тиков - приняли "1"
   Incr Byt
    If Byt < 9 Then
     Shift Address_0 , Right
     Address_0.7 = 1
    End If
    If Byt >= 9 And Byt < 17 Then
     Shift Address_1 , Right
     Address_1.7 = 1
    End If
    If Byt >= 17 And Byt < 25 Then
     Shift Command_0 , Right
     Command_0.7 = 1
    End If
    If Byt >= 25 Then
     Shift Command_1 , Right
     Command_1.7 = 1
    End If
  End If
  If Tik >= 10 And Tik < 22 And Start_flag = 1 Then         'если случилось от 10 до 21 тика - приняли "0"
   Incr Byt
    If Byt < 9 Then
     Shift Address_0 , Right
    End If
    If Byt >= 9 And Byt < 17 Then
     Shift Address_1 , Right
    End If
    If Byt >= 17 And Byt < 25 Then
     Shift Command_0 , Right
    End If
    If Byt >= 25 Then
     Shift Command_1 , Right
    End If
  End If
 Tik = 0
  If Byt = 32 Then                                          'если приняли 4 байта, проверяем правильность приёма команды
                                                             'если адрес 16-ричный, проверка не проходит
    Address = Address_0
    Address_inv = Address_1
    S1 = Str(address)
    S1 = S1 + " "
    S1 = S1 + Str(address_inv)
    Summa = Command_0 + Command_1
        If Summa = 255 Then                                 ' Если сумма байт команды дает 255, значит данные приняты корректно
            Command = Command_0
            Command_inv = Command_1
            S2 = Str(command)
            S2 = S2 + " "
            S2 = S2 + Str(command_inv)
            Set Checked_flag
        Else
            Command = 0
            Command_inv = 0
            S2 = "err"
        End If
  Byt = 0
  Repeat_flag = 0
  Start_flag = 0
  Stop Timer0                                               'останавливаем таймер
  End If
 Return

Отредактировано bulat943 (2018-09-09 19:19:04)

0

7

При нажатии любой кнопки пишет повтор- "R"

0

8

bulat943, как минимум камень работает в 2 раза медленнее (исходник на 16 МГц), а тайминги не подогнал на частоту 8 МГц.

0

9

bulat943 написал(а):

Пробовал разные варианты но никак не могу принять коммандыс пульта-что нетак не пойму,что может быть не так?

А какой пульт используете ? Если самсунг, попробуйте TIMER0 = 254.

bulat943 написал(а):

При нажатии любой кнопки пишет повтор- "R"

С самсунгом у меня то же самое было. Samsung и NEC это не одно и то же. У них по разному реализован повтор команд при удержании кнопки.

код повтора в протоколе NEC

При удержании кнопки посылка повторно не передаётся. Вместо этого каждые 110 мс передаётся специальный код повтора.

А как реализован повтор команд у Samsung я не нашел. Здесь пример, который у меня работает и с Samsung и с NEC.

0

10

Пульт точно NEC- здесь работает отлично,пульт от тв FUSION

0

11

Не пойму-что не так!!!фузы на 8 МГц,не работает,сдул атмега328р,впаял атмега8,в программе изменил

Код:
$regfile = "m8adef.dat"

,откомпилировал,прошил-все работает как надо...

0

12

В M238p еще делитель DIV8 во фьюзах есть.

0

13

И программно прямо из кода можно делить тактовую частоту в 328 меге )))

0

14

я прекрасно знаю про CKDIV8,я же написал-фузы на 8 МГц,если б делитель был включен то я б написал что фузы на 1 МГц и тогда мой усб-асп просто не видел бы атмега328 (без перемычки SLOW SCK)
включил CKOUT-частота 7,950 МГц а не 8 мгц,может в этом дело?

0

15

Код:
'Config Timer0 = Timer , Prescale = 256                                         ' 16000000/256 = 62500


На 8 МГц и 16 МГц это разные периоды

0

16

Одинаково
Так посчитайте у себя и у меня-частота одинаковая -
у вас-

$crystal = 16000000
Config Timer0 = Timer , Prescale = 256 
в цикле обработчике прерывания  Timer0 = 250,значит частота 16000000/256/(256-250)=10416,66666666667 гц

у меня-
$crystal = 8000000
Config Timer0 = Timer , Prescale = 256
в цикле обработчике прерывания  Timer0 = 253,значит частота 8000000/256/(256-253)=10416,66666666667 гц

Отредактировано bulat943 (2018-09-11 15:37:19)

0

17

Ок.
А с мегой8 все работает штатно?
Значит с камнем 328 глюк?

0

18

C Aтмега8 все отлично,но у меня не поместится программа,ставил две атмега328р-ответ "R" и все-хоть убей...
думаю сделать замер таймингов с пульта в атмега328,может так собака зарыта...

0

19

Если бы был серьезный глюк с таймингами, то в диапазон

Код:
If Tik >= 116 And Tik < 139 Then                          'если случилось от 116 до 138 тиков - "ПОВТОР"

не попали, было бы переполнение:

Код:
If Tik >= 1200 Then                                        'если время паузы (без сигнала) больше 110 мс, то прекращаем прием данных
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 0
 Command_1 = 0
 Address_0 = 0
 Command_0 = 0
 Reset Led
 Stop Timer0                                                'останавливаем таймер
 End If


Схема подключения ИК приемника верная? С подтяжками к +Uпит все в норме?

0

20

схема верная,подтяжка 4,7 ком (пробовал 10 ком-все так же,импульсыидут с фотоприемника-смотрел осциллографом HANTEK DSO5102P)
накидал программку для атмега8,замер таймингов-во время старт-импульса успевает досчитать до 141,лог ноль-до 12,лог один-до 23-24,сдую феном и впаяю атмегу328р,посмотрю сколько получится...

0

21

Впаял атмега328р,проверил,старт-импульс=137-138!!! вот он и пишет повтор!
лог 0=11-12,лог 1=22-23
вписал

Код:
If Tik >= 116 And Tik < 137 Then 

-заработало!!!

0

22

хм. странно оно как то

0

23

Код:
$regfile = "m8adef.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 40
$framesize = 40

$baud = 9600

Dim Temp As Byte , Tiki As Byte , Temp2 As Byte , Temp3 As Byte , Temp_tx As Byte
Dim Data_1 As Byte , Data_2 As Byte , Data_3 As Byte , Data_4 As Byte

Declare Function Rx() As Byte



Config Portb = Output


Ir_signal Alias Pind.3                                      ' Подключение ИК-приёмника
Config Ir_signal = Input

Led Alias Portb.0                                           '  св.диод
'Config Led = Output





Print
Print "!@"

Start_prg:


      Bitwait Ir_signal , Set                               ' Ждём сигнал = 1...

       Aa:
       Temp = 248                                           ' Ждём _длинную_ паузу в сигнале >7500 us!
       Ab:
       If Ir_signal = 1 Then Goto Aa
       Waitus 22

       Decr Temp : If Temp > 1 Then Goto Ab

       Bb:
       Temp = 100                                           ' Ждём _длинный  сигнал
       Bc:
       If Ir_signal = 0 Then Goto Bb
       Waitus 22

       Decr Temp : If Temp > 1 Then Goto Bc

   Led = 0
       Bitwait Ir_signal , Reset                            ' Ждем завершения сигнала

       Data_1 = Rx()
       Data_2 = Rx()
       Data_3 = Rx()
       Data_4 = Rx()

      Print Data_1 ; "  " ; Data_2 ; "  " ; Data_3 ; "  " ; Data_4

  Led = 1

Waitms 150

Goto Start_prg                                              ' >>>>>>>>>>>>>>>>>>>






' ======    ПРИЕМ КОМАНД ИК-ПУЛЬТА   =======
Function Rx() As Byte
 Local Tiki As Byte , Temp3 As Byte
 Rx = 0

 For Temp3 = 7 To 0 Step -1
       Bitwait Ir_signal , Set                              ' Ждём сигнал = 1...
       Waitus 270
       Tiki = 0
        While Ir_signal = 1
            Incr Tiki
            Waitus 7
        Wend

        If Tiki > 100 Then Rx.temp3 = 1                     'длинный -> бит =1
       Bitwait Ir_signal , Reset                            ' Ждем завершения сигнала

  Next Temp3

End Function

0

24

У меня нет на телевизоре часов,а так хочется чтоб утром в 6.15 включался телевизор,вот и решил собрать часы-ночник со встроенным будильником,который при срабатывании будет включать телевизор   
Здесь конечно можно обойтись и аттини13+ds1307,но это слишком просто и потому не интересно,решил усложниться-вытравил и спаял плату,на ней атмега328р,жки WH-1602,ЧРВ DS1307,фотоприемник и ик-светодиод( еще стоит RDA5807,но я пока  ее не буду использовать)
Прочитал статью ,но у меня пульт NEC и незачем так усложнять программу

теперь дело за выдачей комманд с помощью ик-светодиода...

0


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » NEC протокол. Прием и передача