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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Тестю индикатор. Правильная обработка прерываний. Как сделать?


Тестю индикатор. Правильная обработка прерываний. Как сделать?

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

1

Собрал на макетке схему семисегментного индикатора на 4 разряда с обвязкой( для выбора разрядов  ключи pnp с резисторами 1 кОм на базе, выводы сегментов через резисторы 1кОм). Получилось 4 вывода для управления выбором разрядов, 8 выводов для управления сегментами. Активный уровень управления 0 В.
Решил сделать тестовую прошивку. Начальные числа для разрядов 0, 1, 2, 3. Каждую секунду происходит инкремент числа каждого разряда. Использую динамическую индикацию, поэтому нужно переключать разряды с частотой 400 Гц(4 разряда х 100 раз в секунду для одного разряда).
Использовал два таймера в режиме совпадения - таймер1 для периода 1с( 1 Гц), таймер0 для частоты 400 Гц. Таймер1 генерирует прерывания для инкремента значений разрядов. Таймер0 отвечает за динамическую индикацию и не генерирует прерываний, а только устанавливает флаг совпадения, поэтому проверку флага и перебор разрядов нужно производить в основном цикле.
Правильно я сделал? Прошивку не тестировал ещё( боюся ;-)).
Главный вопрос - если несколько источников прерываний срабатывают одновременно, как они срабатывают по приоритету? Сначала обрабатывается прерывание с большим приоритетом, а с меньшим приоритетом затем обрабатывается автоматически или нужны махинации с регистрами? Может, поделитесь ссылками на примеры с несколькими источниками прерываний.

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000

Declare Sub View(byval Digit_value As Byte , Byval Number_digit As Byte , Byval Dp_view As Byte)
' процедура вывода сегментов для отдельного разряда

Dim Digit1 As Byte , Digit2 As Byte , Digit3 As Byte , Digit4 As Byte ' значения разрядов
Dim Dp As Byte ' флаг отображения точки
Dim Next_digit As Byte ' номер отображаемого разряда в данный момент времени
Dim View_flag as Byte ' флажок в неоходимости изменения сегментов

Digit1 = 0 : Digit2 = 1 : Digit3 = 2 : Digit4 = 3
Dp = 0
Next_digit = 1 : View_flag = 0 

Restore Digits

Config Portb = Output ' управление разрядами
Config Portd = Output ' управление сегментами

Config Portb.5 = Output
Config Timer1 = Timer , Prescale = 256 , Compare_a = Disconnect , Clear_timer = 1
Compare1a = 62500  ' 1 sec
On Oc1a Pr1

Config Timer0 = Timer , Prescale = 256 , Compare_a = Disconnect , Clear_timer = 1
Ocr0a = 155   ' 400Hz

Enable Oc1a
Enable Interrupts
Start Timer1
Start Timer0

Do
   If Tifr0.1 = 1 Then
      Next_digit = Next_digit + 1
      View_flag = 1                                       ' разряд изменился - сегменты надо обновить на другие
      Tifr0.1 = 1                                           ' сброс флага ocr1a
   End If
   If Next_digit > 4 Then
      Next_digit = 1
   End If
   If View_flag = 1 Then
      Select Case Next_digit
         Case 1 : Call View(digit1 , Next_digit , 0)        
         Case 2 : Call View(digit2 , Next_digit , 0)
         Case 3 : Call View(digit3 , Next_digit , 0)
         Case 4 : Call View(digit4 , Next_digit , 0)
      End Select
   View_flag = 0 ' сброс флажка обновления
   End If
Loop

Sub View(digit_value As Byte , Number_digit As Byte , Dp_view As Byte)
'Local L1 As Byte
'L1 = Number_digit
Portd = 255
Select Case Number_digit
   Case 1 : Portb = &B00001110
   Case 2 : Portb = &B00001101
   Case 3 : Portb = &B00001011
   Case 4 : Portb = &B00000111
End Select
Portd = Lookup(digit_value , Digits)
End Sub

Pr1:
Digit1 = Digit1 + 1
Digit2 = Digit2 + 1
Digit3 = Digit3 + 1
Digit1 = Digit4 + 1
If Digit1 > 9 Then
   Digit1 = 0
End If
If Digit2 > 9 Then
   Digit2 = 0
End If
If Digit3 > 9 Then
   Digit3 = 0
End If
If Digit4 > 9 Then
   Digit4 = 0
End If
Return

End

Digits:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

Отредактировано Sikorsky (2017-04-12 23:16:21)

0

2

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

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


"Кто раньше встал, того и тапки". У Atmega нет приоритетов на прерывания. Обрабатывается первое поступившее, затем все последующие, они не пропадают, если конечно не сбросить флаг о происшедшем прерывании.

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

Может, поделитесь ссылками на примеры с несколькими источниками прерываний

Варианты

Семисегментные индикаторы

Отредактировано sasha_1973 (2017-04-13 05:30:33)

0

3

Протестил индикатор. Программу изменил. Всё завязано на один таймер теперь.

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
Declare Sub View(byval Digit_value As Byte , Byval Number_digit As Byte , Byval Dp_view As Byte)

Restore Digits
Config Portd = Output
Portd = 255
Config Portb = Output
Portb = 0
Dim Var As Byte , Buffer As Word
Dim Digit1 As Byte , Digit2 As Byte , Digit3 As Byte , Digit4 As Byte       ' значения разрядов
Dim Dp As Byte                                              ' флаг отображения точки
Dim Next_digit As Byte

