|  | 
| 
 | ||||||||
|     | 
 | 
|  |  219351  119  0  0 |  | Опции темы | Поиск в этой теме | 
|  23.02.2012, 18:17 |  101   | 
| Завсегдатай Фонарёвки |   
			
			Если разрешены прерывания, то выполнение программы "приостанавливается" - сохраняются значения регистров, производится вызов обработчика прерывания. Как только он отработал, производится возврат управления программе, т.е. в вашем случае продолжится выполнение delay_ms(8000);. Как следствие из этого и не следует долго засиживаться в обработчиках прерываний
		 | 
|   |     | 
|  24.02.2012, 11:43 |  102   | 
| Лазеростроитель Регистрация: 23.02.2012 Последняя активность: 24.02.2012 11:43 
					Сообщений: 2
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Да это всё понятно, в прерывании я выполняю одну-две команды, возвращаюсь в delay, как из него экстренно выйти, ждать 8000ms нельзя, нужен экстренный стоп ну или запуск чего либо, а программа в задержке сидит. Как тут быть?
		 | 
|   |     | 
|  24.02.2012, 15:53 |  103   | 
| Новичок Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07 
					Сообщений: 447
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Вообще то вам правильно все объяснили. Если прерывание сработает, то у вас ТУТ ЖЕ программа ВЫЙДЕТ из той задержки. И начнет ВЫПОЛНЯТЬ ПРОГРАММУ ПРЕРЫВАНИЯ. А после выполнения вернется в задержку.
		 | 
|   |     | 
|  24.02.2012, 16:25 |  104   | |
| Ветеран Фонарёвки Регистрация: 25.02.2010 Последняя активность: 11.09.2013 18:36 
					Сообщений: 1302
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   Цитата: PS: если уровень ниже последующей. | |
|   |     | 
|  25.02.2012, 18:14 |  105   | 
| Ветеран Фонарёвки |   
			
			Либо не использовать delay а писать свою функцию, на цыкле например, и в случае чего выполнять return из него, либо по таймеру проверять значение флагов, и если что то изменилось, то выполнять первостепенное дело не дожидясь завершения delay.
		 | 
|   |     | 
|  25.02.2012, 19:37 |  106   | 
| Завсегдатай Фонарёвки |   
			
			Используй спящий режим и команду sleep. При любом прерывании он выйдет из спящего режима, и после выхода из прерывания уже не продолжит спать.
		 
				__________________ e-mail: euro@********* jabber: shop@********* Сообщение: http://forum.*********/sendm... | 
|   |     | 
|  25.02.2012, 21:06 |  107   | |
| Ветеран Фонарёвки |   Цитата: Из спячки он выйдет при любом прерывании, а задержку нужно прекратить не в любом случае. Спячка идеальна, если нужно ждать какое то событие по прерыванию, тогда в обработчике прерывания можно вообще ничего не делать, просто будить контроллер. | |
|   |     | 
|  21.05.2012, 20:52 |  108   | 
| Лазеростроитель Регистрация: 21.05.2012 Последняя активность: 23.05.2012 02:02 
					Сообщений: 2
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Доброго дня, опыта слишком мало, Си уже давненько не видел, прошу помощи в этом коде, вырезал из текста ... Код:  typedef unsigned char byte;
 struct lcdSymbol {
    byte val;
    byte row;
    byte line;
    byte nbValues;
    byte maxLen;
    byte* caption; // 0 if unused; e.g. "ID "
    byte** line1Values; // e.g. "Full", "1/2", "1/4"
    byte** line2Values; // 0 if unused
 };
 struct lcdSymbol** lcdSymbols = txSymbols
 struct lcdSymbol* rxSymbols[ ] = {&groupSym, &deviceSym, &powerRxSym, 
    &blSym, &idSym, &modeSym };
  // и дальше есть строки
 main {
    prevVal = lcdSymbols[cursorPos]->val;
    currVal = (prevVal+1) % (lcdSymbols[cursorPos]->nbValues);
 }byte* byte** ... что означают звздочки в описании структуры lcdSymbol 2) как используется lcdSymbols и уже две "**" сразу | 
|   |     | 
|  21.05.2012, 22:30 |  109   | 
| Ветеран Фонарёвки |   
			
			это функция такая запись в ней то что со звездочками это указатель на позицию или номер символа. сам возился когда строку в последовательность символов превращал.
		 | 
