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

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

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

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



I2C CLOCK+ALARM

Сообщений 151 страница 180 из 300

151

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

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

Мои размышления, т.с. навскидку... ;)

' Запрос по i2c времени и пересчет его в четырех значное число а также мигалка двух средних точек (22:03)
...
Gosub Getdatetime
Stop Timer0
Viv_peremennaya = Chasi * 100                - эти две строки
Viv_peremennaya = Viv_peremennaya + Minuti   - переместить в Getdatetime перед Return
Start Timer0
...
Waitms 80 - можно попробовать увеличить

Подобное использование Viv_peremennaya есть и в других местах.
Можно ввести еще одну флаговую переменную, а при вызове Getdatetime указывать этим флагом - что нужно обсчитать и вернуть.

Не придется переключать Timer0.
Хотя, в принципе, даже отсутствие Stop/Start вряд ли скажется на подсчете, ведь из обработки прерывания программа вернется сюда же.
Правда, это будет справедливо, если при обработке не будет затронута Viv_peremennaya...

------------------------------------------------------

' Запрос с DS18b20 Температуры, погашение первого числа если температура положительная и зажигания там минуса если отритцательная, либо единици если температура > 99. Зажигание последнего символа в виде буквы С и установка перед ней в верху точки (-22'C)(108'C)(05'C)
...
Waitms 1800

Убрать совсем, а вот здесь

' Запрос текущего числа и месяца и установка точки посредине между числом и месяцем. Пересчет даты в четырех значное число (28.12)
...
Waitms 700 - сделать 2500

Итоговая задержка будет те же 2,5 сек.

+1

152

Nord
это уже завтра. наверное объединю запрос времени и даты с 1307  и температуры в одну остановку таймера, не зачем их теперь разделять ну и добавить Viv_peremennaya_Odin для даты. спасибо, буду пробовать

0

153

Вставлю и свои 5 копеек: в Вашем случае переменная View_menu не используется. Но в программе кое-где проскакивает, нужно убрать ее полностью. И в связи с этим запрос даты стал происходить постоянно в главном цикле:

Код:
    ' Запрос текущего числа и месяца и установка точки посредине между числом и месяцем. Пересчет даты в четырех значное число (28.12)
    Clock_flag = 2
    Stop Timer0
    Viv_peremennaya = Den * 100
    Viv_peremennaya = Viv_peremennaya + Mesjac
    Start Timer0
    Dp_flag1 = 0
    Dp_flag2 = 0
    Dp_flag3 = 1
    Dp_flag4 = 0
    Waitms 700

Потому что пропала строчка:

Код:
If View_menu = 0 Or View_menu = 2 Then

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

0

154

Andrusha
ну, пока что чередование даты\температуры происходит. видимо, путем перезапуска таймера. но завтра все проверю еще раз

0

155

Чередование происходит потому что при измерении температуры:

Код:
T1 = T1 + T2                                                ' Формирмируем результам и выдаем его на индикатор. Команда LCD сама преобразует его в десятичный вид

Chislo(1) = 12
Chislo(2) = T1 Mod 10
Chislo(3) = T1 / 10

А дальше в обработке прерывания таймера0:

Код:
For I = 1 To 4                                              ' цикл в котором разбивается переменная на отдельные числа от 0 до 9
Chislo(i) = Temp_print Mod 10                               ' заносим в масив последнюю цифру от числа Temp_print(12345678 mod 10 = 8)
Temp_print = Temp_print / 10                                ' отсекаем последнюю цифру от числа Temp_print (12345678/10=1234567)
Next

При запросе времени этот кусок можно выкинуть:

Код:
Viv_peremennaya = Chasi * 100
Viv_peremennaya = Viv_peremennaya + Minuti

А при индикации выводить сразу:

Код:
 If Clock_flag = 1 Then
Chislo(4) = Chasi / 10
Chislo(3) = Chasi Mod 10
Chislo(2) = Minuti / 10
Chislo(1) = Minuti Mod 10

If Chasi < 10 Then Chislo(4) = 11
End If