Digit1 = 0 : Digit2 = 1 : Digit3 = 2 : Digit4 = 3
Dp = 0
Next_digit = 1

Var = 0
Buffer = 62500
On Oc1a Pr
Ocr1ah = High(buffer)
Ocr1al = Low(buffer)
Tccr1a = 0
Tccr1b = 12
Enable Oc1a
Enable Interrupts

Do
If Next_digit < 4 Then
Next_digit = Next_digit + 1
Else
Next_digit = 1
End If
Select Case Next_digit
   Case 1 : Call View(digit1 , Next_digit , 0)
   Case 2 : Call View(digit2 , Next_digit , 0)
   Case 3 : Call View(digit3 , Next_digit , 0)
   Case 4 : Call View(digit4 , Next_digit , 0)
End Select
Waitms 5
Loop

Sub View(digit_value As Byte , Number_digit As Byte , Dp_view As Byte)
Portd = 255
Select Case Number_digit
   Case 1 : Portb = &B00001110
   Case 2 : Portb = &B00001101
   Case 3 : Portb = &B00001011
   Case 4 : Portb = &B00000111
End Select
Portd = Lookup(digit_value , Digits)
End Sub
Pr:

If Digit1 < 9 Then
   Digit1 = Digit1 + 1
Else
   Digit1 = 0
End If

If Digit2 < 9 Then
   Digit2 = Digit2 + 1
Else
   Digit2 = 0
End If

If Digit3 < 9 Then
   Digit3 = Digit3 + 1
Else
   Digit3 = 0
End If

If Digit4 < 9 Then
   Digit4 = Digit4 + 1
Else
   Digit4 = 0
End If

Return

End

Digits:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

0

4

Фото собранной макетной платы.
http://sf.uploads.ru/t/Tfj2o.png

0

5

Очень странный метод реализации динамической индикации.
Совершено не понятно для чего нужно использовать два таймера, а динамическую индикацию осуществлять в основном цикле. Как до такого можно додуматься? :O  Это же вообще не логично... :dontknow:

Динамическая индикация на примере термометра вместе с проектом для протеуса. http://pure-basic.narod.ru/forum_files/ … mo_Led.rar

Код:
$regfile = "m8def.dat"                                      ' Выбор типа контроллера.
$crystal = 1000000                                          ' Частота генератора, Гц.
$hwstack = 50                                               ' Размер аппаратного.
$swstack = 30                                               ' и программных стеков.
$framesize = 40

Declare Sub Termo()

'Config Base = 0
Config 1wire = Portb.0
Config Portd = Output
Config Portc = Output

Dim Dinamindex As Byte
Dim Temp As Byte
Dim Dinaminfo(4) As Byte
Dim 1wire_array(9) As Byte                                  ' Объявление массивов
Dim Currenttermo As Word At 1wire_array Overlay

Portc = 0
For Temp = 1 To 4
 Dinaminfo(temp) = 10
Next Temp


Config Timer0 = Timer , Prescale = 64                       ' Конфигурация таймера Timer1.
On Timer0 Dinam                                             'Nosave                                      ' Назначение подпрограммы прерываний от Timer1
Enable Timer0                                               ' Разрешение прерываний от Timer1

Enable Interrupts

Do
   1wreset                                                  ' Сброс датчика.
   1wwrite &HCC                                             ' Команда "Skip ROM".
   1wwrite &H44                                             ' Команда "Convert  T".
   Waitms 800
   1wreset                                                  ' Сброс датчика.
   1wwrite &HCC                                             ' Команда "Skip ROM"
   1wwrite &HBE
   1wire_array(1) = 1wread(2)
   If Err = 0 Then                                          '1wire_array(9) = Crc8(1wire_array(1) , 8) Then
     Call Termo()
   End If
Loop
End

Sub Termo()
  Stop Timer0

   If 1wire_array(2).7 = 1 Then
     Toggle Currenttermo
     Incr Currenttermo
     Dinaminfo(4) = 10
   Else
     Dinaminfo(4) = 11
   End If

   Temp = 1wire_array(1) And 15
   Dinaminfo(1) = Lookup(temp , Ds_dec)
   Shift Currenttermo , Right , 4
   Dinaminfo(2) = 1wire_array(1) Mod 10
   Dinaminfo(3) = Currenttermo / 10

 Start Timer0
End Sub


Dinam: ' Обработчик прерывания от Timer0 - динамическая индикация.

 DinamIndex = DinamIndex + 1
 If Dinamindex > 4 Then Dinamindex = 1

 Temp = Dinaminfo(dinamindex)

 Portc = 0
 Portd = Lookup(temp , Ind)
 If Dinamindex = 2 Then Portd.7 = 0
 Temp = 1
 Decr Dinamindex
 Shift Temp , Left , Dinamindex
 Incr Dinamindex

 Portc = Temp

Return

Ind:
Data &B11000000                                             ' 0
Data &B11111001                                             ' 1
Data &B10100100                                             ' 2
Data &B10110000                                             ' 3
Data &B10011001                                             ' 4
Data &B10010010                                             ' 5
Data &B10000010                                             ' 6
Data &B11111000                                             ' 7
Data &B10000000                                             ' 8
Data &B10010000                                             ' 9
Data &B10111111                                             ' -
Data &B11111111                                             ' Пусто

