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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » 18B20+mega8 - туплю на ровном месте.


18B20+mega8 - туплю на ровном месте.

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

1

Всем привет. Чета лыжи "не едут" - туплю на ровном месте.

Наваял термометр на ATmega8A и DS18B20 с индикацией на LED-ах. Особенности: измерение десятых долей градуса, гашение незначащего нуля и перемещение знака минус. Исходник, разумеется, на Бейсике. Алгоритм работы с датчиком не совсем "по учебнику" (я самоучка), но работает 100%:

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

Готовое устройство работает уже около года и доступно для повторения:

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

Однако, при попытке повторить свое же "творение" я наступил на грабли и они меня крепко щелкнули по лбу - решил перед прошивкой контроллера немного "прибраться" в исходнике и теперь термометр показывает только "0.0". Где-то подтер нужную строчку или не то вписал - ума не приложу, все глаза уже проглядел в монитор. Не могу найти косяк в своей же писанине (бью себя по лбу).

Друзья, кому не лень полистайте исходник, ткните носом:

Код:
'------------------------------------------------------------------------------
$regfile = "m8adef.dat"                                     'ATmega8A
$crystal = 8000000                                          '8МГц
$prog &HFF , &HC4 , &HD9 , &H00                             'generated. Take care that the chip supports all fuse bytes.
$baud = 9600
'------------------------------------------------------------------------------
Ddrb = &B11111111                                           'PB7, PB6, PB5, PB4, PB3, PB2, PB1, PB0
Ddrc = &B11111111                                           'N/C, RESET, PC5, PC4, PC3, PC2, PC1, PC0
Ddrd = &B11111111                                           'PD7, PD6, PD5, PD4, PD3, PD2, TXD, RXD
'------------------------------------------------------------------------------
Dim Count_led As Byte                                       'переменная счета разряда индикатора
Dim N(4) As Integer                                         'значения разрядов индикатора
Dim T(1) As Integer
Dim Ready_18b20 As Bit
Dim Led As Integer
'------------------------------------------------------------------------------
Config Timer0 = Timer , Prescale = 64                       'переполнение каждые 2мсек.
On Timer0 Refresh_led                                       'обработка прерывания TIMER0
'------------------------------------------------------------------------------
Config 1wire = Portd.0                                      'линия 1-Wire
'------------------------------------------------------------------------------
Dig1 Alias Portd.4                                          '1 разряд
Dig2 Alias Portd.5                                          '2 разряд
Dig3 Alias Portd.6                                          '3 разряд
Dig4 Alias Portd.7                                          '4 разряд
'------------------------------------------------------------------------------
Enable Interrupts                                           'разрешаем использование прерываний
Enable Timer0                                               'разрешаем прерывание по переполнению TIMER0
'------------------------------------------------------------------------------
Maine:
   Do
      If T(1) = 250 Then
         If Ready_18b20 = 0 Then
            1wreset
            1wwrite &HCC                                    'пропуск идентификации датчика
            Stop Timer0                                     'тормозим Timer0 на время конвертирования температуры
            1wwrite &H44                                    'конвертирование температуры
            Start Timer0

         Elseif Ready_18b20 = 1 Then
            1wreset
            1wwrite &HCC                                    'пропуск идентификации датчика
            1wwrite &HBE                                    'чтение памяти
            Led = 1wread(2)                                 'читаем значение температуры

            Stop Timer0                                     'тормозим Timer0 на время обработки значения температуры
            Led = Led * 10                                  'корректируем значение температуры
            Led = Led / 16

            N(2) = Led / 100                                'разбиваем значение температуры на отдельные цифры
            N(2) = Abs(n(2))                                '1 цифра

            N(3) = Led Mod 100                              '2 цифра
            N(3) = N(3) / 10
            N(3) = Abs(n(3))

            N(4) = Led Mod 10                               '3 цифра
            N(4) = Abs(n(4))

            Select Case Led
               Case Is > 999 : N(1) = 1 : N(2) = N(2) - 10  'температура > +99.9 => "1" в 1-сегм., корректировка показаний 2-сегм.
               Case Is > 99 : N(1) = 14                     'температура +9.9...+99.9 => гасим 1-сегм.
               Case Is >= 0 : N(1) = 14 : N(2) = 14         'температура 0...+99.9 => гасим 1-сегм., гасим 2-сегм.
               Case Is >= -99 : N(1) = 14 : N(2) = 10
               Case Is < -99 : N(1) = 10
            End Select
            Start Timer0
         End If

         T(1) = 0
         Toggle Ready_18b20
      End If
   Loop
   End
'------------------------------------------------------------------------------
Refresh_led:                                                'обработка индикации
   Incr Count_led                                           'выбираем разряд для загрузки
   If Count_led > 4 Then Count_led = 1                      'всего 4 разряда

   Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4

   Portb = Lookup(n(count_led) , Digits)                    'закидываем в порт код цифры

   Select Case Count_led                                    'включаем соответствующий разряд индикатора
      Case 1 : Set Dig1                                     '1 разряд
      Case 2 : Set Dig2                                     '2 разряд
      Case 3 : Set Dig3 : Reset Portb.7                     '3 разряд (с запятой)
      Case 4 : Set Dig4                                     '4 разряд
   End Select

   Incr T(1)
Return
'------------------------------------------------------------------------------
Digits:                                                     'символы, выводимые на LED-индикатор
   Data &B11000000 , &B11111001 , &B10100100 , &B10110000   '0 1 2 3
   Data &B10011001 , &B10010010 , &B10000010 , &B11111000   '4 5 6 7
   Data &B10000000 , &B10010000 , &B10111111 , &B10100001   '8 9 - d
   Data &B10000110 , &B10101111 , &B11111111                'E r []
'------------------------------------------------------------------------------

В Протеусе, кстати, все работает, а в железе нет. Доступа к первой поделке нет.

0

2

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

В Протеусе, кстати, все работает, а в железе нет.


Датчик рабочий ?

0

3

Не знаю, что было удалено при "подметании", но вот это зачем-то осталось:
$baud = 9600

На PORTD.0 посажен сигнал датчика и при этом мы разрешаем работу UART ?
Вот и воюют два протокола... ;)

Отредактировано Nord (2018-04-18 01:53:55)

0

4

Далее настройка 1wire + подтяжка  -  должно перетягивать.

на всякий случай:
Ucsrb.rxen = 0      'отключение приёмника USART
Config 1wire = Portd.0       'линия 1-Wire

0

5

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

Далее настройка 1wire + подтяжка  -  должно перетягивать.
            на всякий случай:Ucsrb.rxen = 0      'отключение приёмника USARTConfig 1wire = Portd.0       'линия 1-Wire

Проще $baud заремить при компиляции... ;)

0

6

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

Проще $baud заремить при компиляции


А вдруг что-то надо передать по USART.

0

7

Возможно, это проблема только Меги8, но, если не ремить этот оператор, то в железе с PORTD.0 и PORTD.1 начинаются грабли, если в программе они используются, как входы/выходы.
Если UART никак не упомянут, то проблем нет.

0

8

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

А вдруг что-то надо передать по USART.

У Меги8 не хватает одной ноги, куда 1-Wire можно прицепить ? ;)
Именно туда надо ?

0

9

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

У Меги8 не хватает одной ноги, куда 1-Wire можно прицепить ?
Именно туда надо ?


А вдруг именно туда, пути разработчика не исповедимы !

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

Возможно, это проблема только Меги8, но, если не ремить этот оператор, то в железе с PORTD.0 и PORTD.1 начинаются грабли, если в программе они используются, как входы/выходы.


После Baud=...  просто отключить аппаратную часть RxD или TxD или всё вместе. Вкл/выкл по мере надобности.

0

10

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

После Baud=...  просто отключить аппаратную часть RxD или TxD или всё вместе. Вкл/выкл по мере надобности.

Я же не спорю, я просто указываю на один из вариантов лечения проблемы у ТС... ;)

Словил сам подобное, когда делал контроллер для RGB ленты.
На эти ножки попали D4 и D5 дисплея.
Ух, какая каша была на экране ! ;)
В Протеусе прогонял без дисплея, выводил на терминал, потому baud и остался, хотя все Print'ы заремил...
Заремил его и все устаканилось.

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

0

11

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

Друзья, кому не лень полистайте исходник, ткните носом:

Проверил в железе, Atmega328P с передачей данных по USART, RxD отключен