И то же самое можно сделать с дата/температура.Только нужно определиться как будут переключаться показания.
И не надо никаких Clock_flag = 2. Сразу обрабатывайте оба индикатора.

Отредактировано Andrusha (2017-10-19 17:42:49)

0

156

Andrusha
кстатида, лишние переменные можно выкинуть. спасибо, попробую

0

157

итого - почти поборол.

код

'I2C KLOCK+ALARM
'I2C KLOCK+ALARM
'P-a-h-a@yandex.ru
$regfile = "m8def.dat"                                      ' говорим компилятору что у нас микропроцессор Atmega 8
$crystal = 8000000                                          ' говорим компилятору что процессор тактируется от генератора с частотой 8, 000 000 мегагерц

$lib "mcsbyte.lbx"                                          ' for smaller code
$lib "ds1307clock.lib"                                      ' modified lib
Config Sda = Portc.4 : Config Scl = Portc.5
Const Ds1307w = &HD0                                        ' Addresses of Ds1307 clock
Const Ds1307r = &HD1
Config Clock = User                                         ' this will dim the bytes automatic
Config Pinb.4 = Input : Portb.4 = 1
Config Pinb.5 = Input : Portb.5 = 1
Config Pinc.6 = Input                                       ': PortC.6 = 1
Config Portb = Output : Config Portd = Output : Config Portc.0 = Output : Config Portc.1 = Output : Config Portc.2 = Output : Config Portc.3 = Output       ' конфигурируем порты на выход к которым подключен семисегментник                                       ' ‘
Config 1wire = Portb.6                                      ' на эту ножку подключим DS18B20 и подтягивающий резистор на 4,7 ком к + питания
Dim W As Byte , Z As Byte , Y As Byte , I As Byte , X As Byte , Chislo(8) As Integer , Chasi As Byte , Minuti As Byte , Secundi As Byte
Dim Weekday As Byte , Clock_flag As Byte , Dp_flag1 As Bit , Dp_flag2 As Bit , Dp_flag3 As Bit , Dp_flag4 As Bit , Dp_flag5 As Bit , Migalka As Integer , Den As Byte , Mesjac As Byte , God As Byte
Dim Mode_flag As Byte , View_menu As Byte , Nosave_time As Byte       ' задаем переменные
Dim T1 As Integer , T2 As Integer , Byte0 As Byte , Byte1 As Byte

A Alias Portd.5 : B Alias Portd.7 : C Alias Portd.3 : D Alias Portd.1 : E Alias Portd.0 : F Alias Portd.6 : G Alias Portd.4 : Dp Alias Portd.2       'Тут вписываем порты к которым подключены сегменты индикатора
Dig1 Alias Portb.3 : Dig2 Alias Portb.2 : Dig3 Alias Portb.1 : Dig4 Alias Portb.0 : Dig5 Alias Portc.0 : : Dig6 Alias Portc.1 : Dig7 Alias Portc.2 : Dig8 Alias Portc.3 : Dp2 Alias Portb.7       ' тут вписываем порты к которым подключены общие провода каждой цифры

For X = 1 To 8                                              ' присваиваем всем цифрам пустоту, чтоб в момент включения не высвечивались ноли
Chislo(x) = 11
Next
Config Timer0 = Timer , Prescale = 8 : On Timer0 Pulse :    ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Config Timer1 = Timer , Prescale = 8 : On Timer1 Bootons :  ' конфигурируем таймер 0 и назначаем подпрограмму которая выполняется при переполнении таймера
Enable Interrupts : Enable Timer0 : Enable Timer1           ' разрешаем прерывания и таймер 0