Ds_dec:
Data 0 , 1 , 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 , 6 , 7 , 7 , 8 , 9 , 9

+1

6

Накинулись... сами-то раньше вопросы и похуже задавали  :D
Пусть человек учится а остальное со временем придёт, и прерывания тоже  :flag:

+1

7

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

Протестил индикатор. Программу изменил. Всё завязано на один таймер теперь


Если не секрет, чего это должно получиться ?

0

8

Сделал версию демо-программы, в которой все основные действия вынес в прерывания. Каждую секунду инкрементируется значение каждого разряда. А так хочу кодовый замок сделать, но не обычный, а квестовый.

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
Declare Sub View(byval Digit_value As Byte , Byval Number_digit As Byte , Byval Dp_view As Byte)

Restore Digit_segments
Config Portd = Output
Portd = 255
Config Portb = Output
Portb = 0

Dim Current_digit As Byte , I As Word
Dim Digits(4) As Byte                                       ' çíà÷åíèÿ ðàçðÿäîâ
Dim Dp As Byte                                              ' ôëàã îòîáðàæåíèÿ òî÷êè
Dim Next_digit As Byte

Digits(1) = 0 : Digits(2) = 1 : Digits(3) = 2 : Digits(4) = 3
Dp = 0
Next_digit = 1:


On Oc1a Pr_1
Ocr1ah = High(62500)
Ocr1al = Low(62500)
Tccr1a = 0
Tccr1b = 12

On Oc2a Pr_2
Ocr2a = 200
Tccr2a = 2
Tccr2b = 5

Enable Oc1a
Enable Oc2a
Enable Interrupts

Do
Waitms 5
Loop

Sub View(digit_value As Byte , Number_digit As Byte , Dp_view As Byte)
Portd = 255
Select Case Number_digit
   Case 1 : Portb = &B00001110
   Case 2 : Portb = &B00001101
   Case 3 : Portb = &B00001011
   Case 4 : Portb = &B00000111
End Select
Portd = Lookup(digit_value , Digit_segments)
End Sub

Pr_1:

For I = 1 To 4
If Digits(i) < 9 Then
   Digits(i) = Digits(i) + 1
Else
   Digits(i) = 0
End If
Next I

Return

Pr_2:

If Next_digit < 4 Then
Next_digit = Next_digit + 1
Else
Next_digit = 1
End If
Call View(digits(next_digit) , Next_digit , 0)
Return

End

Digit_segments:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

0

9

Изучил ацп для авра. Сделал делитель напряжения на переменном резисторе и подключил к ардуино. Первый разряд индикатора показывает степень поворота ручки переменного резистора.

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
Declare Sub View(byval Digit_value As Byte , Byval Number_digit As Byte , Byval Dp_view As Byte)

Restore Digit_segments
Config Portd = Output
Portd = 255
Config Portb = Output
Portb = 0

Dim Current_digit As Byte , I As Word
Dim Digits(4) As Byte                                       ' значения разрядов
Dim Dp As Byte                                              ' флаг отображения точки
Dim Next_digit As Byte
Dim Value As Byte

Digits(1) = 0 : Digits(2) = 0 : Digits(3) = 0 : Digits(4) = 0
Dp = 0
Next_digit = 1:

Didr0 = 1
Admux = 32
Adcsra = 199

On Oc2a Pr
Ocr2a = 200
Tccr2a = 2
Tccr2b = 5

Enable Oc2a
Enable Interrupts

Do
Value = Adch
Adcsra = 199
If Value < 25 Then
Digits(1) = 0
Elseif Value < 52 Then
Digits(1) = 1
Elseif Value < 77 Then
Digits(1) = 2
Elseif Value < 102 Then
Digits(1) = 3
Elseif Value < 127 Then
Digits(1) = 4
Elseif Value < 153 Then
Digits(1) = 5
Elseif Value < 178 Then
Digits(1) = 6
Elseif Value < 204 Then
Digits(1) = 7
Elseif Value < 229 Then
Digits(1) = 8
Elseif Value < 255 Then
Digits(1) = 9
End If
Loop

Sub View(digit_value As Byte , Number_digit As Byte , Dp_view As Byte)
Portd = 255
Select Case Number_digit
   Case 1 : Portb = &B00001110
   Case 2 : Portb = &B00001101
   Case 3 : Portb = &B00001011
   Case 4 : Portb = &B00000111
End Select
Portd = Lookup(digit_value , Digit_segments)
End Sub


Pr:

If Next_digit < 4 Then
Next_digit = Next_digit + 1
Else
Next_digit = 1
End If
Call View(digits(next_digit) , Next_digit , 0)
Return

End

Digit_segments:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

Отредактировано Sikorsky (2017-04-29 21:12:27)

0

10

Собранная установка на макетке для проверки ацп авра.
http://s5.uploads.ru/t/Mug3U.png

Отредактировано Sikorsky (2017-04-29 21:11:20)

0

11

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

Изучил цап для авра.

АЦП - Аналогово-цифровой преобразователь.

Из прерываний лучше не вызывать подпрограммы с аргументами и с локальными переменными, чтобы не было сбоев.

0

12

Пётр написал(а):

АЦП - Аналогово-цифровой преобразователь.

Спасибо за исправление.

0

13

