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

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

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

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



1Wire

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

1

1Wire не запустился. :(

Беда та же: жесточайшее нарушение временных параметров протоколов.
Или Bascom-51 заточен под что-то ну совсем древнее, или я что-то в нём не так настраиваю.

0

2

Александр Д. написал(а):

1Wire не запустился.
Беда та же: жесточайшее нарушение временных параметров протоколов.
Или Bascom-51 заточен под что-то ну совсем древнее, или я что-то в нём не так настраиваю.

В протоколе 1W всем рулит ведущий, т.е. МК.

Вы пробовали этот подход ?
ИМХО, должно сработать...

0

3

вообще ничего не проверял "самодельного".
Тестировал только родные библиотеки Bascom

0

4

Александр Д. написал(а):

вообще ничего не проверял "самодельного".
Тестировал только родные библиотеки Bascom

Я "8051" не ставил, не знаю как он с привычными МК (AVR) работает, но в указанной "самоделке" мной использованы наработки другого автора в попытке получить что-то удобоваримое для себя.
В конце концов - Ассм - он и на Марсе Ассм... ;)
Получилось. С некоторыми издержками (там указаны).
Получилось даже чуть больше - DS18B20 "частично эмулировали"... ;)

Единственное, что не удалось "перешагнуть" - работа с ID...

Так что для написания собственной LIB для работы с 1W вполне сгодится.

0

5

ассм у АВР и 8051 - разный,
железо - тоже.
Только брать описание алгоритма обмена и реализовывать.

0

6

Александр Д. написал(а):

ассм у АВР и 8051 - разный,
железо - тоже.
Только брать описание алгоритма обмена и реализовывать.

А я же не предлагаю прямое использование.

Взять концепцию, логику работы и "перевести" на используемый язык.
СИшную клинопись же портируем порой в Bascom и наоборот... ;)

0

7

понял
ну, при изменении тактовой - это понятное дело!
Я так в своё время "ловил" биты по линии питания коммутатора спутникового сигнала - DISEqC
Стоило сменить кварц - всё заново ((

0

8

А эта линейка МК вообще где-то работает с 1W ?

0

9

не понял вопроса
Бери да пиши, главное чтобы мог читать и писать в порты )
Аппаратный нигде не встречал.

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

писать LIB для работы этого МК с 1W

А что понимается под LIB? чем тут она отличается от Подпрограммы, подгруженной по Include?

0

10

Александр Д. написал(а):

А что понимается под LIB? чем тут она отличается от Подпрограммы, подгруженной по Include?

Под LIB подразумевается код в любом виде, вызываемый любым способом, позволяющий работать с 1W.

0

11

короче: Если опустить тактовую МК до 1Mhz, то  1Wire работает

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 1000000                        ' CPU clock frequence '11059200/2= 5529600
$romstart = &H0                           ' code starting address

Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte

Dim S$ As String * 16 , I As Byte , A As Byte
Dim Ar(9) As Byte


P1ie = &B1111_1111                        ' 1: Enable digital pins
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m0 = &B0000_0100 : P1m1 = &B0000_0000   ' output mode

P3ie = &B1111_1111                        ' 1: Enable digital pins
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m0 = &B0000_0010 : P3m1 = &B0000_0000   ' output mode

Config 1wire = P1.0                       ' 1wire use this pin

My_led Alias P1.2

' UART
P_sw1 = &H00                  'RXD/P3.0, TXD/P3.1

Scon = &H50                   ' 8-Bits And Variable Baudrate
Auxr = &H54                               'Timer is 1T mode, use Timer1 as baudrate generator
Tmod = Tmod And &H0F          'Set timer work mode
Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 19200 / 1MHz
Et1 = 0                       'Disable Timer interrupt
Tr1 = 1                       'Timer1 start run
Sbuf = 0                      ' Magic ...

My_led = 0
Waitms 50

Print " Start!"
My_led = 1

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' 204 Выдаем команду чтения ПЗУ
1wwrite &H4E                              ' 78 Установим разрядность термодатчика
1wwrite 0
1wwrite 0

1wwrite &H1F                              ' 31 Configuration 9-BIT Mode 0.5° 94 mS

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' 204 Выдаем команду чтения ПЗУ
1wwrite &H44                              ' 68 Запуск измерения

My_led = 0

Waitms 255

My_led = 1

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' 204 Команда чтения ПЗУ
1wwrite &HBE                              ' 190 Команда чтения ОЗУ датчика  Ds18b20

For I = 1 To 9
 Ar(i) = 1wread()                         'place into array
Next
For I = 1 To 9
 Printhex Ar(i) ; " ";                    'print output
Next
Print

' Проверяем на отрицательную температуру. 248 в десятичном, 11111000 в двоичном.
If Ar(2) >= 248 Then                      ' Если температура отрицательная – вычитаем из &HFF
 Ar(1) = &HFF - Ar(1)
 Ar(2) = &HFF - Ar(2)
End If


Temp = Ar(1) : Temp = Temp And &B00001111       ' оставим 4 младших бита = Т после запятой

Shift Ar(1) , Right , 4                   ' Сдвигаем первый байт вправо на 4 бита
Shift Ar(2) , Left , 4                    ' Сдвигаем второй байт влево на 4 бита

Temp = Ar(1) + Ar(2)                      ' Формируем результат целой части значения температуры
Print Temp ; "'C"


Do
 My_led = Not My_led
 Waitms 35
Loop


Есть идея:

работать на какой надо частоте, потом опускать её до 1 МГц и запоминать, дальше возвращать частоту МК на нужную и обрабатывать

Ту же идею хочу проверить на LCD1602

0

12

Впору затянуться и выдохнуть УФФФ! ))) Благо я не курю.
1Wire работает

Такого изгольства я не ожидал ни от производителей МК, ни от себя )))

В Мк имеется точный генератор тактовой частоты.
Имеется ряд откалиброванных значений в неких пределах. И хитрый делитель этой частоты.
Если вы указали ТЧ из списка предложенных, то делитель =0
Если ниже - программа загрузки STC-isp подбирает оптимальное значение ТЧ и делителя для достижения результата.

Т.е., я выставил тч МК = 8MHz
Программа выбирает частоту генератора 24 MHz  и делитель 3 и загружает в спец.регистры в процессе загрузки программы.
Поняв это, я на лету меняю делитель с 3 на 24, тем самым изменяя тч с 8 до 1 MHz.
Делаю всё работы с 1Wire и возвращаю тч обратно (после смены частоты требуется некая пауза для стабилизации, я ставлю просто Waitms 1)

Код:
$regfile = "STC_8H.DAT"                   ' STC registers list
$crystal = 5529600                        ' CPU clock frequence '11059200/2= 5529600
$romstart = &H0                           ' code starting address

Dim Temp As Byte , Temp_w As Byte , Adres_w As Word , Flag_sost As Byte

Dim S$ As String * 16 , I As Byte , A As Byte , Minus As Byte
Dim Ar(9) As Byte


P1ie = &B1111_1111                        ' 1: Enable digital pins
P1pu = &B0000_0000                        ' 1: pull-up resistor
P1m0 = &B0000_0100 : P1m1 = &B0000_0000   ' output mode

P3ie = &B1111_1111                        ' 1: Enable digital pins
P3pu = &B0000_0000                        ' 1: pull-up resistor
P3m0 = &B0000_0010 : P3m1 = &B0000_0000   ' output mode

My_led Alias P1.2
My_led = 1

Config 1wire = P1.0                       ' 1wire use this pin


' UART
P_sw1 = &H00                  ' RXD/P3.0, TXD/P3.1
'P_sw1 = &H40                              'RXD_2/P3.6, TXD_2/P3.7
'P_sw1 = &H80                              'RXD_3/P1.6, TXD_3/P1.7

Scon = &H50                               ' 8-Bits And Variable Baudrate
Auxr = &H54                               ' Timer is 1T mode, use Timer1 as baudrate generator
Tmod = Tmod And &H0F                      ' Set timer work mode

'Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 19200 / 1MHz
'Tl1 = &HF3 : Th1 = &HFF                   'Initial timer - 38400 / 2MHz
Tl1 = &HCC : Th1 = &HFF                   'Initial timer - 38400 / 8MHz
'Tl1 = &HE0 : Th1 = &HFE                   'Initial timer - 9600 / 11059200
'Tl1 = &HE8 : Th1 = &HFF                   'Initial timer - 115200 / 11059200

Et1 = 0                       ' Disable Timer interrupt
Tr1 = 1                       ' Timer1 start run
Sbuf = 0                      ' Magic ...

Waitms 10
Print " Start!"

P_sw2.7 = 1
Clkdiv = 24
P_sw2.7 = 0
Waitms 1

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' Выдаем команду чтения ПЗУ
1wwrite &H4E                              ' Установим разрядность термодатчика
1wwrite 0
1wwrite 0

1wwrite &H1F                              ' Configuration 9-BIT Mode       0.5° 94 mS
'1wwrite &H7F                             ' Configuration 12-BIT Mode  0.0625° 750 mS

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' Выдаем команду чтения ПЗУ
1wwrite &H44                              ' Запуск измерения

My_led = 0

Waitms 15                                 ' на скорости 1 Mhz это примерно 125 mS

My_led = 1

1wreset                                   ' Инициализация шины 1Wire
1wwrite &HCC                              ' Команда чтения ПЗУ
1wwrite &HBE                              ' Команда чтения ОЗУ датчика Ds18b20
For I = 1 To 9
 Ar(i) = 1wread()                         'place into array
Next

P_sw2.7 = 1
Clkdiv = 3
P_sw2.7 = 0
Waitms 50

For I = 1 To 9
 Printhex Ar(i) ; " ";                    'print output
Next
Print

Minus = 0
' Проверяем на отрицательную температуру. 248 в десятичном, 11111000 в двоичном.
If Ar(2) >= 248 Then                      ' Если температура отрицательная – вычитаем из &HFF
 Ar(1) = &HFF - Ar(1)
 Ar(2) = &HFF - Ar(2)
 Minus = 1
End If

Shift Ar(1) , Right , 4                   ' Сдвигаем первый байт вправо на 4 бита
Shift Ar(2) , Left , 4                    ' Сдвигаем второй байт влево на 4 бита
Temp = Ar(1) + Ar(2)                      ' Формируем результат целой части значения температуры

If Minus = 1 Then Print "-";
Print Temp ; "'C"


Do
 My_led = Not My_led
 Waitms 35
Loop

+1

13

Александр Д. написал(а):

Если ниже - программа загрузки STC-isp подбирает оптимальное значение ТЧ...
Программа выбирает частоту генератора 24 MHz  и делитель 3 и загружает в спец.регистры в процессе загрузки программы.
Поняв это, я на лету меняю...

Если я это правильно понял, то при указании ТЧ ниже какого-то предела, эта самая "программа загрузки STC-isp" принимает на себя функции "решальщика" и определяет на какой ТЧ будет работать МК ?
Уже ИИ попахивает... ;)
Хорошо, хоть не втайне, а указывает в спец.регистры, в которые надо заглянуть, чтоб "понять это"...  :canthearyou:
А ты потом заворачивайся в десять узлов, пытаясь мигнуть светиком...
Что курили разработчики ? ;)

0

14

всё удивительно гармонично и логично, никакой ИИ не нужен: банальные 10-15 условий и несколько реперных точек в выборе частоты

Регулируемые диапазоны двух частотных диапазонов микроконтроллеров серии STC8H составляют от 15,5 до 27 МГц и от 25,3 до 43,6 МГц соответственно.
Хотя верхний предел диапазона частот 35 МГц можно регулировать до значения более 40 МГц, внутренняя флэш-память программ чипа не может работать на скорости более 40 МГц.
Поэтому при использовании загрузки через ISP вам следует установить внутреннюю частоту IRC не выше 40 МГц. Обычно рекомендуется устанавливать частоту ниже 35 МГц.
Если вам нужна более низкая рабочая частота, вы можете использовать регистр CLKDIV для деления настроенной частоты.
Например, если вам нужна частота 11,0592 МГц, и эту частоту невозможно получить с помощью внутренней регулировки IRC,
но внутренний IRC можно настроить на 22,1184 МГц, вы можете получить 11,0592 МГц, разделив на 2 с помощью CLKDIV.

