Перейти к содержанию

С нуля Программирование AVR Купил программатор и Контроллер Что дальше...


Рекомендуемые сообщения

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

if((!(PINB&0b00000001))&&(T>=(ton0+d0)))//если нажат "+" и есть возможность расширения импульса
if((!(PINB&0b00000010))&&(0<=(ton0-d0)))//если нажат "-" и есть возможность сужения импульса
if((!(PINB&0b00000100))&&(T>=(ton1+d1)))//если нажат "+" и есть возможность расширения импульса
if((!(PINB&0b00001000))&&(0<=(ton1-d1)))//если нажат "-" и есть возможность сужения импульса

учитывая скорость работы микроконтроллера вам потребуется задержка после T--;//считаем период

Вы с помощью цикла while(T>0)//период хотите получить более точное выдерживание параметров ШИМ? У вас это не получиться, т.к. после окончания обработки одного периода ШИМ вы уходите на обработку кнопок. И время которое у вас ушло на обработку кнопок добавляется в конец времени периода ШИМ (отключенное состояние всех выходов). Таким образом период у вас начинает плавать (когда вы нажимаете на кнопки). Вы выдерживаете длительность импульса, а период плавает и без задержки, которую я вам указал достаточно сильно. Наверно всё работать будет, но при нажатии на кнопки работать будет не стабильно.

 

 

 

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

В 08.03.2017 в 13:39, COKPOWEHEU сказал:

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

uint8_t temp; //заводите временную переменную
temp = count; //копируете в нее счетчик
temp &= 0b00001111; //зануляете старшие биты
if( temp == 0 ){...} //потом пишете проверку того что получилось на равенство нулю
...
if( !(count & 0b00001111) ){...} //если сработает - оптимизируйте до одной строчки

 

9 часов назад, pliss сказал:

смотрите, один вариант с указанием VOLATILE, другой - без указания. Больше ничего не менялось. Как так?

Доступ к volatile переменным гораздо дольше чем к расположенным в регистрах. Возможно, дело в этом. Вы же почитали что-то по этому модификатору, а не лепите от балды.

8 часов назад, pliss сказал:

Вовсе нет. И, скорее всего, окончательный вариант будет именно на таймере...

Ознакомьтесь с принципом формирования ШИМ на аппаратном таймере чтобы потом реализовать программно. Вкратце, заводите глобальный счетчик времени и на каждой итерации увеличиваете. При равенстве этой переменной заданному заполнению канала, выставляете соответствующий вывод в 1, при достижении максимума - в 0. Получится инверсный ШИМ (переменная канала соответствует длительности низкого уровня). Изменить на неинверсный несложно. Для точности менять значение счетчика можно по таймеру либо даже добавить в цикл фиксированную задержку (_delay_us). Проверка кнопок там же, в бесконечном цикле.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

12 часа назад, pliss сказал:

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

А может не месяц. Может - год. И весь год опрашивать? Это же не клавиатура для скоростного набора текста...

Вы неправильно рассуждаете. Микроконтроллеру ни тепло ни холодно независимо от того, какую программу вы зальете. Задача микроконтроллера отрабатывать любой код.

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

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Вообще начинать программировать контроллеры надо с ассемблера. На С слишком много всяких заморочек, внешне выглядящих как настоящая МАГИЯ, и научится программировать контроллеры будет очень сложно, потому что там важен точный учет каждого ньюанса. Если бы у вас был уже написан HAL для контроллера и/или минимальная ОСРВ, тогда можно было бы сразу начинать писать на С.

И не поверите, ДА устройства с клавиатурами бывает годами ждут когда нажмут кнопку и постоянно их опрашивают. Даже тот же пульт от телека - прерывание в нем используется только чтобы "проснуться" и просканировать клавиатуру, если бы не необходимость экономить заряд батарей опрос был бы постоянным.

Да та же микроволновка, годами сканирует клавиатуру бесконечно в ожидании нажатия. А всё почему? При отсутствии требований к экономии энергии нерационально кнопки опрашивать по прерыванию. Микроконтроллер это не человек, он не сходит с ума от нудной работы и не устаёт - ему что секунду кнопки опрашивать что годами один фиг.

 

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

Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, Alexeyslav сказал:

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

 

Я когда-то писал на асме и был ярым его поклонником. Когда перешел на си, я понял, о чем говорили мне "старшие". Поэтому, сейчас мое мнение. Изучать си. Систему команд изучить в достаточной мере, чтобы понимать, что накомпилировал компилятор.

