Угу, понятно, обучалка вроде нашей - принцип показан, но без конкретики и на практике еёйные прымэры лучше не пользовать..... Спасибо за наводку! Собственно проблема была несколько ширше - имел нужду читать только младшую тетраду порта, игнорируя старшую. В баскоме всё прокатывало, а вот в протеусе фигвам - сколь ни толмил конфиги и ДДРы биты старшей тетрады никак не хотели игнориться (может, конечно, это всего-лишь особенности протеуса). Короче не знаю, насколь это по жлобски, но проблема решилась только по-битным разбиением переменной.
DDRD = 11110000 ..........
Bndn = 0 Bndn.3 = Pind.3 Bndn.2 = Pind.2 Bndn.1 = Pind.1 Bndn.0 = Pind.0 If Bndn.0 <> Bnd.0 or Bndn.1 <> Bnd.1 or Bndn.2 <> Bnd.2 or Bndn.3 <> Bnd.3 Then Start Watchdog
Еще раз спасибо!
_________________ В начале жизнь мучает вопросами, в конце - ответами...
Работать это будет одинаково, так что как хочется, так и пишите.
Работать - да, но все же пара команд LDI/OUT лучше чем 8 штук SBI/CBI.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
edm2007, тут вот какая штука. В начале разработки я рисую схему в протеусе и под нее пишу программу. В программе обозначены порты через SBI/CBI, а работа в программе с ними через алиасы. Потом, при создании печатной платы, зачастую меняется назначение портов для оптимальной разводки. При этом в программе нужно изменить порт только в одном месте - где прописан алиас. А с LDI/OUT придется лопатить всю программу, где упоминается измененные порты.
Это разумеется, у меня вся периферия дефайнами на порты / пины цепляется, и проблем никаких нет. Я немного о другом, я о том, во что превращается первый и второй вариант.
_________________ "Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Здравствуйте уважаемые коты! Прошу помощи в реализации такого алгоритма: Есть некоторый параметр (к примеру число импульсов, которые следует отсчитать до срабатывания реле) имеющий вид многоразрядного (ну предположим 8-ми разрядного) числа. И нужна его предварительная установка одной кнопкой. Естейственно нажимать кнопку миллион с лишнем раз, пока не достигнется нужного показателя- не реально. Как поразрядно настроить нужное значение? Например: первое длительное нажатие кнопки- устройство переходит в режим настройки и начинает мигать самый младший разряд 8-ми разрядного семисегментного индикатора. Далее последовательно, короткими нажатиями той же кнопки, число в этом разряде устанавливается от 0 до 9 и запись установленного значения в память МК. Длительное назатие кнопки переключает на соседний, более старший разряд и процедура повторяется вплоть до настройки самого старшего разряда. Следующее длительное нажатие вызывает запись всего установ ленного числа в память и выход из режимапредустановки. Я думаю, алгоритм получился бы довольно универсальный и мог бы пригодиться для разработки многих устройств, требующих предустановку отслеживаемого параметра. Мне это нужно для программы двухканального реверсивного счётчика импульсов с предустановкой начала отсчёта. Планирую использовать его для подсчёта израсходованого бензина в машине. В связке с двумя роторными датчиками расхода (как стоят в кофемашинах) Один будет стоять в прямой магистрали (будет вычитать импульсы), другой в обратке (прибавлять). А разница в в том, что они насчитают, умноженая на кол-во импульсов на литр (устанавливается в программе) и будет искомый расход. Т.е, заправил некоторое количество топлива, ввёл это значение и в любой момент знаеш сколько у тебя РЕАЛЬНО осталось в баке! Неделю пытался биться с Bascom AVR самостоятельно, пришёл только к самому счётчику. А вот с предварительной настройкой- никак не получается. Вот код, что у меня получился и проэкт в Протеусе.
Код:
$regfile = "m8def.dat" $crystal = 4000000
' * * * заводим переменные * * * Dim A As Integer Dim W As Word Dim B As Byte Dim C As Byte
Dim N1 As Byte Dim N2 As Byte Dim N3 As Byte
Dim M1 As Integer Dim M2 As Integer Dim M3 As Integer
M1 = W ' вот это число будем отображать M2 = M1 M3 = M1
M1 = M1 / 100 'обработка первого числа N1 = Abs(m1)
M2 = M2 Mod 100 'обработка второго числа M2 = M2 / 10 N2 = Abs(m2)
M3 = M3 Mod 10 ' обработка четвертого числа N3 = Abs(m3)
Gosub Led 'после преобразования вызываем подпрограмму обработки индикации
Loop
'* * * подпрограма обработки индикации * * *
Led: 'зажигаем первое число
Portd = &B01000000 'зажигаем первое число If N1 = 0 Then 'гашение не значащих нулей Portd = &B00000000 End If
Select Case N1 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select
Waitms 5
Portd = &B00100000 'зажигаем второе число вместе с точкой If N2 = 0 And N1 = 0 Then 'гашение не значащих нулей Portd = &B00000000 End If
Select Case N2 Case 0 : Portb = &B01000000 Case 1 : Portb = &B01111001 Case 2 : Portb = &B00100100 Case 3 : Portb = &B00110000 Case 4 : Portb = &B00011001 Case 5 : Portb = &B00010010 Case 6 : Portb = &B00000010 Case 7 : Portb = &B01111000 Case 8 : Portb = &B00000000 Case 9 : Portb = &B00010000 End Select
Waitms 5
Portd = &B00010000 'зажигаем третье число
Select Case N3 Case 0 : Portb = &B11000000 Case 1 : Portb = &B11111001 Case 2 : Portb = &B10100100 Case 3 : Portb = &B10110000 Case 4 : Portb = &B10011001 Case 5 : Portb = &B10010010 Case 6 : Portb = &B10000010 Case 7 : Portb = &B11111000 Case 8 : Portb = &B10000000 Case 9 : Portb = &B10010000 End Select
Waitms 5 Return
'Подпрограмма обработки прерываний от датчиков Schet: If Pinc.2 = 0 Then Waitms 5 Incr A End If If Pinc.3 = 0 Then Waitms 5 Decr A End If 'коэффициент пересчёта If A = 2 Then Incr W A = 0 End If
If A = -2 Then Decr W A = 0 End If Writeeeprom W , Wdata
Return 'вот до сюда, работает
Knopka: Readeeprom W , Wdata M1 = W 'разбиваем число W на цифры- значения отдельных разрядов M2 = M1 M3 = M1
M1 = M1 / 100 N1 = Abs(m1)
M2 = M2 Mod 100 M2 = M2 / 10 N2 = Abs(m2)
M3 = M3 Mod 10 N3 = Abs(m3) Reset C While Pinc.0 = 0 'если кнопка нажата Incr B 'идёт приращение переменной B If B => 200 Then 'если нажатие длиное C = C + 1 'Прибавить Единицу К Переменной С End If B = 0
If C = 1 Then 'если значение С равно одному, то Gosub Digit_3 'подпрограмму настройки третьего разряда End If
If C = 2 Then 'если значение С равно двум, то Gosub Digit_2 End If
If C = 3 Then 'если значение С равно трём, то Gosub Digit_1 End If
If C = 4 Then Gosub Vihod End If Wend B = 0
'третий разряд
Digit_3: C = 1 Do 'запуск цикла мигания третьим разрядом Portd = &B01100000 Waitms 400 Portd = &B01110000 Waitms 400 While Pinc.0 = 0 'отслеживать повторное ДЛИТЕЛЬНОЕ нажатие Incr B If B => 200 Then 'при повторном длительном нажатии B = 0 C = C + 1 'прибавить единицу к значению C End If Wend If Pinc.0 = 0 Then 'в случае короткого нажатия N3 = N3 + 1 'прибавить единицу к значению N3 End If 'при достижении N3 значения 9, сбросить N3 на ноль If N3 > 9 Then N3 = 0 End If
Loop Until C <> 1 'если значение C неравно одному, то выход из цикла
' второй разряд
Digit_2: C = 2 Do 'запуск цикла мигания вторым разрядом Portd = &B01010000 Waitms 400 Portd = &B01110000 Waitms 400 While Pinc.0 = 0 'отслеживать повторное ДЛИТЕЛЬНОЕ нажатие Incr B If B => 200 Then 'при повторном длительном нажатии B = 0 C = C + 1 'прибавить единицу к значению C End If Wend If Pinc.0 = 0 Then 'в случае короткого нажатия N2 = N2 + 1 'прибавить единицу к значению N2 End If 'при достижении N2 значения 9, сбросить N2 на ноль If N2 > 9 Then N2 = 0 End If
Loop Until C <> 2 'если значение C неравно двум, то выход из цикла
'первый разряд
Digit_1: C = 3 Do 'запуск цикла мигания первым разрядом Portd = &B00110000 Waitms 400 Portd = &B01110000 Waitms 400 While Pinc.0 = 0 'отслеживать повторное ДЛИТЕЛЬНОЕ нажатие Incr B If B = 200 Then B = 0 'при повторном длительном нажатии C = C + 1 'прибавить единицу к значению C End If Wend If Pinc.0 = 0 Then 'в случае короткого нажатия N1 = N1 + 1 'прибавить единицу к значению N1 End If If N1 > 9 Then 'при достижении N1 значения 9, сбросить N1 на ноль N1 = 0 End If
Loop Until C <> 3 'если значение C неравно трём, то выход из цикла
N2 = N2 * 10 N2 = N2 + N3 'собираем обратно, из отдельных цифр N1, N2 и N3 число W N1 = N1 * 100 W = N1 + N2
Writeeeprom W , Wdata 'записываем установленное значение
На первый взгляд, может не достаточно внимательный, сразу пришло в голову, что индикацию лучше привязать к таймеру. То есть независимую от основного цикла. В этом же прерывании (от таймера) отслеживать время нажатия кнопки и в нем же режим мигания. Потом обратил внимание на постоянную запись в энергонезависимую память. А циклов там всего 100000 по паспорту. Казалось бы много, но во время работы это будет происходить постоянно по срабатыванию датчиков. Посчитайте, с какой частотой будут срабатывать датчики и на сколько времени хватит надежной работы памяти. Потом никто не угадает, что будет записываться. Может лучше переписывать только изменение в литрах. 100 тонн бензина проездить, это надолго. Если эти предложения реализовать, будет другая программа с совсем другим алгоритмом.
На первый взгляд, может не достаточно внимательный, сразу пришло в голову, что индикацию лучше привязать к таймеру. То есть независимую от основного цикла. В этом же прерывании (от таймера) отслеживать время нажатия кнопки и в нем же режим мигания. Потом обратил внимание на постоянную запись в энергонезависимую память. А циклов там всего 100000 по паспорту. Казалось бы много, но во время работы это будет происходить постоянно по срабатыванию датчиков. Посчитайте, с какой частотой будут срабатывать датчики и на сколько времени хватит надежной работы памяти. Потом никто не угадает, что будет записываться. Может лучше переписывать только изменение в литрах. 100 тонн бензина проездить, это надолго. Если эти предложения реализовать, будет другая программа с совсем другим алгоритмом.
На счёт памяти- согласен. В идеале записывать только значения начальной установки и значения перед отключением питания. Только я не знаю пока, как это сделать. Да и на счёт таймера- тоже соглашусь. Только КАК это сделать не разберусь ни как. Примеров кода с похожим алгоритмом в Bascom, я не нашёл. А программы на Ассемблере или на Си- для меня, вообще, пока "тёмный лес"
Насчет памяти. Одну ногу привязать к зажиганию и по отключению зажигания записывать показания. Приблуду можно отправить в спящий режим, хотя её потребление при отключенных индикаторах меньше саморазряда аккумулятора. А индикаторы тушить то же по зажиганию. Теперь про таймер для динамической индикации. Не буду сейчас сочинять на ходу. Примеров навалом. Например. Число индикаторов увеличивается до нужного. Ну и массив для отображения сегментов приложен. В прерывании еще нужна будет переменная типа байт, которая постоянно увеличивается до 255 а затем снова с нуля. Пусть так и ходит по кругу. При нажатии кнопки эта переменная обнуляется, но таймер продолжает работать и увеличивать значение. В момент отпускания посмотреть значение переменной. Нажатие и отпускание можно посадить на прерывание. Или после нажатия ждать отпускания. Как угодно. В общем идея такова.
Насчет памяти. Одну ногу привязать к зажиганию и по отключению зажигания записывать показания. Приблуду можно отправить в спящий режим, хотя её потребление при отключенных индикаторах меньше саморазряда аккумулятора. А индикаторы тушить то же по зажиганию. Теперь про таймер для динамической индикации. Не буду сейчас сочинять на ходу. Примеров навалом. Например. Число индикаторов увеличивается до нужного. Ну и массив для отображения сегментов приложен. В прерывании еще нужна будет переменная типа байт, которая постоянно увеличивается до 255 а затем снова с нуля. Пусть так и ходит по кругу. При нажатии кнопки эта переменная обнуляется, но таймер продолжает работать и увеличивать значение. В момент отпускания посмотреть значение переменной. Нажатие и отпускание можно посадить на прерывание. Или после нажатия ждать отпускания. Как угодно. В общем идея такова.
Спасибо за пример. Буду думать-разбираться.
Добавлено after 2 minutes 51 second:
kip96 писал(а):
Интересно узнать, а чем обусловлена задача, только с одной кнопкой?
На мой, субъективный конечно, взгляд, так прикольнее! Ну если уж совсем получаться не будет, придётся ещё кнопок подкидывать.
kip96, мне попадались часы, которые настраивались одним сенсорным контактом. Как раз примерно так, как представляет LazarevSergey. Длинное нажатие - переход на параметр, короткое - его изменение. Неудобно, если постоянно что то менять нужно, а если раз в неделю, так вроде и пойдет.
kip96, мне попадались часы, которые настраивались одним сенсорным контактом. Как раз примерно так, как представляет LazarevSergey. Длинное нажатие - переход на параметр, короткое - его изменение. Неудобно, если постоянно что то менять нужно, а если раз в неделю, так вроде и пойдет.
А кода нет, случайно? Интересно было бы поглядеть, как люди эту задачу решают.
Добавлено after 10 minutes 4 seconds:
kip96 писал(а):
Мне кажется, энкодер с кнопкой (3 пина) пипец как облегчил бы задачу!
Возможно. Но в машине энкодер, а точнее его ручку, надо куда то колхозить. А вот встроить Led индикатор в приборную панель и вывести ОДНУ кнопку, да ещё фирменную, под стиль интерьера авто-куда более эстетично! Чем меньше бросающегся в глаза изменений интерьера- тем лучше (я так думаю)
Можно порекомендовать ещё сенсорную кнопку - TIP223. Работает отлично. Жменька стоит пять копеек. Можно установить не нарушая интерьер. Если с одной кнопкой то примерно так.
Код:
If Kn = 0 Then Time_ret_button = 0 ' переменная увеличивается по таймеру, к примеру каждую секунду While Kn = 0 ' пока удерживается кнопка If Time_ret_button = 5 Then ' если удерживаем пять секунд, то делаем что надо. К примеру увеличиваем переменную cont ' и обозначаем это как нибудь(к примеру звуком)
end if
wend select case cont case 1: ' моргаем первым индикатором и кнопкой меняем его case 2: ' моргаем вторым и кнопкой меняем его case 0: ' делаем основную работу
_________________ Все делают ошибки, только мудрецы - новые, а дураки - старые.
Уважаемые знатоки, а как на Баскоме можно сохранить в Eram переменную типа Bit ?
У меня в девайсе есть настройки, переменная Aaa типа bit принимает значение 0 или 1, больше не нужно, меняется Toggle. Dim aaa as bit - работает, а Dim bbb as eram bit - пишет, что только байт.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения