Jump to content

Recommended Posts

ну или более удобней через структуру

// описание переменых
union {       
struct {
  unsigned bit0  : 1;  
  unsigned bit1  : 1;
  unsigned bit2  : 1;
  unsigned bit3  : 1;
  unsigned bit4  : 1;  
  unsigned bit5  : 1;
  unsigned bit6 : 1;  
  unsigned bit7 : 1;   
} PIN;             
  unsigned char reg;       
} temp,tempOld; 

// применение
temp.reg=0;
if(PINB&(1<<0)) temp.PIN.bit0 =1;
if(PINC&(1<<2)) temp.PIN.bit1 =1;
if( !tempOld.PIN.bit0
     && temp.PIN.bit0
     && temp.PIN.bit1 ) PORTD |=(1<<0);
if( !temp.PIN.bit1
     && tempOld.PIN.bit1 ) PORTD &= ~(1<<0);
tempOld.reg=temp.reg;

 

Share this post


Link to post
Share on other sites
10 часов назад, IMXO сказал:

сдается мне это не правильно. условие выполняется при любом значении пинС

надо фиксировать фронт импульса пинВ и спад импульса пинС

я бы сделал так
 


temp_PIN=0;
if(PINB&(1<<0)) temp_PIN |=(1<<0);
if(PINC&(1<<2)) temp_PIN |=(1<<1);
if(!(tempOld_PIN&(1<<0))
     &&(temp_PIN&(1<<0))
     &&(temp_PIN&(1<<1))) PORTD |=(1<<0);
if(!(temp_PIN&(1<<1))
     &&(tempOld_PIN&(1<<1)) PORTD &= ~(1<<0);
tempOld_PIN=temp_PIN;

 

IMXO, Спасибо за очередную подсказку. Я далеко еще не все изучил в AVR поэтому прошу вас расшифруйте мне эту строчку  "tempOld_PIN&(1<<0)"

Я конечно это найду, но иногда хочется хоть что-нибудь сразу.:)

Share this post


Link to post
Share on other sites

Логическое И переменной с маской в которой установлен один бит(нулевой). В итоге останется только 0-й бит переменной, остальные сравняются с нулём.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

Драйверы MOSFET/IGBT Infineon – силой нужно управлять!

Специалисты Infineon усовершенствовали традиционные кремниевые MOSFET и IGBT и выпустили компоненты на базе принципиально иных материалов – нитрида галлия и карбида кремния. Мы создали подборку полезных материалов, чтобы вы разобрались во всех тонкостях и стали экспертом по управлению силовыми приборами нового поколения CoolMOS, CoolGaN, CoolSiC!

Подробнее

по факту вы пытаетесь реализовать обычный RS-триггер с приоритетом Reset,  только Reset у вас инверсный. PC2=!Reset, PB0=Set. те RS-триггер устанавливается по нарастающиму фронту, сбрасывается  по спадающему фронту.

zzxx.png.6bd650d7f8993afc61e43909fcf87cc1.png

А далее все просто. для фиксации фронтов нужно знать предыдущие состояние пина (переменная tempOld_PIN) , тк вы используете пины на разных порта ввода, то для работы текущие состояние пинов записываются в переменную temp_PIN, значение Set записываем в бит0 , Reset в бит1.

temp_PIN=0;
if(PINB&(1<<0)) temp_PIN |=(1<<0);
if(PINC&(1<<2)) temp_PIN |=(1<<1);

проверяем условие установки: нарастающий фронт на Set и высокий уровень на Reset , если выполняется устанавливаем выход

if(!(tempOld_PIN&(1<<0)) // нарастающий фронт: предыдущий Set=0,
     &&(temp_PIN&(1<<0)) // текущий Set=1.
     &&(temp_PIN&(1<<1)))// + текущий Reset=1.
  PORTD |=(1<<0);

проверяем условие сброса: спадающий фронт на Reset