Do                                                          'Основной режим работы. Отображение времени, числа, температуры.
Times:
'*******************************************************************************
' Запрос по i2c времени и даты пересчет его в четырех значное число а также точка-разделитель даты (22.03)
Clock_flag = 1
Stop Timer0
Gosub Getdatetime
Start Timer0
Dp_flag1 = 0
Dp_flag2 = 0
Dp_flag3 = 1
Dp_flag4 = 0
Waitms 500
'*******************************************************************************
Portb.7 = 1
Waitms 500
Portb.7 = 0                                                 'точка-разделитель времени
'*******************************************************************************
' Запрос с DS18b20 Температуры, погашение первого числа если температура положительная и зажигания там минуса если отритцательная, либо единици если температура > 99. Зажигание последнего символа в виде буквы С и установка перед ней в верху точки (-22'C)(108'C)(05'C)
Clock_flag = 0
1wreset
Stop Timer0                                                 ' : Portd = 255
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44                                                ' Запуск измерения
Start Timer0
Waitms 750                                                  ' Ждем окончания преобразования
1wreset
Stop Timer0                                                 ': Portd = 255
1wwrite &HCC
1wwrite &HBE                                                ' Команда чтения ОЗУ датчика
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт
Start Timer0
If Byte1 >= 248 Then                                        ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Chislo(4) = 10
Else
Chislo(4) = 11
End If
T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2                                                ' Формирмируем результам и выдаем его на индикатор. Команда LCD сама преобразует его в десятичный вид
Chislo(1) = 12
Chislo(2) = T1 Mod 10
Chislo(3) = T1 / 10
If T1 > 99 Then Chislo(4) = 1

Dp_flag1 = 1
Dp_flag2 = 0
Dp_flag3 = 0
Dp_flag4 = 0
Waitms 500
'*******************************************************************************
Portb.7 = 1
Waitms 500
Portb.7 = 0
Loop

'*******************************************************************************
'работа с  ds1307
Getdatetime:
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 0                                                ' start address in 1307

  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307r                                          ' send address
  I2crbyte _sec , Ack
  I2crbyte _min , Ack                                       ' MINUTES
  I2crbyte _hour , Ack                                      ' Hours
  I2crbyte Weekday , Ack                                    ' Day of Week
  I2crbyte _day , Ack                                       ' Day of Month
  I2crbyte _month , Ack                                     ' Month of Year
  I2crbyte _year , Nack                                     ' Year
  I2cstop
Secundi = Makedec(_sec) : Minuti = Makedec(_min) : Chasi = Makedec(_hour)

   Den = Makedec(_day) : Mesjac = Makedec(_month) : God = Makedec(_year)
Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 4                                                ' starting address in 1307
  I2cwbyte _day                                             ' Send Data to SECONDS
  I2cwbyte _month                                           ' MINUTES
  I2cwbyte _year                                            ' Hours
  I2cstop
Return

Settime:
  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)
  I2cstart                                                  ' Generate start code
  I2cwbyte Ds1307w                                          ' send address
  I2cwbyte 0                                                ' starting address in 1307
  I2cwbyte _sec                                             ' Send Data to SECONDS
  I2cwbyte _min                                             ' MINUTES
  I2cwbyte _hour                                            ' Hours
  I2cstop
Return
'*******************************************************************************

'*************************Вывод на индикатор************************************
Pulse:
Stop Timer0                                                 ' останавливаем таймер 0
If Clock_flag < 2 Then                                      ' цикл в котором разбивается переменная на отдельные числа от 0 до 9
Chislo(8) = Chasi / 10
Chislo(7) = Chasi Mod 10
Chislo(6) = Minuti / 10
Chislo(5) = Minuti Mod 10

If Chasi < 10 Then Chislo(8) = 11

If Clock_flag = 1 Then
Chislo(4) = Den / 10
Chislo(3) = Den Mod 10
Chislo(2) = Mesjac / 10
Chislo(1) = Mesjac Mod 10

If Den < 10 Then Chislo(4) = 11
End If
End If

Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4 : Reset Dig5 : Reset Dig6 : Reset Dig7 : Reset Dig8
Incr W : If W > 8 Then W = 1                                ' выбираем какую цифру сейчас включать
Y = 0
Gosub Look : A = Z                                          ' переходим к подпрограмме Look, которая определяет нужно ли сейчас загорется сегменту А
Gosub Look : B = Z
Gosub Look : C = Z
Gosub Look : D = Z
Gosub Look : E = Z
Gosub Look : F = Z
Gosub Look : G = Z