|   |     | 
|  22.05.2012, 12:03 |  110   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18 
					Сообщений: 1034
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			byte* - указатель на байт (физически - адрес одиночного байта в памяти, или адрес первого элемента массива байт) byte** - указатель на указатель на байт (физически - адрес указателя на байт в памяти, или адрес первого указателя массива указателей на байт) 
				__________________ Чем бы дитя не тешилось - лишь бы не лазером... | 
|   |     | 
|  23.05.2012, 02:02 |  111   | 
| Лазеростроитель Регистрация: 21.05.2012 Последняя активность: 23.05.2012 02:02 
					Сообщений: 2
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Спасибо Вам за подсказки. Полистал Кернигана и Ритчи, много полезного, но как-то скомканно, без примеров (.... вот это почитал ... Указатели на структуры Многоуровневая адресация теперь код понимаю следующим образом Код: typedef unsigned char byte;
struct lcdSymbol {
    byte val;
    byte row;
    byte line;
    byte nbValues;
    byte maxLen;
    byte* caption; // 0 if unused; e.g. "ID "
    byte** line1Values; // e.g. "Full", "1/2", "1/4"
    byte** line2Values; // 0 if unused
 };
static byte* blValues1[]   = { lampOff1, lampOn1 };	// массив указателей
static byte* blValues2[]   = { lampOff2, lampOn2 };	// ссылающихся на массивы "символов"
static byte* modeValues[]  = { codeTx, codeRx };	// возможных режимов
struct lcdSymbol powerASym = { 0, 1, 1, 8, 4, codeA, powerValues, 0 }; // codeA - указатель на первый символ в массиве
struct lcdSymbol powerBSym = { 0, 1, 2, 8, 4, codeB, powerValues, 0 }; // создаём структуры с типом lcdSymbol
struct lcdSymbol powerCSym = { 0, 1, 3, 8, 4, codeC, powerValues, 0 }; // powerValues - двойной указатель на массив указателей, разных режимов
	// массив указателей на адреса структур, 2 режима работы с разным набором структур
struct lcdSymbol* txSymbols[] = {&powerASym, &powerBSym, &powerCSym, &powerDSym, &blSym, &idSym, &modeSym};
struct lcdSymbol* rxSymbols[] = {&groupSym, &deviceSym, &powerRxSym, &blSym, &idSym, &modeSym };
struct lcdSymbol** lcdSymbols = txSymbols; // двойной указатель **lcdSymbols на первый указатель  в массиве txSymbols
					   // а тот в свою очередь на конкретную структуру 
  // и дальше есть строки
 main {
   .
   . 
   .
    prevVal = lcdSymbols[cursorPos]->val;
    currVal = (prevVal+1) % (lcdSymbols[cursorPos]->nbValues);
 }Вроде понял)) | 
|   |     | 
|  09.06.2012, 01:46 |  112   | 
| Увлеченный |   
			
			Ребят, расскажите, пожалуйста, как использовать АЦП, что такое разрядность, и, хотелось бы, пример. Что-то совсем не вкуриваю. И какое значение возвращает функция ADC_Read? Спасибо!
		 
				__________________ Внимание! Это сообщение сгенерировано автоматически, отвечать на него не нужно. | 
|   |     | 
|  09.06.2012, 08:42 |  113   | 
| Ветеран Фонарёвки |   
			
			Разрядность- точность его. допустим он 10 разрядный тогда эта функция возвращает значения от 0 до 1024. расчитывается оно относительно опорного напряжения. допустим опорное напряжение формируется внутренним источником. допустим это 2.55 вольта тогда мк делит это значение на разрядность - 2.56/1024=0,0025 вольта на 1 значение, иными словами АЦП может измерить напряжение с точностью в 0,0025 вольта. При замере напряжения мк сравнивает их и на выходе выдает значение . нужно учитывать что разрядность так же зависит от скорости ацп. чем медленнее тем точнее это в даташите есть. Расчитывается напряжение так: при источнике опорного напряжения 2,56 вольта имеем 1 значение в 0,0025 вольта. Если входное напряжение у нас выше чем 2,56 то его нужно поделить резистивным делителем, что бы попасть в пределв 0-2,56, а при расчетах еще и умножать на коэффициент деления резистивного делителя. допустим мы меряем напряжение до 12 вольт, тогда резистивным делителем можно поделить его напрмиер на 5 - получим максимум 2,4 вольта. в итоге расчет напряжения будет такой. 0,0025 * [значение которое вернула функция]*5 допустим получили на выходе функции 524, тогда 0,0025*524=1,31 вольта это на входе АЦП а 1,31*5=6,55 это напряжение до резистивного делителя. | 