Подключил к ардуино четыре переменных резистора на четыре канала ацп. Каждый разряд индикатора показывает степень поворота ручки резистора.

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
Declare Sub View(byval Digit_value As Byte , Byval Number_digit As Byte , Byval Dp_view As Byte)
Declare Function Getdigit(byval Value As Byte) As Byte


Restore Digit_segments
Config Portd = Output
Portd = 255
Config Portb = Output
Portb = 0

Dim Current_digit As Byte
Dim Digits(4) As Byte                                       ' значения разрядов
Dim Dp As Byte                                              ' флаг отображения точки
Dim Next_digit As Byte
Dim Next_channel As Byte
Dim Buffer As Byte

Digits(1) = 0 : Digits(2) = 0 : Digits(3) = 0 : Digits(4) = 0
Dp = 0
Next_digit = 0
Next_channel = 1

Didr0 = 15
Admux = 32
Adcsra = 199

On Oc2a Pr
Ocr2a = 200
Tccr2a = 2
Tccr2b = 5

Enable Oc2a
Enable Interrupts

Do

Buffer = Adch
Digits(next_channel) = Getdigit(buffer)
Next_channel = Next_channel + 1
If Next_channel > 4 Then
Next_channel = 1
End If
Buffer = Next_channel - 1
Select Case Buffer
Case 0:
Admux = 32
Case 1
Admux = 33
Case 2
Admux = 34
Case 3
Admux = 35
End Select
Adcsra = 199
Waitms 10
Loop

Sub View(digit_value As Byte , Number_digit As Byte , Dp_view As Byte)
Portd = 255
Select Case Number_digit
   Case 1 : Portb = &B00001110
   Case 2 : Portb = &B00001101
   Case 3 : Portb = &B00001011
   Case 4 : Portb = &B00000111
End Select
Portd = Lookup(digit_value , Digit_segments)
End Sub

Function Getdigit(value As Byte) As Byte
If Value < 25 Then
Getdigit = 0
Elseif Value < 52 Then
Getdigit = 1
Elseif Value < 77 Then
Getdigit = 2
Elseif Value < 102 Then
Getdigit = 3
Elseif Value < 127 Then
Getdigit = 4
Elseif Value < 153 Then
Getdigit = 5
Elseif Value < 178 Then
Getdigit = 6
Elseif Value < 204 Then
Getdigit = 7
Elseif Value < 229 Then
Getdigit = 8
Elseif Value <= 255 Then
Getdigit = 9
End If
End Function



Pr:

If Next_digit < 4 Then
Next_digit = Next_digit + 1
Else
Next_digit = 1
End If
Call View(digits(next_digit) , Next_digit , 0)
Return

End

Digit_segments:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000

0

14

Фото собранной установки. Возник вопрос - какие есть решения для силовой части кодовых замков?
http://s8.uploads.ru/t/kxHhn.jpg

0

15

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

какие есть решения для силовой части кодовых замков?

Актуатор замка двери.Дёшево и сердито)

0

16

Привет, баскомщики. Мучаю свой проект.))
Сделал аппаратный интерфейс для индикатора на сдвиговых регистрах, теперь запись данных и управление не по 12 линиям, а по 3 линиям. Плюс индикация статическая. Так как у меня индикатор на четыре разряда, то пришлось кроме сдвиговых регистров дополнить схему мультивибратором на и-не, счётчиком, дешифратором.
Текст прошивки:

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
Declare Sub Pushdigit(byval Digit_value As Byte , Byval Dp_view As Byte)
Declare Sub View
Declare Sub Clrs
Declare Function Getdigit(byval Value As Byte) As Byte

Restore Digit_segments
Config Portb = Output
Ds Alias Portb.0       ' ввод данных
St_cp Alias Portb.1       ' сохранение данных в регистр
Sh_cp Alias Portb.2       ' сдвиг и запись данных в нутрь регистра
Portb = 0

Dim Current_digit As Byte
Dim Digits(4) As Byte       ' значения разрядов
Dim Dp As Byte       ' флаг отображения точки
Dim Next_digit As Byte
Dim Next_channel As Byte
Dim Buffervalue As Byte , Count As Byte

Digits(1) = 0 : Digits(2) = 0 : Digits(3) = 0 : Digits(4) = 0
Dp = 0
Next_digit = 0
Next_channel = 1

Didr0 = 15
Admux = 32
Adcsra = 199

Call Clrs
Call View

Do
Buffervalue = Adch
Digits(next_channel) = Getdigit(buffervalue)
Next_channel = Next_channel + 1
If Next_channel > 4 Then
Next_channel = 1
End If
Buffervalue = Next_channel - 1
Select Case Buffervalue
Case 0:
Admux = 32
Case 1
Admux = 33
Case 2
Admux = 34
Case 3
Admux = 35
End Select
Adcsra = 199
For Count = 1 To 4
Call Pushdigit(digits(count) , 0)
Next Count
Call View
Loop