Select Case W                                               ' включаем цифру которую выбрали (w). Подаем плюс на общий провод конкретной цифры
Case 1 :
If Dp_flag1 = 1 Then Reset Dp Else Set Dp
Set Dig1
Case 2 :
If Dp_flag2 = 1 Then Reset Dp Else Set Dp
Set Dig2
Case 3 :
If Dp_flag3 = 1 Then Reset Dp Else Set Dp
Set Dig3
Case 4 :
If Dp_flag4 = 1 Then Reset Dp Else Set Dp
Set Dig4
Case 5 :
Set Dig5
Case 6 :
Set Dig6
Case 7 :
Set Dig7
Case 8 :
Set Dig8
End Select

Start Timer0                                                ' запускаем таймер0
Return                                                      ' возвращаемся к выполнению основной программы

Look:                                                       ' подпрограмма которая определяет нужно ли сейчас гореть сегменту, который вызвал эту подпрограмму
Z = Chislo(w) * 7 : Z = Y + Z                               ' определяем порядковый номер числа из таблици DATA. W - это цифра которую будем выводить 0..1..2..3.......9, Y это номер сегмента (A=0 B=1 C=2...G=7)
Z = Lookup(z , Cifri)                                       ' выбираем из таблици включить или выключить нужный сегмент
Incr Y                                                      'Y это номер сегмента (A=0 B=1 C=2...)

Return                                                      'возвращаемся на место откуда сюда прислали

Cifri:
' таблица сегментом для семисегментников с общим плюсом      |Chislo(i)| Символ |
Data 0 , 0 , 0 , 0 , 0 , 0 , 1                              '0
Data 1 , 0 , 0 , 1 , 1 , 1 , 1                              '1
Data 0 , 0 , 1 , 0 , 0 , 1 , 0                              '2
Data 0 , 0 , 0 , 0 , 1 , 1 , 0                              '3
Data 1 , 0 , 0 , 1 , 1 , 0 , 0                              '4
Data 0 , 1 , 0 , 0 , 1 , 0 , 0                              '5
Data 0 , 1 , 0 , 0 , 0 , 0 , 0                              '6
Data 0 , 0 , 0 , 1 , 1 , 1 , 1                              '7
Data 0 , 0 , 0 , 0 , 0 , 0 , 0                              '8
Data 0 , 0 , 0 , 0 , 1 , 0 , 0                              '9
Data 1 , 1 , 1 , 1 , 1 , 1 , 0                              '10           "-"
Data 1 , 1 , 1 , 1 , 1 , 1 , 1                              '11           ""
Data 0 , 1 , 1 , 0 , 0 , 0 , 1                              '12           "C"
Data 0 , 0 , 1 , 1 , 0 , 0 , 0                              '13           "P"
Data 1 , 1 , 1 , 0 , 0 , 0 , 0                              '14           "t"

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

'*****************************Работа с кнопками*********************************
Bootons:

Stop Timer1

If Pinb.5 = 0 Then Gosub Set_booton

Bitwait Pinb.5 , Set                                        'ждем пока не отпустят кнопку
Bitwait Pinb.4 , Set

Start Timer1

Return

'*****************************вывод меню настройки******************************
Set_booton:
Enable Interrupts : Enable Timer0 : Start Timer0 : Stop Timer1

Clock_flag = 2

Bitwait Pinb.5 , Set                                        ' ждем пока не отпустим кнопку настроек
  Do                                                        ' цикл настройки часов
                                         ' включаем первые две цифры на которых показаны текущие часы суток, второй кнопкой их можно прибавлять
    Chislo(5) = 11
    Chislo(6) = 11
    Chislo(7) = Chasi Mod 10
    Chislo(8) = Chasi / 10
    Reset Dp_flag1
    Set Dp_flag2
    Set Dp_flag3
    Reset Dp_flag4
    Waitms 100
    If Pinb.4 = 0 Then : Incr Chasi : Set Nosave_time : End If
    If Chasi >= 24 Then Chasi = 0
  Loop Until Pinb.5 = 0