if(!(temp_PIN&(1<<1)) // спадающий фронт: текущий Reset=0
     &&(tempOld_PIN&(1<<1)) // предыдущий Reset=1
   PORTD &= ~(1<<0);

сохраняем текущие значение пинов

tempOld_PIN=temp_PIN;

 

Share this post


Link to post
Share on other sites

Снижена цена на DC/DC и AC/DC преобразователи Mornsun в Компэл!

Компэл снизил цены на всю продукцию Mornsun. В ассортименте – как широко известные и популярные позиции, так и новинки. Доступны AC/DC, неизолированные DC/DC-преобразователи или импульсные стабилизаторы (семейство K78/R3), изолированные DC/DC, и новейшее поколение R4.

Подробнее

      IMXO. Большое спасибо за помощь. Фактически я закончил программу для задуманного устройства. Пока она в виде отдельных блоков, объединить их в одно целое, не составит проблем (надеюсь). Изучать программирование AVR не собираюсь бросать (было такое желание), вошел во вкус. Читая ваш пост, вспомнилось приятное чувство, когда попался отличный перевод  руководства по программированию одного ПЛК. (Сам использую CodeSys, но на фирменном оборудование часто используется СИ)

P.S. В ин-нете много информации для начинающих , начинается с морганием светодиодом, потом сразу подключение LCD .:o Есть информация по таймерам, АЦП (на троечку, но есть), а вот по ДИСКРЕТНОЙ ЛОГИКЕ почти ни чего не нашел, а ведь как оказалось здесь столько нюансов, которые надо не только понять, а просто тупо запомнить.

P.P.S. Теперь дело за программатором.

Share this post


Link to post
Share on other sites

Новинки гибридных конденсаторов: преимущества технологии

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

Подробнее

Просто сама логика это как ССР(само-собой-разумеется) является базой для изучения контроллеров, раз забрался на такой уровень то уж логику должен понимать. Просто надо знать одну вещь - контроллер в отличие от ПЛИС все операции делает последовательно, поэтому любую сложную логику надо разворачивать на последовательные шаги.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

Есть код  такого плана:

while (1){		
			
	if (TIFR & (1 << TOV0)){	// if timer overflow
		run_timer4us();
		ON;			
		OFF;
		resetTOV0;			// reset overflow flag
	}			
	
	if (GIFR & (1 << INTF0)){	// if pin level change
		run_timer6us();
		ON;			
		OFF;			
		ON;			
		OFF;
		resetINTF0;	// reset INTF0 interrupt
	}		
			
}

 

Т.е. в бесконечном цикле идёт опрос двух флагов. Первый - на переполнение таймера, второй - на смену лог. уровня пина PD2. Контроллер ATtiny 2313A. 
Всё вроде бы не плохо, если бы не одно но. В логике цикла заложена такая штука, что если произошла смена лог. уровня - таймер взводится на 6 мкс (чтобы попасть на середину следующего бита в передаче), а если смены за 4 или 6 мкс не наблюдалось - значит мы как раз на середине принимаемого бита. Но иногда переполнение с 4 мкс наступает раньше, чем должно, а событие по смене уровня отрабатывается потом.

Никаких прерываний не используется, ON, OFF - макросы для своего рода дебага в железе типа PORT_LED |= (1 << LED_PIN). run_timerXus() - inline функции с одной строкой TCNT0 = fUs4, где fUs4 - константа, ресеты тоже макросы типа resetTOV0    TIFR &= (1 << TOV0).

Картина того, что иногда идёт не так:

IMG_20180305_013021.thumb.jpg.902aa51ae4bff77fcd6785b50db57072.jpg

Сверху - принимаемый сигнал - внизу - результат работы команд ON/OFF в условиях. Тут видно, что вторая смена уровня отрабатывается позже, чем переполнение таймера в 4 мкс, хотя измеритель показывает, что прошло как раз 6 мкс. 

А вот как оно должно быть по задумке:

IMG_20180305_015605.thumb.jpg.daf81d29a0537b63f4c431dc47b60a3e.jpg

То есть отрабатывается смена логического уровня и через 6 мкс уже срабатывает переполнение. Но даже это время отклика меня несколько смущает. Сам уровень вроде давно поменялся, а условие только где-то через микросекунду а то и больше срабатывает. Есть вероятность, что фронты/спады недостаточно крутые, пока нечем посмотреть, но это не критично. Критична именно ситуация на первом фото. Как такое вообще может произойти?

P.S. Прерывания не использую, потому что с ними вообще не успеваю, период 4 мкс, кварц 24 (!) МГц стоит, (на 20 под рукой не было), константы есть под оба варианта, но это уже другая история :) 

Share this post


Link to post
Share on other sites
11 минуту назад, Tokes сказал:

Но даже это время отклика меня несколько смущает. Сам уровень вроде давно поменялся, а условие только где-то через микросекунду а то и больше срабатывает.

1. смотрим в ДШ время установки флага.

2. смотрим асм и считаем сколько команд выполняется и сколько на это уходит времени.

Share this post


Link to post
Share on other sites
while (1){		
			
	//if (TIFR & (1 << TOV0)){	// if timer overflow
	//	run_timer4us();
	//	ON;			
	//	OFF;
	//	resetTOV0;			// reset overflow flag
	//}			
	
	if (GIFR & (1 << INTF0)){	// if pin level change
	//	run_timer6us();
		ON;			
		OFF;			
		ON;			
		OFF;
		resetINTF0;	// reset INTF0 interrupt
	}		
			
}

Я думаю так можно проверить, как затянут задний фронт входного сигнала

Можно сигнал сделать длинней и задержки 4 ms  и 6 ms и не надо будет сомневаться успевает контроллер или нет

Share this post


Link to post
Share on other sites
Только что, snn_krs сказал:

и задержки 4 ms  и 6 ms и не надо будет сомневаться успевает контроллер или нет

тут точно, без сомнений - не успеет :D

Share this post


Link to post
Share on other sites

@IMXO , посмотрел. В даташите это время, если я всё верно понял равно четырём тактам осциллятора:
5a9d06dfaafdb_1.PNG.cf10b16f7cf87e56ae0b0c322bb622fb.PNG

В дизассемблере проход по этим двум командам ветвления плюс переход на начала цикла занимает 6 инструкций, некоторые по два такта за инструкцию Пусть будет 10. Итого, по идее, максимум должно быть в самой плохой ситуации 10+4+10 - 24 такта. При тактовой в 24Мгц это 1 мкс. А у меня как будто всё в самом худшем случае, а то и ещё хуже, как в Беларуси )
@Геннадий , а если сюда ещё прерывания добавить, пока перейдёт на старт ПП прерывания, пока всё это сохранит/вытащит из стека, потом возврат...  - это будет точно дольше, чем такая конструкция в данной ситуации. Хотя я уже ни в чём не уверен :wacko:

Ладно, а кто-нибудь видит способ выйти из ситуации победителем?

Share this post


Link to post
Share on other sites

оставлять только флаг ИНТ , задержку делать НОРами

Share this post


Link to post
Share on other sites
31 минуту назад, Tokes сказал:

Пусть будет 10. Итого, по идее, максимум должно быть в самой плохой ситуации 10+4+10 - 24 такта. При тактовой в 24Мгц это 1 мкс

вы сюда еще забыли впихнуть время на переустановку таймера, как в АВР не знаю а в ПИКах таймер валиден только через машинный цикл те время переустановки  8 тактов осциллятора думеецо в АВР не меньше. те выполняя  run_timer6us(); проверка if (TIFR & (1 << TOV0)) идет на 7-8 такте...

Share this post


Link to post
Share on other sites

@IMXO , про задержку NOPами подумаю, спасибо за идею. Но на дешёвых AVR я, похоже, упёрся в потолок. Давно смотрю на STM32, но как подумаю, сколько там всего...

Share this post


Link to post
Share on other sites

то же самое там все, только быстрее и в бОльшем ассортименте. А смысл программирования тот же самый - пока не нужно, не трогай лишнего. Натроил тактирование, включил нужный модуль, подав на него такты, и погнали. Так что бояться там особо нечего. Если есть практика на 8-битках то осваивается влет. Потом уже альтернативы просто перестают существовать за те деньги и с теми возможностями при прочих равных.

Представь так сразу с велосипеда ты пересел в феррари, да еще и сэкономил. Ясно дело ощущения совсем другие будут )

Edited by mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites

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

Edited by GOR23

Share this post


Link to post
Share on other sites
5 часов назад, Tokes сказал:

Ладно, а кто-нибудь видит способ выйти из ситуации победителем?

waitHigh:
while (1){		
	if (TIFR & (1 << TOV0)){	// if timer overflow
		run_timer4us();
		ON;			
		OFF;
		resetTOV0;			// reset overflow flag
	}			
	if (PIND & (1 << 2)){	// if pin level go to high
		run_timer6us();
		ON;			
		OFF;			
		ON;			
		OFF;
		resetINTF0;	// reset INTF0 interrupt
		goto waitLow;
	}		
}

waitLow:
while (1){		
	if (TIFR & (1 << TOV0)){	// if timer overflow
		run_timer4us();
		ON;			
		OFF;
		resetTOV0;			// reset overflow flag
	}			
	if (!(PIND & (1 << 2))){	// if pin level go to zero
		run_timer6us();
		ON;			
		OFF;			
		ON;			
		OFF;
		resetINTF0;	// reset INTF0 interrupt
		goto waitHigh;
	}		
}

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

Других проблем действительно не видно!

15 часов назад, Tokes сказал:

TIFR &= (1 << TOV0)

а тут опечатка на сайте, наверно? он вроде единицей сбрасывается, так должно быть:

TIFR |= (1 << TOV0);

?

 


Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


Link to post
Share on other sites
19 минут назад, GOR23 сказал:

диммер на мк.

смотря для чего, для освещения линейно.  глаз имеет логарифмическую зависимость нарастания яркости , синус дает линейность. или нет?

Share this post


Link to post
Share on other sites
6 часов назад, Tokes сказал:

посмотрел. В даташите это время, если я всё верно понял равно четырём тактам осциллятора

а этот регистр у тебя задан:

7.6.3. Clock Prescaler Register
Name: CLKPSR

Bits 3:0 – CLKPS[3:0]: Clock Prescaler Select

Сколько?


Можно сделать все! Но чем больше можно, тем больше нельзя!

Share this post


Link to post
Share on other sites
2 часа назад, GOR23 сказал:

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

Конечно. Предварительно посчитанные табличные значения. Что может быть быстрее выбора значения по таблице? Но... обчно линейной регулировки достаточно.


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites

@ruhi , интересный вариант тоже, обдумаю. По поводу опечатки - у меня всё верно. Читаем внимательно: определённый флаг сбрасывается записью единицы в соответствующий бит соответствующего регистра - это по документации. Представьте ситуацию, где в регистре, например, TIFR установлено несколько флагов. А мы берём эти несколько флагов, проводим с ними операцию ИЛИ и записываем все эти флаги вместе с установленным в этот же регистр. Что произойдёт в итоге? Правильно - вместо какого-то конкретного мы сбросим все установленные флаги, которые были установлены в единицу на момент операции ИЛИ.
Дальше, Clock Prescale Register - я так понял позволяет на ходу подключать прескалер к тактовому генератору? Я даже не знал, что в этом МК такое можно :) Не пользовался этим регистром, поэтому, подозреваю, этот прескалер отключён. Иначе бы я не получал точных временных выдержек.

@mail_robot , я тут почитал. Хочу себе феррари :) Есть у меня в запасах платка, типа для ардуино, там F103 серия. Скачал референс мануал, а так же даташит на эту серию. Сходу разобраться не получилось. Там указана максимальная тактовая в 72 МГц, так же где-то читал недавно, что порты IO не могут на такой частоте работать. Это так? Ну и другой вопрос - я эту платку смогу использовать где-то кроме как в среде ардуино, которую я так не перевариваю?

Share this post


Link to post
Share on other sites

Именно так, там ядро работает на одной частоте(до 72Мгц) а периферия, причем разная, может работать от других частот - это настраивается соответствующими прескалерами, и по умолчанию всё отключено. В настройке периферии и заключается сожность работы с контроллером, под настройки периферии целые шаблонизаторы кода делают.

 


Учение - изучение правил. Опыт - изучение исключений.

Share this post


Link to post
Share on other sites
5 hours ago, Tokes said:

Там указана максимальная тактовая в 72 МГц, так же где-то читал недавно, что порты IO не могут на такой частоте работать. Это так?

порты на частоте ядра априори не могут работать. Но вопрос в другом - а так ли это необходимо? Принцип обработки сигналов в СТМ отличается от обычного парсинга. Там все строится на модулях, а до ядра доходит уже в переработанном виде (в основном)

5 hours ago, Tokes said:

я эту платку смогу использовать где-то кроме как в среде ардуино, которую я так не перевариваю?

я конечно понимаю, что меня опять закидают тапками - типа говно и все такое. Но мне как то пофик. Попробуй CubeMX в связке с Keil. Кодить можно попробовать на HAL. Это будет чтото типа Java, если сравнивать с голым регистровым кодом. Просто, быстро и оно работает. Есть гениальные индивиды, которые говорят что это то же самое что и ардуино, но это далеко не так. Это нормальная библиотека абстрагированного кода на С, которая кстати предлагается самим производителем камней как основной и желательный инструмент. Единственный официально поддерживаемый на сегодняшний день. Но у нас тут есть люди, которые считают себя умнее всех инженеров и программистов ST, поэтому лучше выбирай сам. Вариант ассемблера кстати тоже не исключен

если смотреть на бонусы, которые получаешь от HAL, то это будет хорошая читабельность кода, портируемость, удобство сопровождения ну и высокая скорость разработки.

Из минусов - потеря производительности (порядка 1-5%), более массивный бинарник на выходе. Tсли ты не готов отдать 5 лишних килобайт из 32-х (обычно) и 4 мегагерца из 72-х (допустим) за утроенную скорость написания кода, то это не твой инструмент и лучше юзать например SPL. Месяц на колупание кода и у тебя отличный софт, который правда недели через две ты сам будешь читать как китайские иероглифы. Но это не страшно, говорят привыкаешь быстро. Годик другой кодинга в режиме полной занятости и все будет на автомате )