Примечание. После сброса пользовательской программы система автоматически установит начальное значение этого регистра в соответствии с коэффициентом деления частоты, необходимым для рабочей частоты, установленной во время последней загрузки ISP.

0

15

Посмотрел декомпил встроенного 1w. Он заточен под фиксированную частоту классического 12T. Буду своё лепить.

0

16

Кот Обормот написал(а):

Буду своё лепить.

Лучше на UART.
Потому что программный чувствительный к прерываниям и у меня не раз было что встроенные функции 1Wire нормально не работали если использовались прерывания.

Отредактировано Пётр (2026-08-22 14:02:08)

0

17

Нужно запрещать прерывания перед работой с 1w. Да и задача простая: принять на одну ногу мастером и отправить на другую слейвом.
А если в жирную портянку потом понадобится, то просто переделать на UART.

Контрольная сумма для DS18B20
Код:
$regfile = "8H1K08.DAT"
$crystal = 6000000
$ramsize = 1024
$map
$large

Dim Crc_calc As Byte

Dim 1w_arr(9) As Xram Byte
'(
1w_arr(1) = &H14
1w_arr(2) = &HFE
1w_arr(3) = &H4B
1w_arr(4) = &H46
1w_arr(5) = &H7F
1w_arr(6) = &HFF
1w_arr(7) = &H0C
1w_arr(8) = &H10
1w_arr(9) = &HB2
')
1w_arr(1) = &H50
1w_arr(2) = &H05
1w_arr(3) = &H4B
1w_arr(4) = &H46
1w_arr(5) = &H7F
1w_arr(6) = &HFF
1w_arr(7) = &H0C
1w_arr(8) = &H10
1w_arr(9) = &H1C
$asm
      MOV   R7, #8           ' Счетчик байт (считаем 8 байт)
      MOV   R0, #0           ' Инициализация CRC = 0
      MOV   DPtr, #{1w_arr}  ' Адрес массива в XRAM

   Crc_Byte_Loop:
      MOVX  A, @DPTR         ' Читаем байт из XRAM
      INC   DPTR             ' Сдвигаем указатель
      MOV   R2, A            ' Сохраняем прочитанный байт в R2 (он будет нашими данными)
      MOV   R1, #8           ' Счетчик бит (8 бит в байте)

   Crc_Bit_Loop:
      ' 1. Проверяем младший бит: (Data XOR CRC) & 1
      MOV   A, R2            ' Берем данные
      XRL   A, R0            ' Ксорим с текущим CRC
      RRC   A                ' Сдвигаем вправо. Флаг C ahora содержит нужный бит (0 или 1)
      JC    Do_Xor           ' Если C=1, прыгаем делать XOR с полиномом

      ' 2. Ветка C=0: просто сдвигаем CRC вправо
      MOV   A, R0
      CLR   C
      RRC   A                ' Сдвигаем CRC вправо (старший бит становится 0)
      SJMP  Next_Bit         ' Идем к следующему биту

      ' 3. Ветка C=1: сдвигаем CRC и ксорим с полиномом 0x8C
   Do_Xor:
      MOV   A, R0
      CLR   C
      RRC   A                ' Сдвигаем CRC вправо
      XRL   A, #140         ' Накладываем отраженный полином 1-Wire (0x8C)

   Next_Bit:
      MOV   R0, A            ' Сохраняем обновленный CRC обратно в R0
      MOV   A, R2            ' Берем обратно наши данные
      CLR   C
      RRC   A                ' Сдвигаем данные вправо, чтобы на следующем шаге проверить следующий бит
      MOV   R2, A            ' Сохраняем сдвинутые данные
      DJNZ  R1, Crc_Bit_Loop ' Повторяем 8 раз для каждого бита

      DJNZ  R7, Crc_Byte_Loop' Переходим к следующему байту массива

      ' Записываем финальный результат из R0 в переменную Crc_calc
      MOV   A, R0
      MOV   {Crc_calc}, A