Bitwait Pinb.5 , Set                                        ' ждем пока не отпустят кнопку настроек

  Do                                                        ' цикл настройки минут
                                         ' включаем вторые две цифры с минутами -||-
    Chislo(5) = Minuti Mod 10
    Chislo(6) = Minuti / 10
    Chislo(7) = 11
    Chislo(8) = 11
    Reset Dp_flag1
    Set Dp_flag2
    Set Dp_flag3
    Reset Dp_flag4
    Waitms 100
    If Pinb.4 = 0 Then : Incr Minuti : _sec = 0 : Set Nosave_time : End If
    If Minuti >= 60 Then Minuti = 0
  Loop Until Pinb.5 = 0
Bitwait Pinb.5 , Set
    Chislo(5) = 11
    Chislo(6) = 11

  If Nosave_time = 1 Then                                   ' смотрим было ли изменение времени, если да то записываем установленное время по i2c
  _hour = Chasi
  _min = Minuti
  Gosub Settime                                             ' устанавливаем по i2c текущее время
  Else
  Reset Nosave_time
  End If

  Do                                                        ' цикл настройки номера месяца
                                          ' включаем первые две цифры с днем месяца -||-
    Chislo(1) = 11
    Chislo(2) = 11
    Chislo(3) = Den Mod 10
    Chislo(4) = Den / 10
    Reset Dp_flag1
    Reset Dp_flag2
    Set Dp_flag3
    Reset Dp_flag4
    Waitms 100
    If Pinb.4 = 0 Then : Incr Den : Set Nosave_time : End If
    If Den >= 32 Then Den = 1
  Loop Until Pinb.5 = 0
Bitwait Pinb.5 , Set

  Do                                                        ' цикл настройки дня месяца  ' включаем вторые две цифры с номером месяца -||-

    Chislo(1) = Mesjac Mod 10
    Chislo(2) = Mesjac / 10
    Chislo(3) = 11
    Chislo(4) = 11
    Reset Dp_flag1
    Reset Dp_flag2
    Set Dp_flag3
    Reset Dp_flag4
    Waitms 100
    If Pinb.4 = 0 Then : Incr Mesjac : Set Nosave_time : End If
    If Mesjac >= 13 Then Mesjac = 1
  Loop Until Pinb.5 = 0
Bitwait Pinb.5 , Set

  Do                                                        ' включаем первые две цифры с номером года 20 и вторые две, которые можно изменять 10. все изменяется от 2010 до 2099

    Chislo(1) = God Mod 10
    Chislo(2) = God / 10
    Chislo(3) = 0
    Chislo(4) = 2
    Reset Dp_flag1
    Reset Dp_flag2
    Reset Dp_flag3
    Reset Dp_flag4
    Waitms 100
    If Pinb.4 = 0 Then : Incr God : Set Nosave_time : End If
    If God >= 100 Then God = 10
  Loop Until Pinb.5 = 0
Bitwait Pinb.5 , Set

If Nosave_time = 1 Then
_day = Den
_month = Mesjac
_year = God
Gosub Setdate                                               ' устанавливаем по i2c текущую дату не зависимо меняли ее или нет
Else
  Reset Nosave_time
End If

Bitwait Pinb.5 , Set
Start Timer1
Goto Times:                                                 ' переход к отображению времени

Return

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

0

158

А что означает вот это

Код:
If Clock_flag < 2 Then 

а потом вот это

Код:
If Clock_flag = 1 Then

Насколько я помню математику один меньше двух. В коде я не нашел как переключаются показания дата\температура. И желательно убрать из главного цикла измерение температуры. Незачем датчик так часто опрашивать. Я в своих часах сделал немного по другому. Я тоже убрал VIEW_MENU и одна кнопочка в основном режиме освободилась. На нее я повесил термометр. Часы показывают время, а при нажатии на кнопку идет опрос DS18B20 и вывод на индикатор. Через 3 сек. возврат к отображению времени. Но хозяин-барин.

0

159

Andrusha
Clock_flag становится равным 2 в подпрограмме кнопок. иначе на индикаторах чехарда получается. ну и для определения что выводится на второй индикатор - дата иил температура. соответсвенно 1 или 0. вызов температуры через кнопку мне не подходит, часы будут настенные (собственно поэтому от режимов и отказался)

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

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

и куда его? ну в подпрограмму, понятно. а вызывать в подпрограмму Pulse непосредственно перед выводом на индик?
по ULN не подскажете чего? в протеусе воткнул ее в схему, инвертировал сегменты, получил ерунду

0

160

Как часто должны переключаться дата\температура? Какие основные показания даты или температуры?
А с термометром проще пареной репы. Создаете еще одну переменную. В прерывании таймера1 инкременируете эту переменную. Когда она достигает определенного значения (подобрать или рассчитать) уходите на подпрограмму термометра, а переменную обнуляете. Как то так. Как по мне, там дата есть в компьютере, в мобильнике. Зачем, чтобы она еще в часах светила целый день.

0

161

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

Как часто должны переключаться дата\температура? Какие основные показания даты или температуры?

ну, 2 секунды туда, 2 оттуда. показания равнозначны

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

Как по мне, там дата есть в компьютере, в мобильнике. Зачем, чтобы она еще в часах светила целый день

часы нас-тен-ны-е. для красоты и уюта. я могу на стену мобильник прибить, но это мелко. а ноутбук - дорого :)

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

Создаете еще одну переменную. В прерывании таймера1 инкременируете эту переменную. Когда она достигает определенного значения (подобрать или рассчитать) уходите на подпрограмму термометра, а переменную обнуляете

а вот это попробуем! (с)
но меня щас больше всего ключи на сегменты волнуют. аж кушать не могу, да :(

0

162

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

В прерывании таймера1

таймера0 наверное. таймер1 - он для кнопки. хотя они одинаковые...

0

163

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

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

При опросе ds18b20 чаще 1 раза в 7 сек., идёт саморазогрев датчика (завышает до 2°С), при измерении газообразной среды.

+1

164

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

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

    В прерывании таймера1

таймера0 наверное. таймер1 - он для кнопки. хотя они одинаковые...

Нет именно таймера1. Таймер0 считает до 255. Это представьте, какой величины должна быть переменная, чтобы отсчитать, к примеру, 20 сек. А таймер1 считает до 65535. Вы, наверное, не очень хорошо представляете работу таймеров. При конфигурации таймера 0 или 1 не важно, вы задаете предделитель. В данном случае 8. То есть таймер будет считать каждый восьмой импульс. Так же вы задаете подпрограмму, которая будет выполняться при переполнении таймера 0(1). В данном случае это Pulse или Button. Таймер считает непрерывно, доходит до 255 (65535) , сбрасывается в 0 и опять продолжает считать. И так непрерывно. В момент перехода с максимального значения до 0 происходит переполнение таймера 0 (1). И контроллер переходит к выполнению подпрограммы, заданной в конфигурации Pulse (Button). После выполнения подпрограммы контроллер возвращается к выполнению основной программы. При обработке прерывания, чтобы таймер не продолжал считать, его останавливают физически. Иначе получится, что предыдущее прерывание еще не обработано, а уже наступило следующее. Ну вроде понятно объяснил.

0

165

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

Вы, наверное, не очень хорошо представляете работу таймеров.

ну, просто забыл, что они разной разрядности

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

При опросе ds18b20 чаще 1 раза в 7 сек., идёт саморазогрев датчика (завышает до 2°С), при измерении газообразной среды.

ну е-мае, кругом засада :(

0

166

получилось как-то так:
главный цикл с подпрограммой датчика

код

Clock_flag = 1
Stop Timer0
Gosub Getdatetime
If Tmp>106 Then   'больше 7 секунд
Gosub Temper
Tmp=0
End If
Start Timer0
Dp_flag1 = 0
Dp_flag2 = 0
Dp_flag3 = 1
Dp_flag4 = 0

Waitms 500
'*******************************************************************************
Portb.7 = 1
Waitms 500
Portb.7 = 0                                                 'точка-разделитель времени
'*******************************************************************************
Waitms 500
'*******************************************************************************
Portb.7 = 1
Waitms 500
Portb.7 = 0
Loop

' Запрос с DS18b20 Температуры, погашение первого числа если температура положительная и зажигания там минуса если отритцательная, либо единици если температура > 99. Зажигание последнего символа в виде буквы С и установка перед ней в верху точки (-22'C)(108'C)(05'C)
Temper:
Clock_flag = 0
1wreset
Stop Timer0                                                 ' : Portd = 255
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44                                                ' Запуск измерения
Start Timer0
Waitms 750                                                  ' Ждем окончания преобразования
1wreset
Stop Timer0                                                 ': Portd = 255
1wwrite &HCC
1wwrite &HBE                                                ' Команда чтения ОЗУ датчика
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт
Start Timer0
If Byte1 >= 248 Then                                        ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Chislo(4) = 10
Else
Chislo(4) = 11
End If
T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2                                                ' Формирмируем результам и выдаем его на индикатор. Команда LCD сама преобразует его в десятичный вид
Chislo(1) = 12
Chislo(2) = T1 Mod 10
Chislo(3) = T1 / 10
If T1 > 99 Then Chislo(4) = 1

Dp_flag1 = 1
Dp_flag2 = 0
Dp_flag3 = 0
Dp_flag4 = 0
Return

и подпрограмма таймера1

код

Bootons:

Stop Timer1

If Pinb.5 = 0 Then Gosub Set_booton

Bitwait Pinb.5 , Set                                        'ждем пока не отпустят кнопку
Bitwait Pinb.4 , Set

Start Timer1
Tmp = Tmp + 1  ;счетчик для датчика температуры
Return

0

167

Код:
    Bootons:

    Stop Timer1
    Incr Tmp
    If Tmp > 106 Gosub Temper
    If Pinb.5 = 0 Then Gosub Set_booton

    Bitwait Pinb.5 , Set                                        'ждем пока не отпустят кнопку
    Bitwait Pinb.4 , Set

    Start Timer1

    Return

И дальше

Код:
Temper:
Tmp = 0

Я думаю, что как то так. И подождите с ULN. Все должно работать и так.

+1

168

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

И подождите с ULN. Все должно работать и так.

ну вот не работает. по одному если подключить - все путем, если вместе - большой индик еле светит
и мой код лучше. по вашему индикатор ерунду выдает: периодически гасит все цифры кроме одной любой  :'(

0

169

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

по одному если подключить - все путем, если вместе - большой индик еле светит

А по току ИП вытягивает ?
Мощный индикатор хомячит некисло... ;)

0

170

Nord
если подключить их по одному - все пучком. ток большого индикатора 25мА при номинальных 4.2В (после транзистора именно это и получается). маленький - 25мА при номинальных 2.7В и максимальных 4.2В (при динамической индикации тоже в рамках терпимого). а вот когда тупо в параллель - маленький светит нормально, а большой еле-еле видно. пришел к выводу, что ULNка не спасет, надо разводить аноды по времени. т.е. когда включены аноды первого индикатора - выключены второго или наоборот. попробовал сделать так:

Select Case W                                               ' включаем цифру которую выбрали (w). Подаем плюс на общий провод конкретной цифры
Case 1 :
If Dp_flag1 = 1 Then Reset Dp Else Set Dp
Set Dig1
Case 2 :
If Dp_flag2 = 1 Then Reset Dp Else Set Dp
Set Dig2
Case 3 :
If Dp_flag3 = 1 Then Reset Dp Else Set Dp
Set Dig3
Case 4 :
If Dp_flag4 = 1 Then Reset Dp Else Set Dp
Set Dig4
Case 5 :
reset Dig1 : reset Dig2 : reset Dig3 : reset Dig4 'сбрасываем первые 4 анода
Set Dig5
Case 6 :
Set Dig6
Case 7 :
Set Dig7
Case 8 :
Set Dig8
End Select

вроде в протеусе работает. в смысле - в единицу времени включен только 1 анод. можно и покрасивше сделать, но потом. и никак не могу побороть периодическое мерцание

0

171