|   |     | 
|  09.06.2012, 13:35 |  114   | 
| Увлеченный |   Цитата: Спасибо, с этим понятно. Буду пробовать! | 
|   |     | 
|  09.06.2012, 17:45 |  115   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36 
					Сообщений: 1342
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			На первый взгляд всё просто, но у АЦП столько нюансов, что точность можно поднять на порядок, если подходить к этому делу с умом. Вообще вики в помощь: АЦП. Полезно ещё почитать за оверсемплинг. Чем выше скорость АЦП, тем он точнее (при равной разрядности), до поры до времени. Но чтоб пользоваться этим - недостаточно в лоб считывать данные, нужно проводить коррекцию, усреднять, подмешивать шум в измеряемый сигнал и т.п. К примеру у AVR (АЦП последовательного приближения) у меня более менее нормально считать в лоб получается на скорости всего лишь 9 килосемплов, это если пользуешься мультиплексором (каждый раз меряешь что-то новое). На более высоких скоростях устройство выборки-хранения не успевает полностью перезарядится до значения резко изменившегося уровня сигнала. Поведение похожее на RC-фильтр, этот эффект нужно учитывать и писать дополнительные корректирующие алгоритмы. Он так же и на АЧХ влияет, в некоторых задачах это может быть критичным (крутит амплитуду и фазу в зависимости от частоты). На более высоких скоростях растёт шум, да, но усреднение позволит получать разрядность и выше 10-ти бит, а со снижением частоты измеряемого сигнала - разрядность будет продолжать расти. Тут шум наоборот помогает. Особенно это актуально для сигма-дельта АЦП, они изначально за счёт шума квантования и работают... В общем запас по частоте дискретизации позволяет получить более годный (мягкий) для многих задач сигнал. И на резкие изменения можно среагировать быстрее, и более точно померить на более длительных периодах, причём одновременно. Алиасинг тоже существенно меньше (из-за него желательно входной сигнал фильтровать, хотя бы простым RC-фильтром). | 
|   |     | 
|  09.06.2012, 18:43 |  116   | 
| Ветеран Фонарёвки |   
			
			Пришел Инф и распугал всех новичков    | 
|   |     | 
|  09.06.2012, 19:18 |  117   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36 
					Сообщений: 1342
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			А что тут страшного? Я ведь не говорю что без всех этих моментов АЦП юзать невозможно? Возможно, просто тогда круг задач, или качество их выполнения, которые с его помощью можно решить, сужается. А новичку и не надо относится к этому настолько серьёзно, задачи у него, как правило, достаточно примитивные. Это я просто забегая на перёд описал некоторые моменты, которые в будущем могут пригодится, как пригодились мне... Раньше я, к примеру, не верил что на AVR можно собрать достаточно качественный преобразователь, чтоб питать им такие нежные вещи как ЛД. А сейчас собираюсь собрать бек-буст на 4 ампера, на тиньке. И рассчитываю получить довольно высокую скорость реакции на помехи и довольно высокую точность установки заданного режима. Просто используя передискретизацию, коррекцию АЧХ, и сигма-дельта модуляцию слишком грубой ШИМ... | 
|   |     | 
|  09.06.2012, 19:38 |  118   | 
| Завсегдатай Фонарёвки |   
			
			Инф уже сам как ходячая википедия   (если кто обратил внимание на ссылки на википедию в тексте). | 
|   |     | 
|  09.06.2012, 23:46 |  119   | 
| Ветеран Фонарёвки Регистрация: 25.02.2010 Последняя активность: 11.09.2013 18:36 
					Сообщений: 1302
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   | 
|   |     | 
|  25.08.2015, 11:41 |  120   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18 
					Сообщений: 1034
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |  Re: Основы программирования контроллеров AVR на Си 
			
			Эту тему бы в "важные" поднять...
		 | 
|   |     |