$end Asm

' Проверка результата
Printhex 1w_arr(9)
Printhex Crc_calc


Do

Loop

Проверял в симуляторе, но пример данных взят захватом шины у железки.

Отредактировано Кот Обормот (2026-08-22 15:47:42)

0

18

Кот Обормот написал(а):

Посмотрел декомпил встроенного 1w. Он заточен под фиксированную частоту классического 12T. Буду своё лепить.

Там ещё нет таумаутов при зависании линии.
Для чистых и коротких линий нормально и так, но с удалённой и зашумлённой линией не стану такое использовать.
Мажоритарная система и  только так.

0

19

Мажоритарная система для всех данных или только КС? Это же как минимум в три раза больше данных. Но если для серьезного проекта, то да.

0

20

Мажоритарная для всей посылки.
Мне нужно по итогу пустить линию по длинному плоскому шлейфу FFC (если взлетит, но попробую; пока на метровом куске мусора проверяется) в самый ад с наводками от инверторного компрессора прямо по металлическому корпусу.

+1

21

Кот Обормот написал(а):

Мне нужно по итогу пустить линию по длинному плоскому шлейфу FFC

Тонкий экранированный кабель не получится пустить? В крайнем случае витую пару.
Потому что если помех много и они интенсивные, может вообще нормально не работать.

Отредактировано Пётр (2026-08-25 16:51:36)

0

22

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

Тонкий экранированный кабель не получится пустить? В крайнем случае витую пару.
Потому что если помех много и они интенсивные, может вообще нормально не работать.

Присоединяюсь ;)
Для длинной линии лучше витой пары, да если еще с экраном - лучше не придумать.
Да и не слишком удорожает конструкцию по сравнению с программным решением головоломок.

0

23

Витая пара и любой другой вариант не подходят. Нужно плоский кабель. Из лучших вариантов коса из самого тонкого МГТФ.

0

24

Не надо ничего делить и лепить
Понижаете тактовую, пауза один такт. Работаете с медленной шиной . Вертаете взад частоту МК. Ждёте один такт
Всё работает
Там же в моём коде есть пример.

0

25

Слеплено уже. Во встроенном коде нет защиты от зависания потому что автор процедур просто ждёт изменения уровня шины.

+1

26

Кот Обормот написал(а):

Мажоритарная для всей посылки.

Адаптивный дискретно-интегральный метод. В топку полумеры. Цеплял 2,2 нФ на линию - читает; цеплял ~5,5 нФ - не читает; граница где-то между.

0

27

Кот Обормот написал(а):

Цеплял 2,2 нФ на линию - читает; цеплял ~5,5 нФ - не читает; граница где-то между.

3,3 нФ ? ;)

0

28

Кот Обормот написал(а):

Цеплял 2,2 нФ на линию

Про индуктивность не забудьте чтобы отсеять высокочастотные помехи.

0

29

Прерывания при работе можно не глушить.
У меня двухсторонняя не блокируемая ожиданиями флагов приём\передача (на приём кольцевой буфер чтобы успевать).
Поэтому работа с 1w только вручную.
Перед вызовом процедуры отправки байта с командой сбрасываем флаг, который в случае прерывания UART устанавливается в самом прерывании.
Если при выводе очередного бита команды этот флаг появится, то прерываем отправку по 1w и считаем этот сеанс не валидным. Потом просто повторяем через определённый интервал времени.
С приёмом же данных в ответ на команду всё проще, проверяем контрольную сумму.

Отредактировано Кот Обормот (2026-09-12 18:10:51)

0

30

Кот Обормот написал(а):

Прерывания при работе можно не глушить.

Смотря какая у них длительность.
Если они долго выполняются, тогда могут мешать библиотеке 1Wire баскома.

0