Sub Pushdigit(byval Digit_value As Byte , Byval Dp_view As Byte)
Local Buffer As Byte , I As Byte
Buffer = Lookup(digit_value , Digit_segments)
If Dp_view = 1 Then
Buffer = Buffer And &B01111111
End If
For I = 0 To 7       ' цикл для записи байта данных в регистр
If Buffer.7 = 0 Then
Ds = 0
Else
Ds = 1
End If       ' если седьмой (последний) бит переменной равен 0, то отправляем 0 на ввод данных. (для индикатора с ОА. Для индикатора с ОК изменить условие не противоположное, таблицу данных не трогать!)
Sh_cp = 1       ' подаем импульс на вход тактовых импульсов для сдвига регистра (запись в регистр)
Sh_cp = 0
Shift Buffer , Left , 1       ' сдвигаем все биты переменной влево на один бит
Next I
End Sub
Sub View
St_cp = 1
St_cp = 0
End Sub
Sub Clrs
Call Pushdigit(10 , 0)
Call Pushdigit(10 , 0)
Call Pushdigit(10 , 0)
Call Pushdigit(10 , 0)
End Sub
Function Getdigit(value As Byte) As Byte
If Value < 25 Then
Getdigit = 0
Elseif Value < 52 Then
Getdigit = 1
Elseif Value < 77 Then
Getdigit = 2
Elseif Value < 102 Then
Getdigit = 3
Elseif Value < 127 Then
Getdigit = 4
Elseif Value < 153 Then
Getdigit = 5
Elseif Value < 178 Then
Getdigit = 6
Elseif Value < 204 Then
Getdigit = 7
Elseif Value < 229 Then
Getdigit = 8
Elseif Value <= 255 Then
Getdigit = 9
End If
End Function

Digit_segments:
Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000
Data &B11111111

0

17

Фото собранной установки:
http://s6.uploads.ru/t/wYum9.jpg
На фото есть загадка для спектрумистов!

0

18

схему выложите, сусед :)
а то не фига не понятно...

0

19

Всем привет, пытаюсь запустить терморегулятор с установкой температуры от ик пульта по nec -стандарту, если не запускать таймер1(он закоментирован) то работает чётко, с ним виснет сразу в начале, и всё... может кто знает в чём проблема...

Код:
$regfile = "m8def.dat"
$crystal = 8000000
 $hwstack = 36
$swstack = 36
$framesize = 40                                             'внутренний генератор
'$lib "lcd4.lbx"
 $lib "mcsbyte.lbx"
            'Config Timer1 = Timer , Prescale = 8 : On Timer1 Pulse : Enable Timer1
 Main:
Config Lcdpin = Pin , Rs = Portd.0 , E = Portd.1 , Db4 = Portd.4 , Db5 = Portb.6 , Db6 = Portb.7 , Db7 = Portd.5
Config Lcd = 16 * 2
 Initlcd
      Cursor Off
Cls
Locate 1 , 4
Lcd "NEC DECODER"
Locate 2 , 4
Lcd "BASCOM-AVR"
Waitms 500

Config Timer0 = Timer , Prescale = 256                      '8000000/256=31250 Hz
Config Int0 = Falling                                       'Interruption on Falling
Stop Timer0
Enable Timer0
Enable Int0
Enable Interrupts
On Timer0 Tikers                                            'work on timer
On Int0 Infrared
'Config Portd.3 = Output
'Set Portd.2
Config 1wire = Portc.5
'Config Portb.1 = Output
'Config Portb.3 = Output , Portc.5 = Output
   Dim I As Byte , X As Byte
 Dim Byte0 As Byte
Dim Byte1 As Byte
     Dim T As Byte
Dim T1 As Single
Dim T2 As Single                                          'work on interruption
Dim Got As Bit
Dim Tik As Word                                             'counter of teaks of timer
Dim Byt As Byte                                             'counter accepted bit
Dim Repeat_flag As Bit                                      'flag of repetition
Dim Start_flag As Bit                                       'flag of start condition
Dim Address_1 As Byte                                       'direct byte of address
Dim Command_1 As Byte                                       'direct byte of command
Dim Address_0 As Byte                                       'indirect byte of address
Dim Command_0 As Byte                                       'indirect byte of command
Dim Summa As Word
Dim Address_nec As Byte , Command_nec As Byte
Dim Тик As Byte
Cursor Off
Cls                                                         'Switch Off cursor
'################################################################################################################

Do
Incr Тик
If Тик => 100 Then Gosub Термо

Portb.1 = 0
Portb.3 = 0                                                 'Main cycle
  Locate 1 , 1
   Lcd "ADDRESS " ; Address_nec
   Locate 2 , 1
   Lcd "COMMAND " ; Command_nec
        Lcd "=" ; I ; "  "
  If Command_nec = 192 Then Goto Main
   'If Command_nec = 144 Then Sound Portc.5 , 50 , 122

  'If Command_nec = 176 Then Sound Portc.5 , 150 , 60


If Got = 1 Then
              Portd.7 = 1
         ' Command_nec = Command_nec And &B01111111
              Waitms 20
              Toggle Portd.7
   Locate 1 , 1
 Lcd "ADDRESS " ; Address_nec
   Locate 2 , 1
   Lcd "COMMAND " ; Command_nec
                                             'Lcd ADDRESS and COMMAND
   Reset Got
End If


Waitms 20                                                   'Delay 10 en
Loop
End                                                         'End of main cycle

'################################################################################################################

 Tikers:                                                    'work on timer
 Timer0 = 253                                               '31250/(256-253)=10416,66 Hz (96 een)
 Incr Tik
 If Tik >= 1200 Then                                        'if 1200 teaks, have thrown all in source condition
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 255
 Command_1 = 255
 Address_0 = 0
 Command_0 = 0
 Address_nec = 255
 Command_nec = 255
 Stop Timer0
 End If
 Return