Edited by mail_robot

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

Share this post


Link to post
Share on other sites
20 часов назад, Tokes сказал:

...а если сюда ещё прерывания добавить...

Не добавить, а заменить "это сюда" на прерывания.

19 часов назад, mail_robot сказал:

...да еще и сэкономил.

Как-то сомнительно. Продаваны следят за спросом. Сейчас тот же STM32f103C8T6 уже обгоняет в стоимости Atmega328p.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения


  • Электромагнит напряжением 5-24В

  • Similar Content

    • Guest Влад
      By Guest Влад
      в этой схеме необходимо заменить микроконтроллер PIC на микроконтроллер AtMega8
    • By Александр Шилин
      Помогите, пожалуйста, со схемой подключения ПЗС-линейки к микроконтроллеру. Задача заключается в том, чтобы определить координату падения светового пятна, сформированного линзой, в пределах линейки.
      Модель линейки TCD132D на 1024 пикселя.
      Согласно даташиту необходимо три управляющих частоты - M, CCD, SH, питающее напряжение 12 В и опорное 5 В. Все эти условия были выполнены. Данные считываются.
      Выход данных с линейки пока просто выведен на осциллограф (красный канал). 
      Я плохо понимаю физические основы работы ПЗС-линейки, но ее работа кажется мне очень странной и нелогичной.
      1) При равномерной фоновой засветке при считывании получается равномерное низкое напряжение на всех пикселях. (Рисунок 1).
      2) При закрытии части линейки чем-либо напряжение на закрытых пикселях возрастает (Рисунок 2).
      3) При включении фонарика или лазерной указки все пиксели зашкаливают, определить максимум не удается (Рисунок 3).
      Если поместить линейку в темное место и светить очень тусклым лазером, то общий уровень напряжения на пикселях высокий, а в месте попадания света наблюдается едва заметный минимум. Возможно так и должно быть и нужно просто инвертировать и усилить сигнал?
      В чем может заключаться проблема? Как грамотно снимать выходной сигнал с линейки и заводить его на АЦП МК?
      Даташит приложен снизу.




      tcd132d.pdf
    • By Alan247
      Представляю на ваш суд:    https://thisismyhobby.ru/AVR_PAL_W.php   Ваше мнение?
       

    • By Rad TV
      Скетч простой и кислий. Сделан автором RadTV канал:https://www.youtube.com/channel/UC1k5elIKErFnmwTzIsRgQrA?view_as=subscriber
      Буду рад рокомендациях и помощи!Сделал сам проект должен бить простим и  что би влезло в ATtini85!
      Есть защита акб и просто парения (!!!Кнопка на розмикания!!!)
      Обновления будут!!!!
       
       
      RadMOD ver1.0.txt
    • By Стас73
      Доброй ночи, уважаемые.
      Прошу Вашего совета по следующей куче проблем для меня, т.к. не соображаю в электронике, схемах, резисторах и подобному, но дружу с компом и есть желание сделать определенный механизм, но пока нет наставления на путь истинный от специалистов)
      Задача состоит в следующем - хочу мотор стеклоочистителя подключить к Ардуино, но управлять им необходимо с кнопки. Шилд, например, который обрабатывает сигнал нажатия на кнопку (допустим кнопка записи), при ее активации, нажимаю на другую кнопку, которая дает команду движку вращаться по часовой стрелке. Отпускают ее, моторчик останавливается. Другая кнопка, вращение в противоположную сторону. Т.е. записал последовательность и продолжительность вращений,  нажимаю вновь на кнопку запись и мои действия сохраняются. Далее на 4 кнопку жму и моя игра с моторчиком автоматически воспроизводится. Если такое выполнимо с помощью плат и шилдов без доп программирования логики, то буду ОЧЕНЬ  признателен если расскажете как вкратце это осуществить или кинете ссылки к примеру на Али с нужными товарами. Если легковыполнимо, то в будущем наверное уже разберусь,  как обойтись без нажатия на 4 кнопку (воспроизведения записанных действий) и запускать этот процесс, подключив датчик движения или звука.
      Если необходимо описывать логику или создавать типа какого-то протокола, что шилд (?) умел понимать, что я от него хочу, то подскажите среду разработки для неба, что б там по минимуму было наворотов) В принципе с основами c++ для Ардуино скорее всего придется ознакомиться. 
      Заранее спасибо!
×
×
  • Create New...