Ссылка на комментарий
Поделиться на другие сайты

Я тоже начинал с Асма, сейчас пишу на Си. Но все равно считаю что не зря потратил время. Появляется интуитивное понимание каких конструкций следует по возможности избегать, понимание что натворил компилятор и как убедить его сделать нормально, возможность делать ассемблерные вставки (в отдельных случаях это может на порядок ускорить код).

А учить Си лучше с компьютерного. Ознакомиться с синтаксисом и основными конструкциями. Не пугаться ручной реализации чего-то, умение ориентироваться в сторонних библиотеках, написание программ с несколькими файлами исходного кода.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

10 часов назад, dm37 сказал:

<...>вы всегда опрашиваете кнопки даже 4 раза (я вам предлагал один раз считать состояние кнопок в переменную, потом обрабатывать)<...

Ну да, конечно... Опять туплю.)

Это мне, вдруг, не нравилось то, что по совету коллеги @Alexeyslav, программа через каждые сколько-то циклов, без разрешения заходила проверять мои кнопки, а после обнаружения нажатия - опять начинала считать перед тем как исполнить то, что должно быть в результате нажатия... Ну, эт я у него самого попробую уточнить. Я переписал код так, чтобы отсчёт "антидребезга" начинался после нажатия на кнопку.

Ну, и решил, что никакого циклического опроса у меня не стало.)))

Бесовское это дело - контроллеры программировать.

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

11 час назад, dm37 сказал:

Вы с помощью цикла while(T>0)//период хотите получить более точное выдерживание параметров ШИМ? У вас это не получиться

Нет, такой задачи пока не было.

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

Но это пока не принципиально...

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

11 час назад, COKPOWEHEU сказал:

Доступ к volatile переменным гораздо дольше чем к расположенным в регистрах. Возможно, дело в этом. Вы же почитали что-то по этому модификатору, а не лепите от балды.

Конечно прочитал.

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

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

Так считывание кнопок реже чем длится дребезг ГАРАНТИРУЕТ что дребезг не повлияет на программу. Максимум что может произойти - это нажатие будет зарегистрировано в следующем цикле. Поэтому при таком подходе не нужно организовывать дополнительный антидребезг - он просто не нужен.

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

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

Ссылка на комментарий
Поделиться на другие сайты

23 минуты назад, Alexeyslav сказал:

Так считывание кнопок реже чем длится дребезг ГАРАНТИРУЕТ что дребезг не повлияет на программу. Максимум что может произойти - это нажатие будет зарегистрировано в следующем цикле. <...>

Я делал как вы сказали, но именно регистрация "в следующем цикле" мне не очень понравилась... Но это конечно, в протеусе. Может в железе это будет не заметно. Ещё не понравилось, но это из той же оперы, имхо, что время между моментом нажатия и приращением переменной сильно разное бывает.

 

12 часа назад, COKPOWEHEU сказал:

Ознакомьтесь с принципом формирования ШИМ на аппаратном таймере чтобы потом реализовать программно. Вкратце, заводите глобальный счетчик времени и на каждой итерации увеличиваете. При равенстве этой переменной заданному заполнению канала, выставляете соответствующий вывод в 1, при достижении максимума - в 0.

Да запускал я на таймере колебания. Несколько страниц назад... Нормально.

Но обработка нажатия кнопок получилась какая-то лохматая - сейчас пытаюсь совладать не столько с самими импульсами, сколько с обработкой кнопок...

12 часа назад, COKPOWEHEU сказал:

менять значение счетчика можно по таймеру либо даже добавить в цикл фиксированную задержку (_delay_us).

И на библиотеке делал задержку для антидребезга. Был подвергнут жесточайшей обструкции.

3 часа назад, COKPOWEHEU сказал:

А учить Си лучше с компьютерного. Ознакомиться с синтаксисом и основными конструкциями.

И так я тоже делал. Мне было указано, что не "нужные книжки я в детстве читал".©

Я стал читать о приложении С к микроконтроллерам - опять не так!))))

Изменено пользователем pliss

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, pliss сказал:

Бесовское это дело - контроллеры программировать.

Вот корень проблемы и главный ответ. Отписываюсь от темы. Не в коня корм. Хотите, тратьте на этого персонажа свое время. Религия и точные науки несовместимы.