'################################################################################################################

 Infrared:                                                  'work on interruption
 Start Timer0

 If Tik >= 139 And Tik < 150 Then                           'if has happenned from 139 before 150 teaks - "START"
  Address_nec = 1
  Repeat_flag = 0
  Start_flag = 1
  Address_1 = 255
  Command_1 = 255
  Address_0 = 0
  Command_0 = 0
  Portb.1 = 1
 End If

 If Tik >= 116 And Tik < 139 Then                           'if has happenned from 116 before 138 teaks - "REPETITION"
  Address_nec = 0
  Repeat_flag = 1
  Start_flag = 0
 End If

 If Tik >= 22 And Tik < 116 And Start_flag = 1 Then         'if has happenned from 22 before 115 teaks - have taken "1"
   Incr Byt

   If Byt < 9 Then
      Shift Address_1 , Left
      Address_1 = Address_1 + 1
   End If

   If Byt >= 9 And Byt < 17 Then
      Shift Address_0 , Left
      Address_0 = Address_0 + 1
   End If

   If Byt >= 17 And Byt < 25 Then
      Shift Command_1 , Left
      Command_1 = Command_1 + 1
   End If

   If Byt >= 25 Then
      Shift Command_0 , Left
      Command_0 = Command_0 + 1
   End If
 End If

 If Tik >= 10 And Tik < 22 And Start_flag = 1 Then          'if has happenned from 10 before 21 teaks - have taken "0"
    Incr Byt
    If Byt < 9 Then
      Shift Address_1 , Left
    End If

    If Byt >= 9 And Byt < 17 Then
       Shift Address_0 , Left
    End If

    If Byt >= 17 And Byt < 25 Then
       Shift Command_1 , Left
    End If

    If Byt >= 25 Then
       Shift Command_0 , Left
    End If
 End If

 Tik = 0

 If Byt = 32 Then
   Address_nec = Address_1
   Command_nec = Command_1
   Set Got
   Address_1 = 255
   Command_1 = 255
   Byt = 0
   Repeat_flag = 0
   Start_flag = 0
   Stop Timer0
   Portb.3 = 1
 End If

 Return

 Термо:

  Тик = 0
1wreset
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44
 Waitms 750
 Stop Timer0
 Stop Timer2
1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт

T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
I = T1
Start Timer0
Start Timer2
Return


Pulse:

Do
Loop
Return

0

20

Володя написал(а):
Код:
Config Timer1 = Timer , Prescale = 8 : On Timer1 Pulse : Enable Timer1
Володя написал(а):
Код:
Pulse:

Do
Loop
Return

Действительно не понимаете почему виснет?

0

21

Теперь понимаю, просто это тестовая с лсд , что бы видеть код кнопки, а вот этот код не работает , хотя температуру и показывает

Код:
$regfile = "m8def.dat"
$crystal = 8000000
 $hwstack = 36
$swstack = 36
$framesize = 40
 '$baud = 9600                                               'внутренний генератор
'$lib "lcd4.lbx"
 $lib "mcsbyte.lbx"
 Config Portb = Output
Config 1wire = Portd.0
Config Portd.1 = Output                                     ' реле выход
Config Portc.0 = Output
Config Portc.1 = Output
Config Portc.2 = Output
Config Portc.3 = Output
Config Portd.3 = Output
'Config Portd.2 = Input                        ' вход ик датчика
   Dim Cifri(4) As Byte
  Dim I As Byte , X As Byte
 Dim Byte0 As Byte
Dim Byte1 As Byte
     Dim T As Byte
Dim T1 As Single
Dim T2 As Single
Dim S As Byte
Dim Память As Eram Byte
Dim Счет As Word
Dim D As Byte
Dim Тик As Word
Dim A As Byte
Dim B As Byte
 Config Timer2 = Timer , Prescale = 8 : On Timer2 Pulse : Enable Timer2

Config Timer0 = Timer , Prescale = 256                      '8000000/256=31250 Hz
Config Int0 = Falling                                       'Interruption on Falling
Stop Timer0
Enable Timer0
Enable Int0
Enable Interrupts
On Timer0 Tikers                                            'work on timer
On Int0 Infrared

 'work on interruption
Dim Got As Bit
Dim Tik As Word                                             'counter of teaks of timer
Dim Byt As Byte                                             'counter accepted bit
Dim Repeat_flag As Bit                                      'flag of repetition
Dim Start_flag As Bit                                       'flag of start condition
Dim Address_1 As Byte                                       'direct byte of address
Dim Command_1 As Byte                                       'direct byte of command
Dim Address_0 As Byte                                       'indirect byte of address
Dim Command_0 As Byte                                       'indirect byte of command
Dim Summa As Word
Dim Address_nec As Byte , Command_nec As Word
 Command_nec = 0
  If Portc.4 = 0 Then Память = 25
 Выход Alias Portd.1
  Main:
  Тик = 0
  Счет = 0
  Do
  B = 10
  A = 11
 Incr Тик
If Тик => 30 Then Gosub Температура
If Command_nec = 138 Then Goto Установка

If I >= Память Then Выход = 0
D = I - 1
If I < D Then Выход = 1

If Got = 1 Then
              Portd.3 = 1
         ' Command_nec = Command_nec And &B01111111
              Waitms 10
              Toggle Portd.3

   Reset Got
End If


Waitms 20

Loop

 Установка:

 Do
 Incr Счет
 If Счет => 100 Then Goto Main
 A = 40
 B = 40



If Command_nec = 232 Then S = S + 1
If S => 35 Then S = 35
If Command_nec = 885 Then S = S -1
If S =< 20 Then S = 20
I = S
Waitms 150
If Command_nec = 138 Then
   Память = S
Goto Main
End If
 Loop


   Pulse:
Cifri(3) = I Mod 10 : Cifri(4) = I / 10 : Cifri(2) = B : Cifri(1) = A
Portc = &HFF
Incr X : If X > 3 Then X = 0
Portb = Lookup(cifri(x + 1) , Dta)
Reset Portc.x
Return

 Температура:
    Тик = 0
1wreset
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44
 Waitms 750
 Stop Timer0
 Stop Timer2
1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт

T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
I = T1
Start Timer0
Start Timer2
Return


Dta:

Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F , &H63 , &H39


 Tikers:                                                    'work on timer
 Timer0 = 253                                               '31250/(256-253)=10416,66 Hz (96 een)
 Incr Tik
 If Tik >= 1200 Then                                        'if 1200 teaks, have thrown all in source condition
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 255
 Command_1 = 255
 Address_0 = 0
 Command_0 = 0
 Address_nec = 255
 Command_nec = 255
 Stop Timer0
 End If
 Return
'################################################################################################################

 Infrared:                                                  'work on interruption
 Start Timer0

 If Tik >= 139 And Tik < 150 Then                           'if has happenned from 139 before 150 teaks - "START"
  Address_nec = 1
  Repeat_flag = 0
  Start_flag = 1
  Address_1 = 255
  Command_1 = 255
  Address_0 = 0
  Command_0 = 0
  'Portb.1 = 1
 End If

 If Tik >= 116 And Tik < 139 Then                           'if has happenned from 116 before 138 teaks - "REPETITION"
  Address_nec = 0
  Repeat_flag = 1
  Start_flag = 0
 End If

 If Tik >= 22 And Tik < 116 And Start_flag = 1 Then         'if has happenned from 22 before 115 teaks - have taken "1"
   Incr Byt

   If Byt < 9 Then
      Shift Address_1 , Left
      Address_1 = Address_1 + 1
   End If

   If Byt >= 9 And Byt < 17 Then
      Shift Address_0 , Left
      Address_0 = Address_0 + 1
   End If

   If Byt >= 17 And Byt < 25 Then
      Shift Command_1 , Left
      Command_1 = Command_1 + 1
   End If

   If Byt >= 25 Then
      Shift Command_0 , Left
      Command_0 = Command_0 + 1
   End If
 End If

 If Tik >= 10 And Tik < 22 And Start_flag = 1 Then          'if has happenned from 10 before 21 teaks - have taken "0"
    Incr Byt
    If Byt < 9 Then
      Shift Address_1 , Left
    End If

    If Byt >= 9 And Byt < 17 Then
       Shift Address_0 , Left
    End If

    If Byt >= 17 And Byt < 25 Then
       Shift Command_1 , Left
    End If

    If Byt >= 25 Then
       Shift Command_0 , Left
    End If
 End If

 Tik = 0

 If Byt = 32 Then
   Address_nec = Address_1
   Command_nec = Command_1
   Set Got
   Address_1 = 255
   Command_1 = 255
   Byt = 0
   Repeat_flag = 0
   Start_flag = 0
   Stop Timer0
   Portd.3 = 1
 End If

 Return

0

22

Володя написал(а):

а вот этот код не работает

Что конкретно не работает?

+1

23

от пульта не принимает сигнал, а всё то же самое работает в первом коде

0

24

Я уже и таймер для светиков останавливаю, не читает с пульта и всё тут (на lcd всё чётко работает)

Код:
$regfile = "m8def.dat"
$crystal = 8000000
 $hwstack = 36
$swstack = 36
$framesize = 40                                             'внутренний генератор
'$lib "lcd4.lbx"
 $lib "mcsbyte.lbx"
            Config Timer2 = Timer , Prescale = 8 : On Timer2 Pulse : Enable Timer2


Config Timer0 = Timer , Prescale = 256                      '8000000/256=31250 Hz
Config Int0 = Falling                                       'Interruption on Falling
Stop Timer0
Enable Timer0
Enable Int0
Enable Interrupts
On Timer0 Tikers                                            'work on timer
On Int0 Infrared
'Config Portd.3 = Output
'Set Portd.2
Config Portb = Output
Config 1wire = Portd.0
Config Portd.1 = Output                                     ' реле выход
Config Portc.0 = Output
Config Portc.1 = Output
Config Portc.2 = Output
Config Portc.3 = Output
Config Portd.3 = Output
Config Pinc.4 = Input : Set Portc.4
     Dim Cifri(4) As Byte

   Dim I As Byte , X As Byte
 Dim Byte0 As Byte
Dim Byte1 As Byte
     Dim T As Byte
