1Wire не запустился. 
Беда та же: жесточайшее нарушение временных параметров протоколов.
Или Bascom-51 заточен под что-то ну совсем древнее, или я что-то в нём не так настраиваю.
Программирование ATMEL в BASCOM. |
Привет, Гость! Войдите или зарегистрируйтесь.
Вы здесь » Программирование ATMEL в BASCOM. » Аппаратные возможности МК серии STC8H1Kxxx » 1Wire
1Wire не запустился. 
Беда та же: жесточайшее нарушение временных параметров протоколов.
Или Bascom-51 заточен под что-то ну совсем древнее, или я что-то в нём не так настраиваю.
1Wire не запустился.
Беда та же: жесточайшее нарушение временных параметров протоколов.
Или Bascom-51 заточен под что-то ну совсем древнее, или я что-то в нём не так настраиваю.
В протоколе 1W всем рулит ведущий, т.е. МК.
Вы пробовали этот подход ?
ИМХО, должно сработать...
вообще ничего не проверял "самодельного".
Тестировал только родные библиотеки Bascom
вообще ничего не проверял "самодельного".
Тестировал только родные библиотеки Bascom
Я "8051" не ставил, не знаю как он с привычными МК (AVR) работает, но в указанной "самоделке" мной использованы наработки другого автора в попытке получить что-то удобоваримое для себя.
В конце концов - Ассм - он и на Марсе Ассм... 
Получилось. С некоторыми издержками (там указаны).
Получилось даже чуть больше - DS18B20 "частично эмулировали"... 
Единственное, что не удалось "перешагнуть" - работа с ID...
Так что для написания собственной LIB для работы с 1W вполне сгодится.
ассм у АВР и 8051 - разный,
железо - тоже.
Только брать описание алгоритма обмена и реализовывать.
ассм у АВР и 8051 - разный,
железо - тоже.
Только брать описание алгоритма обмена и реализовывать.
А я же не предлагаю прямое использование.
Взять концепцию, логику работы и "перевести" на используемый язык.
СИшную клинопись же портируем порой в Bascom и наоборот... 
понял
ну, при изменении тактовой - это понятное дело!
Я так в своё время "ловил" биты по линии питания коммутатора спутникового сигнала - DISEqC
Стоило сменить кварц - всё заново ((
А эта линейка МК вообще где-то работает с 1W ?
не понял вопроса
Бери да пиши, главное чтобы мог читать и писать в порты )
Аппаратный нигде не встречал.
писать LIB для работы этого МК с 1W
А что понимается под LIB? чем тут она отличается от Подпрограммы, подгруженной по Include?
А что понимается под LIB? чем тут она отличается от Подпрограммы, подгруженной по Include?
Под LIB подразумевается код в любом виде, вызываемый любым способом, позволяющий работать с 1W.
короче: Если опустить тактовую МК до 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
Впору затянуться и выдохнуть УФФФ! ))) Благо я не курю.
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
Если ниже - программа загрузки STC-isp подбирает оптимальное значение ТЧ...
Программа выбирает частоту генератора 24 MHz и делитель 3 и загружает в спец.регистры в процессе загрузки программы.
Поняв это, я на лету меняю...
Если я это правильно понял, то при указании ТЧ ниже какого-то предела, эта самая "программа загрузки STC-isp" принимает на себя функции "решальщика" и определяет на какой ТЧ будет работать МК ?
Уже ИИ попахивает... 
Хорошо, хоть не втайне, а указывает в спец.регистры, в которые надо заглянуть, чтоб "понять это"...
А ты потом заворачивайся в десять узлов, пытаясь мигнуть светиком...
Что курили разработчики ? 
всё удивительно гармонично и логично, никакой ИИ не нужен: банальные 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.
Посмотрел декомпил встроенного 1w. Он заточен под фиксированную частоту классического 12T. Буду своё лепить.
Буду своё лепить.
Лучше на UART.
Потому что программный чувствительный к прерываниям и у меня не раз было что встроенные функции 1Wire нормально не работали если использовались прерывания.
Отредактировано Пётр (2026-08-22 14:02:08)
Нужно запрещать прерывания перед работой с 1w. Да и задача простая: принять на одну ногу мастером и отправить на другую слейвом.
А если в жирную портянку потом понадобится, то просто переделать на UART.
Код:$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)
Посмотрел декомпил встроенного 1w. Он заточен под фиксированную частоту классического 12T. Буду своё лепить.
Там ещё нет таумаутов при зависании линии.
Для чистых и коротких линий нормально и так, но с удалённой и зашумлённой линией не стану такое использовать.
Мажоритарная система и только так.
Мажоритарная система для всех данных или только КС? Это же как минимум в три раза больше данных. Но если для серьезного проекта, то да.
Мажоритарная для всей посылки.
Мне нужно по итогу пустить линию по длинному плоскому шлейфу FFC (если взлетит, но попробую; пока на метровом куске мусора проверяется) в самый ад с наводками от инверторного компрессора прямо по металлическому корпусу.
Мне нужно по итогу пустить линию по длинному плоскому шлейфу FFC
Тонкий экранированный кабель не получится пустить? В крайнем случае витую пару.
Потому что если помех много и они интенсивные, может вообще нормально не работать.
Отредактировано Пётр (2026-08-25 16:51:36)
Тонкий экранированный кабель не получится пустить? В крайнем случае витую пару.
Потому что если помех много и они интенсивные, может вообще нормально не работать.
Присоединяюсь 
Для длинной линии лучше витой пары, да если еще с экраном - лучше не придумать.
Да и не слишком удорожает конструкцию по сравнению с программным решением головоломок.
Витая пара и любой другой вариант не подходят. Нужно плоский кабель. Из лучших вариантов коса из самого тонкого МГТФ.
Не надо ничего делить и лепить
Понижаете тактовую, пауза один такт. Работаете с медленной шиной . Вертаете взад частоту МК. Ждёте один такт
Всё работает
Там же в моём коде есть пример.
Слеплено уже. Во встроенном коде нет защиты от зависания потому что автор процедур просто ждёт изменения уровня шины.
Мажоритарная для всей посылки.
Адаптивный дискретно-интегральный метод. В топку полумеры. Цеплял 2,2 нФ на линию - читает; цеплял ~5,5 нФ - не читает; граница где-то между.
Цеплял 2,2 нФ на линию - читает; цеплял ~5,5 нФ - не читает; граница где-то между.
3,3 нФ ? 
Цеплял 2,2 нФ на линию
Про индуктивность не забудьте чтобы отсеять высокочастотные помехи.
Прерывания при работе можно не глушить.
У меня двухсторонняя не блокируемая ожиданиями флагов приём\передача (на приём кольцевой буфер чтобы успевать).
Поэтому работа с 1w только вручную.
Перед вызовом процедуры отправки байта с командой сбрасываем флаг, который в случае прерывания UART устанавливается в самом прерывании.
Если при выводе очередного бита команды этот флаг появится, то прерываем отправку по 1w и считаем этот сеанс не валидным. Потом просто повторяем через определённый интервал времени.
С приёмом же данных в ответ на команду всё проще, проверяем контрольную сумму.
Отредактировано Кот Обормот (2026-09-12 18:10:51)
Прерывания при работе можно не глушить.
Смотря какая у них длительность.
Если они долго выполняются, тогда могут мешать библиотеке 1Wire баскома.
Вы здесь » Программирование ATMEL в BASCOM. » Аппаратные возможности МК серии STC8H1Kxxx » 1Wire