Ссылка на комментарий
Поделиться на другие сайты

Цитата

регистрация "в следующем цикле" мне не очень понравилась...

Т.е. вы уже научились реагировать со скоростью милисекунд? Следующий цикл наступает через 16 миллисекунд, человеческая реакция - от 100мс и больше. Чёрт побери... где ваша логика?

Цитата

время между моментом нажатия и приращением переменной сильно разное бывает

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

Цитата

учить Си лучше с компьютерного. Ознакомиться с синтаксисом и основными конструкциями.

Лучше, потому что отладчик толковый, всегда можно посмотреть как работает программа изнутри, и не надо каждую итерацию начинать с прошивки контроллера обновлённой прошивкой или запускать протеус - сделал изменения, пара секунд компиляции одна милисекунда выполнения и результат готов. Но это только даст навык написания программы, причем его надо отработать до автоматизма чтобы как воздухом дышать, чтобы не лазить в справку по компилятору как правильно использовать ту или иную конструкцию на каждом шагу.
И вот потом уже начинается чисто контроллерная специфика - периферия, регистры... честно говоря это всё чуждо ЯВУ но другого выхода нет. Как альтернатива - брать библиотеку которая реализует HAL или же ОСРВ но... это ещё одно болото без дна - тонуть можно годами наступая на грабли.

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

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

Ссылка на комментарий
Поделиться на другие сайты

4 минуты назад, Alexeyslav сказал:

Т.е. вы уже научились реагировать со скоростью милисекунд? Следующий цикл наступает через 16 миллисекунд, человеческая реакция - от 100мс и больше. Чёрт побери... где ваша логика?

Я - нет. Протеус - давно умеет. Я же уточнил, что, возможно в железе будет совершенно нормально...

7 минут назад, Alexeyslav сказал:

как только нажатие зарегестрировано и определена кнопка счёт до приращения переменной идёт на микросекунды.

Может, я не правильно вас понял.

Вернулся к вашему варианту опроса через "Х" циклов:

Скрытый текст

/*
 * PVM_ATmega16.c
 увеличение и уменьшение заполнения ШИМ нажатием кнопок
 */ 
#define F_CPU 4000000UL
#include  <avr/io.h>

int main()

{	

DDRB=0x00;//кнопки
PORTB=0xFF;//кнопки с резисторами

DDRD=0xFF;//выход шим
PORTD=0x00;//выход шим низкий

DDRC=0xFF;//контроль
PORTC=0x00;//контроль низкий

volatile int  ton0=0, ton0_=ton0, d0=11;//время PORTD0_on, дубль PORTD0_on и приращение
volatile int  ton1=0, ton1_=ton1, d1=11;//время PORTD1_on, дубль PORTD1_on и приращение
volatile int  T=110, T_=T;//период и дубль
unsigned char  n=0, n0=0, r=0;//общий и инд счётчик, и разрешение изменения

while(1)

{

//  ************************************ проверка кнопок *********************************************** //

n++;//инкр общий счётчик

if(!(n&0b00000111))//если у общего счётчика три мл разряда ==0

	{
			
//  ************************************* кнопки канала PORTD0 ********************************************  //													

									// **** кнопка "+" *** //
										
if((!(PINB&0b00000001))&&(T>=(ton0+d0)))//если нажат "+" и есть возможность расширения импульса

{
	n0++;//увеличиваем инд счётчик										     

	if((!(n0&0b00000111))&&(!(PINB&0b00000001))&&(!r))//если нажат "+" и у инд счётчика три мл разряда ==0 и разрешено приращение

	{		
		ton0=ton0+d0;//увеличиваем время PORTD0_on
		ton0_=ton0;//обновляем дубль
		r=1;//запрещаем изменения
	}
	
}
	
									// **** кнопка "-" *** //
									
if((!(PINB&0b00000010))&&(0<=(ton0-d0)))//если нажат "-" и есть возможность сужения импульса

{
	n0++;//увеличиваем инд счётчик

	if((!(n0&0b00000111))&&(!(PINB&0b00000010))&&(!r))//если нажат "-" и у инд счётчика три мл разряда ==0 и разрешено приращение

	{
		ton0=ton0-d0;//уменьшаем время PORTD0_on
		ton0_=ton0;//обновляем дубль
		r=1;//запрещаем изменения
	}	
}

							
//  ************************************* кнопки канала PORTD1 ********************************************  //

										// **** кнопка "+" *** //

if((!(PINB&0b00000100))&&(T>=(ton1+d1)))//если нажат "+" и есть возможность расширения импульса

{
	n0++;//увеличиваем инд счётчик

	if((!(n0&0b00000111))&&(!(PINB&0b00000100))&&(!r))//если нажат "+" и у инд счётчика три мл разряда ==0 и если разрешено изменение

	{
		ton1=ton1+d1;//увеличиваем время PORTD1_on
		ton1_=ton1;//обновляем дубль
		r=1;//запрещаем изменения
	}	
}
										// **** кнопка "-" *** //

if((!(PINB&0b00001000))&&(0<=(ton1-d1)))//если нажат "-" и есть возможность сужения импульса

{	
	n0++;//увеличиваем инд счётчик

	if((!(n0&0b00000111))&&(!(PINB&0b00001000))&&(!r))//если нажат "-" и у инд счётчика три мл разряда ==0 и разрешено приращение

	{
		ton1=ton1-d1;//уменьшаем время PORTD1_on
		ton1_=ton1;//обновляем дубль
		r=1;//запрещаем изменения
	}	
}


}

// *********************************************** ШИМ ********************************************  //


PORTD=0xFF;//включаем всё
		
while(T>0)//период

{						
	if(ton0>0)ton0--;//считаем время PORTD0_on
	else PORTD&=0b11111110;//выключаем PORTD0_on
	
	
	if(ton1>0)ton1--;//считаем время PORTD1_on
	else PORTD&=0b11111101;//выключаем PORTD1_on
			
	T--;//считаем период				
}
		
T=T_;//восстанавливаем период
	
ton0=ton0_;//обновляем или восстанавливаем время PORTD0_on
ton1=ton1_;//обновляем или восстанавливаем время PORTD1_on
		
if(PINB==0b11111111)r=0;//если кнопки отпущены разрешаем изменение

}
}

 

Считаем "n" до 0bxxxx x000 (это первичный, общий счётчик) - проверяем кнопки.

Если кнопка нажата - считаем "n0" до 0bxxxx x111 (это вторичный, счётчик) - выполняем действие.

У меня вторичный счётчик инкрементируется каждые 8*8 раз при нажатой кнопке...

То есть, нажатие может быть зафиксировано, самое позднее - через 8 периодов, а выполнено через 64 периода...

Если вы говорите, что после определения нажатия - микросекунды, то я не правильно завёл вторичный счётчик...

 

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

Второй счетчик это автоповтор. И работает он только когда кнопка нажата. А действие по кнопке можно производить как непосредственно по нажатию так и при автоповторе. Если автоповтор не нужен, то убираем второй счетчик и жмём кнопку сотню раз чтобы перейти от нуля к максимуму. Если изменять значение крупными шагами, то это означает что разрядность ШИМ избыточна изначально и можно её сделать меньше.

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

Ссылка на комментарий
Поделиться на другие сайты

47 минут назад, Alexeyslav сказал:

Второй счетчик это автоповтор. <...>

Ну вот. Умеете вы рассторить. Я так долго с автоповтором боролся...

То есть, если я просто уберу вторичный счётчик, то автоповтор станет очень быстрым?...

Переменную "r" придумал. Эх...

Мне автоповтор пока не нужен. С величиной приращения можно или за две-три перепрошивки определиться или - если получится совладать с eeprom, то его, как и начальную скважность можно сделать настраиваемыми... Пошёл накапливать вопросы.

47 минут назад, Alexeyslav сказал:

Если изменять значение крупными шагами, то это означает что разрядность ШИМ избыточна изначально и можно её сделать меньше.

Я правильно понимаю - если пользоваться таймером, то максимальная разрядность шим это максимальная разрядность таймера, если пользоваться программным - это количество тактов в периоде шим.

Если у меня период состоит из T=110 тактов, то у меня 110 - разрядный шим?..

Изменено пользователем pliss

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

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

Скрытый текст

/*
 * PVM_ATmega16.c
 увеличение и уменьшение заполнения ШИМ нажатием кнопок
 */ 
#define F_CPU 4000000UL
#include  <avr/io.h>

int main()

{	

DDRB=0x00;//кнопки
PORTB=0xFF;//кнопки с резисторами

DDRD=0xFF;//выход шим
PORTD=0x00;//выход шим низкий

DDRC=0xFF;//контроль
PORTC=0x00;//контроль низкий

int  port_state=PINB;

int  ton0=0, ton0_=ton0, d0=13;//время PORTD0_on, дубль PORTD0_on и приращение
int  ton1=0, ton1_=ton1, d1=13;//время PORTD1_on, дубль PORTD1_on и приращение

int  T=260, T_=T;//период и дубль

unsigned char  n=0, r=0;//счётчик периодического опроса кнопок, разрешение изменения

while(1)//основной цикл

{
//  ************************************ опрос кнопок *********************************************** //

n++;//инкр счётчик периодического опроса кнопок

if(!(n&0b00000111))//если у счётчика периодического опроса кнопок три младших разряда ==0

{
	port_state=PINB;//запоминаем состояние порта B
			
//  ************************************* кнопки канала PORTD0 ********************************************  //													

									// **** кнопка "+" *** //
										
if((!(port_state&0b00000001))&&(T>=(ton0+d0))&&(!r))//если нажат "+" и есть возможность расширения импульса и разрешено изменение

{										     
	ton0=ton0+d0;//увеличиваем время PORTD0_on
	ton0_=ton0;//обновляем дубль
	r=1;//запрещаем изменения	
}
									// **** кнопка "-" *** //
									
if((!(port_state&0b00000010))&&(0<=(ton0-d0))&&(!r))//если нажат "-" и есть возможность расширения импульса и разрешено изменение

{
	ton0=ton0-d0;//уменьшаем время PORTD0_on
	ton0_=ton0;//обновляем дубль
	r=1;//запрещаем изменения
}
							
//  ************************************* кнопки канала PORTD1 ********************************************  //

										// **** кнопка "+" *** //

if((!(port_state&0b00000100))&&(T>=(ton1+d1))&&(!r))//если нажат "+" и есть возможность расширения импульса и разрешено изменение

{	
	ton1=ton1+d1;//увеличиваем время PORTD1_on
	ton1_=ton1;//обновляем дубль
	r=1;//запрещаем изменения		
}
										// **** кнопка "-" *** //

if((!(port_state&0b00001000))&&(0<=(ton1-d1))&&(!r))//если нажат "-" и есть возможность расширения импульса и разрешено изменение

{	
	ton1=ton1-d1;//уменьшаем время PORTD1_on
	ton1_=ton1;//обновляем дубль
	r=1;//запрещаем изменения	
}
}

// *********************************************** ШИМ ********************************************  //

PORTD=0xFF;//включаем всё
		
while(T>=0)//период

{						
	if(ton0>=0)ton0--;//считаем время PORTD0_on
	else PORTD&=0b11111110;//выключаем PORTD0_on
		
	if(ton1>=0)ton1--;//считаем время PORTD1_on
	else PORTD&=0b11111101;//выключаем PORTD1_on
			
	T--;//считаем период				
}
		
T=T_;//восстанавливаем период
	
ton0=ton0_;//обновляем или восстанавливаем время PORTD0_on
ton1=ton1_;//обновляем или восстанавливаем время PORTD1_on
		
if(port_state==0b11111111)r=0;//если кнопки отпущены разрешаем изменение

}
}

 

Если не переходить к использованию аппаратного таймера, можно что-то улучшить радикально?

И чем лучше сравнение с переменной, в которой сохраняется состояние порта, чем сравнение с самим состоянием порта?

Пионер - всем ребятам пример.

There should be information on the web about this, but it may take some digging.

Ссылка на комментарий
Поделиться на другие сайты

Ну наворотил.... оно-то может и работает, но это монстр.

Сравнение с портом плохо тем что содержимое порта может изменится в любой момент времени! Читаешь порт там 1, ещё раз читаешь а там уже 0...

Вот представь себе, ты читаешь порт и регистрируешь что нажата кнопка, потом переходишь к определению какая именно(исходя из факта что как минимум одна из кнопок точно нажата) - читаешь порт ещё раз а там уже нет нажатия... из-за дребезга а алгоритм не предусматривает этой ситуации. Сохранение в переменную гарантирует что оно не изменится пока ты не проведёшь необходимые операции над данными. И это один из самых безопасных вариантов развития событий. Бывают ситуации более изощрённые.
И что самое обидное при этом "глюки" возникают редко и НИКОГДА не ловятся при отладке. Реальный девайс глючит редко но метко, а при отладке всё идеально и сидишь ломаешь голову что за фигня?

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

 