Dim T1 As Single
Dim T2 As Single                                            'work on interruption
Dim Got As Bit
Dim Tik As Word                                             'counter of teaks of timer
Dim Byt As Byte                                             'counter accepted bit
Dim Repeat_flag As Bit                                      'flag of repetition
Dim Start_flag As Bit                                       'flag of start condition
Dim Address_1 As Byte                                       'direct byte of address
Dim Command_1 As Byte                                       'direct byte of command
Dim Address_0 As Byte                                       'indirect byte of address
Dim Command_0 As Byte                                       'indirect byte of command
Dim Summa As Word
Dim Address_nec As Byte , Command_nec As Word

 Dim S As Byte
Dim Память As Eram Byte
Dim Счет As Word
Dim D As Byte
Dim Тик As Word
Dim A As Byte
Dim B As Byte
                                                         'Switch Off cursor
'################################################################################################################
     'portb.2=1

If Pinc.4 = 0 Then Память = 25
 Выход Alias Portd.1
 Тик = 0
  Счет = 0
    Main:
     Do

Incr Тик

If Тик => 10 Then Gosub Термо
B = 10
  A = 11
 'I = Command_nec / 10
If Command_nec = 138 Then Goto Установка

If I >= Память Then Выход = 0
D = I - 1
If I < D Then Выход = 1

If Got = 1 Then
              Portd.3 = 1
         ' Command_nec = Command_nec And &B01111111
              Waitms 20
              Toggle Portd.3

   Reset Got
End If

Waitms 20                                                   'Delay 10 en
Loop
End                                                         'End of main cycle

Установка:

 Do
 Waitms 200
 Incr Счет
 If Счет => 100 Then Goto Main
 A = 40
 B = 40
  Command_nec = 0
If Command_nec = 232 Then S = S + 1
If S => 35 Then S = 35
If Command_nec = 885 Then S = S -1
If S =< 20 Then S = 20
I = S
Waitms 150
If Command_nec = 138 Then
   Память = S
Goto Main
End If
 Loop


   Pulse:
Cifri(3) = I Mod 10 : Cifri(4) = I / 10 : Cifri(2) = B : Cifri(1) = A
Portc = &HFF
Incr X : If X > 3 Then X = 0
Portb = Lookup(cifri(x + 1) , Dta)
Reset Portc.x
Return

 Температура:
    Тик = 0

1wreset
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44
 Waitms 750
 Stop Timer0
 Stop Timer2
1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт

T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
I = T1
Start Timer0
Start Timer2

Return


Dta:

Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F , &H63 , &H39





'################################################################################################################

 Tikers:
 Stop Timer2                                                      'work on timer
 Timer0 = 253                                               '31250/(256-253)=10416,66 Hz (96 een)

 Incr Tik
 If Tik >= 1200 Then                                        'if 1200 teaks, have thrown all in source condition
 Tik = 0
 Repeat_flag = 0
 Start_flag = 0
 Address_1 = 255
 Command_1 = 255
 Address_0 = 0
 Command_0 = 0
 Address_nec = 255
 Command_nec = 255
 Stop Timer0

 End If
 Start Timer2
 Return
'################################################################################################################

 Infrared:
   Stop Timer2                                                 'work on interruption
 Start Timer0

 If Tik >= 139 And Tik < 150 Then                           'if has happenned from 139 before 150 teaks - "START"
  Address_nec = 1
  Repeat_flag = 0
  Start_flag = 1
  Address_1 = 255
  Command_1 = 255
  Address_0 = 0
  Command_0 = 0
  'Portb.1 = 1
 End If

 If Tik >= 116 And Tik < 139 Then                           'if has happenned from 116 before 138 teaks - "REPETITION"
  Address_nec = 0
  Repeat_flag = 1
  Start_flag = 0
 End If

 If Tik >= 22 And Tik < 116 And Start_flag = 1 Then         'if has happenned from 22 before 115 teaks - have taken "1"
   Incr Byt

   If Byt < 9 Then
      Shift Address_1 , Left
      Address_1 = Address_1 + 1
   End If

   If Byt >= 9 And Byt < 17 Then
      Shift Address_0 , Left
      Address_0 = Address_0 + 1
   End If

   If Byt >= 17 And Byt < 25 Then
      Shift Command_1 , Left
      Command_1 = Command_1 + 1
   End If

   If Byt >= 25 Then
      Shift Command_0 , Left
      Command_0 = Command_0 + 1
   End If
 End If

 If Tik >= 10 And Tik < 22 And Start_flag = 1 Then          'if has happenned from 10 before 21 teaks - have taken "0"
    Incr Byt
    If Byt < 9 Then
      Shift Address_1 , Left
    End If

    If Byt >= 9 And Byt < 17 Then
       Shift Address_0 , Left
    End If

    If Byt >= 17 And Byt < 25 Then
       Shift Command_1 , Left
    End If

    If Byt >= 25 Then
       Shift Command_0 , Left
    End If
 End If

 Tik = 0

 If Byt = 32 Then
   Address_nec = Address_1
   Command_nec = Command_1
   Set Got
   Address_1 = 255
   Command_1 = 255
   Byt = 0
   Repeat_flag = 0
   Start_flag = 0
   Stop Timer0

   Portb.3 = 1
 End If
    Start Timer2
     'Toggle Portd.3
 Return

 Термо:

  Тик = 0
1wreset
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44
 Waitms 750
 Stop Timer0
 Stop Timer2
1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт

T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
I = T1
Start Timer0
Start Timer2
Return

0


Вы здесь » Программирование ATMEL в BASCOM. » Исходники » Тестю индикатор. Правильная обработка прерываний. Как сделать?