Ну вот, теперь мы знаем, что один индикатор большой. IDok, Вы как партизан. Информацию приходится клещами вытаскивать. А Вы уверены, что конфликт в железе, а не в прошивке. Напишите программу, где просто зажгите два разных числа, на двух индикаторах. И посмотрите, как будет яркость. Тут уже можно будет судить, "кто виноват и что делать".

0

172

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

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

с самого начала не скрывал  :dontknow:

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

А Вы уверены, что конфликт в железе, а не в прошивке

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

0

173

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

вроде в протеусе работает

В Протеусе будет работать, даже если вместо светодиодов будет указан китайский электрочайник. ;)
Протеус - средство для моделирования, а не отслеживания реальных процессов.

Как ведет себя устройство в железе ?
Если так, как было описано ранее - проблема в ИП (изначально).

Что за "большой" и "маленький" индикаторы ?
ТТХ - в студию ! ;)

Отредактировано Nord (2017-10-21 20:55:18)

0

174

доктор, меня все игнорируют (с)  :(

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

ток большого индикатора 25мА при номинальных 4.2В (после транзистора именно это и получается). маленький - 25мА при номинальных 2.7В и максимальных 4.2В

или, если угодно, BL-D56AX22 маленький и SA10-21GWA большой

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

Как ведет себя устройство в железе ?

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

подключаю по одному (каждый на своих ключах разумеется) - все пучком. включаю оба - не все пучком

это в железе, на макетной плате

Отредактировано IDok (2017-10-21 21:04:15)

0

175

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

доктор, меня все игнорируют (с)

Ошибаемся с диагнозом напрочь... ;)

В Протеусе можно отловить программные ошибки, подправить концепцию схемы, но если схема начинает шалить в железе, то Протеус тут уже ни каким боком...
Индикаторы работают в динамическом режиме, а паспортные токи (наверняка) указаны статические...

Не услышал уверений, что ИП вытягивает данную нагрузку...
При разработке блока КУ столкнулся с тем, что выбранная изначально м/с стабилизатора банально "не тянула" подсветку индикатора...
Мелочь, а неприятно...

Отредактировано Nord (2017-10-21 21:15:08)

0

176

А если попробовать в ключи полевики воткнуть? Все таки сопротивление открытого канала меньше, падение напряжения, соответственно, меньше.

0

177

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

Не услышал уверений, что ИП вытягивает данную нагрузку...

следим за руками:
при одном индикаторе при динамической индикации у нас в момент времени горит один сегмент, ток потребления как правило терпимый для ноги МК
при двух индикаторах у нас получается что: мы по очереди включаем все аноды и держим их, потом начинаем включать сегменты. и оп-па - на обоих индикаторах включен один и тот же сегмент! ток по порту ессно вдвое и напряжение падает. маленькому хватает (2.7В), большому же - зась (4.2В). варианты решения: впендюрить ключи на сегменты или не делать так - "мы по очереди включаем все аноды и держим их". т.е. в момент времени не должны быть включены аноды разных индикаторов

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

Не услышал уверений, что ИП вытягивает данную нагрузку

ну, в статике и не вытянет канешн, а в динамике может и устоять. все же максимальный статический ток атмеги8 = 40мА (а на анодах - транзисторы, там аще по барабану)

0

178

Andrusha
да мне как раз падение и не помешало бы, после транзистора будет 4.3В и это самое оно для большого индикатора. да и для маленького всего лишь максимальное. можно не ставить резисторы на сегменты

0

179

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

все же максимальный статический ток атмеги8 = 40мА (а на анодах - транзисторы, там аще по барабану)

МК - по барабану.
Индикатор питает не МК, а ИП... ;)
А указанный ток МК - это нагрузочный на выводах... ;)
Или я неправ ?

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

Отредактировано Nord (2017-10-21 21:33:31)

0

180

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

но указанные симптомы навевают только одно - ИП...

гм. вообще он на 1.5А и полусамопальный... но могу замерить под нагрузкой. в понедельник

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

Индикатор питает не МК, а ИП...

ну при общем аноде наверное Вы правы :)

0