'------------------------------------------------------------------------------
$regfile = "m328pdef.dat"       'ATmega8A
$crystal = 8000000       '8МГц
'$prog &HFF , &HC4 , &HD9 , &H00       'generated. Take care that the chip supports all fuse bytes.
$baud = 38400
'------------------------------------------------------------------------------
Ddrb = &B11111111       'PB7, PB6, PB5, PB4, PB3, PB2, PB1, PB0
Ddrc = &B11111111       'N/C, RESET, PC5, PC4, PC3, PC2, PC1, PC0
Ddrd = &B11111111       'PD7, PD6, PD5, PD4, PD3, PD2, TXD, RXD
'------------------------------------------------------------------------------
Dim Count_led As Byte       'переменная счета разряда индикатора
Dim N(4) As Integer       'значения разрядов индикатора
Dim T(1) As Integer
Dim Ready_18b20 As Bit
Dim Led As Integer
'------------------------------------------------------------------------------
Config Timer0 = Timer , Prescale = 64       'переполнение каждые 2мсек.
On Timer0 Refresh_led       'обработка прерывания TIMER0
'------------------------------------------------------------------------------
Ucsr0b.rxen0 = 0    'выключение RxD USART
Config 1wire = Portd.0       'линия 1-Wire   
'------------------------------------------------------------------------------
Dig1 Alias Portd.4       '1 разряд
Dig2 Alias Portd.5       '2 разряд
Dig3 Alias Portd.6       '3 разряд
Dig4 Alias Portd.7       '4 разряд
'------------------------------------------------------------------------------
Enable Interrupts       'разрешаем использование прерываний
Enable Timer0       'разрешаем прерывание по переполнению TIMER0
'------------------------------------------------------------------------------
Maine:
   Do
      If T(1) = 250 Then
         If Ready_18b20 = 0 Then
            1wreset
            1wwrite &HCC       'пропуск идентификации датчика
            Stop Timer0       'тормозим Timer0 на время конвертирования температуры
            1wwrite &H44       'конвертирование температуры
            Start Timer0

         Elseif Ready_18b20 = 1 Then
            1wreset
            1wwrite &HCC       'пропуск идентификации датчика
            1wwrite &HBE       'чтение памяти
            Led = 1wread(2)       'читаем значение температуры

            Stop Timer0       'тормозим Timer0 на время обработки значения температуры
            Led = Led * 10       'корректируем значение температуры
            Led = Led / 16

            Print Led

            N(2) = Led / 100       'разбиваем значение температуры на отдельные цифры
            N(2) = Abs(n(2))       '1 цифра

            N(3) = Led Mod 100       '2 цифра
            N(3) = N(3) / 10
            N(3) = Abs(n(3))

            N(4) = Led Mod 10       '3 цифра
            N(4) = Abs(n(4))

            Select Case Led
               Case Is > 999 :
                             N(1) = 1
                             N(2) = N(2) - 10       'температура > +99.9 => "1" в 1-сегм., корректировка показаний 2-сегм.
               Case Is > 99 : N(1) = 14       'температура +9.9...+99.9 => гасим 1-сегм.
               Case Is >= 0 :
                            N(1) = 14
                            N(2) = 14       'температура 0...+99.9 => гасим 1-сегм., гасим 2-сегм.
               Case Is >= -99 :
                            N(1) = 14
                            N(2) = 10
               Case Is < -99 : N(1) = 10
            End Select
            Start Timer0
         End If

         T(1) = 0
         Toggle Ready_18b20
      End If
   Loop
   End
'------------------------------------------------------------------------------
Refresh_led:       'обработка индикации
   Incr Count_led       'выбираем разряд для загрузки
   If Count_led > 4 Then Count_led = 1       'всего 4 разряда

   Reset Dig1 : Reset Dig2 : Reset Dig3 : Reset Dig4

   Portb = Lookup(n(count_led) , Digits)       'закидываем в порт код цифры

   Select Case Count_led       'включаем соответствующий разряд индикатора
      Case 1 : Set Dig1       '1 разряд
      Case 2 : Set Dig2       '2 разряд
      Case 3 :
                Set Dig3
                Reset Portb.7       '3 разряд (с запятой)
      Case 4 : Set Dig4       '4 разряд
   End Select

   Incr T(1)
Return
'------------------------------------------------------------------------------
Digits:       'символы, выводимые на LED-индикатор
   Data &B11000000 , &B11111001 , &B10100100 , &B10110000       '0 1 2 3
   Data &B10011001 , &B10010010 , &B10000010 , &B11111000       '4 5 6 7
   Data &B10000000 , &B10010000 , &B10111111 , &B10100001       '8 9 - d
   Data &B10000110 , &B10101111 , &B11111111       'E r []
'------------------------------------------------------------------------------

Без отключения RxD выдаёт "0"

Сделайте так и всё заработает, при условии отсутствия ошибок в железе:
Ucsrb.rxen = 0      'отключение приёмника USART
Config 1wire = Portd.0       'линия 1-Wire

+1

12

Парни, спасибо огромное - выручили. Все заработало:

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

Ж*пой чуял, что использовать одновременно два вида связи на одной линии к ничему доброму не приведет. Вот и наступил на свои же "грабли".

Я про "$baud=9600" сразу подумал, но когда "заремил" его - ничего не изменилось, показания были по прежнему "0.0". Тут у меня идеи и закончились. А дело было в программаторе USBASP 2.0: отлаживал прошивку не отключая программатор. Сам программатор линии RXD и TXD не использует, но они заведены в микроконтроллер. Т.к. я повесил вывод DQ термодатчика на провод RXD - линия связи с датчиком перестала работать из-за того, что она "подтянута" микроконтроллером программатора к плюсу (или минусу).

Т.к. от аппаратного UART в устройстве я отказываться не намерен (планирую передавать данные для удаленного контроля), переделал выход DQ на другой свободный вывод МК и свободный вывод в разъеме. Схема получилась так:

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

Спасибо Nord и sasha_1973 (за то, что проверил "в железе").

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » 18B20+mega8 - туплю на ровном месте.