Цитата

Если у меня период состоит из T=110 тактов, то у меня 110 - разрядный шим?

Это 6.9 двоичных разрядов. Но мысль в верном направлении. Если при 110 шагах ШИМ у вас возникает необходимость изменять величину шагами по 10 то лучше сделать ШИМ на 10 шагов и изменять по 1...

Изменено пользователем Alexeyslav

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

Ссылка на комментарий
Поделиться на другие сайты

@pliss , постарайтесь понять главное: надо не стремиться код писать сразу правильно, а постепенно обдумывать шаг за шагом действия, которые приведут вас к желаемому результату. Советов вам дают много правильных, но ЧАСТНЫХ, а увязывать их воедино приходится вам - пока вы не представляете, в какую мозаику следует сложить данные советы, у вас получается что угодно, но не красивый результат...

Не претендуя на исключительность, я все-таки посоветую вам прочесть мою статью, которая появилась после того, как я заморился объяснять начинающим, как следует поступать при проектировании программ... В свете статьи я бы рекомендовал вам разбивать решение задачи с кнопками на такую последовательность действий:

1. должна быть функция, которая вернет текущее состояние кнопок
2. если кнопок несколько - каждая должна быть как-то описана, чтобы вышеупомянутая функция возвращала не абы что, а конкретные сведения о конкретных кнопках
3. для узнавания состояния кнопок надо сделать функцию опроса физических линий МК (портов)
4. для борьбы с дребезгом контактов надо сделать двукратный опрос с паузой между ними физических линий и сравнить результаты

В итоге получается такой псевдокод:

тип_КНОПКА {
   НЕТ_НАЖАТЫХ_КНОПОК,
   Кнопка_1,
   Кнопка_2,
   ...
   Кнопка_N
}

тип_КНОПКА опрос_портов(){
   // считать порт
   // проанализировать биты в результате считывания
   // выдать нужный результат
}

тип_КНОПКА состояние_кнопок(){
   тип_КНОПКА перв_опрос;
   
   перв_опрос = опрос_портов();
   пауза_антидребезг;
   если опрос_портов() == перв_опрос
      то вернуть перв_опрос
      иначе вернуть НЕТ_НАЖАТЫХ_КНОПОК;
}

// работа с кнопками в главном цикле
  
бесконечный_цикл(){
   селектор(состояние_кнопок()){
      Кнопка_1: // обработать нажатие первой кнопки
      Кнопка_2: // обработать нажатие второй кнопки
      ...
      Кнопка_N: // обработать нажатие последней кнпоки
      НЕТ_НАЖАТЫХ_КНОПОК: // обработать, если необходимо, ситуацию без нажатых кнопок
   }
}

Я специально не стал писать на Си, чтобы не убивать вашу творческую инициативу :)

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, ARV сказал:

 

Это называется - проектирование сверху вниз. Постановка задачи. ТЗ. И постепенное дробление. Мыслить главными составляющими. Оперировать понятиями. Как-то так...

Ссылка на комментарий
Поделиться на другие сайты

3 минуты назад, demiurg1978 сказал:

Это называется - проектирование сверху вниз.

Так моя статья и называется "Нисходящее программирование" :) 

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, ARV сказал:

Так моя статья и называется "Нисходящее программирование" :) 

Взялся за статью, так расскажи про программные таймеры. Начинающие бьются именно из-за delay, потому что тяму у них не хватает потом, как распараллелить процессы.

Ссылка на комментарий
Поделиться на другие сайты

5 минут назад, demiurg1978 сказал:

Начинающие бьются именно из-за delay, потому что тяму у них не хватает потом, как распараллелить процессы.

С моей точки зрения это как раз из-за того, что многие гуру негативно отзываются о программных задержках и вызывают у начинающих комплекс неполноценности... А на самом деле 90% всех задач, которые интересны начинающим, делаются на delay-ях преотлично. Дело не в задержках, а в разделении задачи на процессы, а процессов на фоновые и нефоновые.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

Я ни разу не видел чтобы "гуру" негативно отзывались о программных таймерах.

Это значит, что они неправильно их готовят. Лично у меня даже нет таких понятий, как фоновые, не фоновые. Есть обработчики прерываний и основной цикл. В обработчиках ничего лишнего. Установка новых значений, установка флагов, необходимые действия. Все остальное в основном цикле.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...