|  | 
| 
 | ||||||||
|     | 
 | 
|  |  219347  119  0  0 |  | Опции темы | Поиск в этой теме | 
|  20.12.2011, 00:01 |  81   | 
| Новичок Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07 
					Сообщений: 447
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Ну во первых программа не очень понятно написана на мой взгляд... Советую писать так: DDRA |= (1<<3) | (1<<5) | (1<<7); Т.е. тут все понятно 3,5, и 7 биты в 1 становятся. Или же. DDRA &= ~((1<<3) | (1<<5) | (1<<7)); Здесь наоборот 3,5, и 7 биты ставятся в 0. Так программа была бы в ГОРАЗДО более ЧИТАЕМОМ виде. А переводить все эти шестнадцатиричные коды не удобно. | 
|   |     | 
|  20.12.2011, 17:33 |  82   | 
| Завсегдатай Фонарёвки |   
			
			Да, и к тому же в вашей программе вы сравнивает значения целого порта с числом... а вам то нужно считать один бит: if (PINB & (1 << N)==0x00) { на пине ноль } Где N - номер бита в порту от 0 до 7 То,что посоветовал Экко - верно, но для справки - остальные биты при той операции в порте не затрагиваются. И он привел "укороченную" запись, которую можно расписать как DDRA = DDRA | (1<<3) | (1<<5) | (1<<7); DDRA = DDRA & ~((1<<3) | (1<<5) | (1<<7)); Соответственно. И советую прочитать курс DI HALT'a по ассемблеру для AVR-ок на easyelectronics.ru | 
|   |     | 
|  20.12.2011, 18:20 |  83   | 
| Новичок Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07 
					Сообщений: 447
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			На нашем сайте есть уроки от Галла. Там все просто и понятно. На языке Си.    | 
|   |     | 
|  20.12.2011, 18:21 |  84   | |
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   Цитата: Код: // где-нибудь в начале программы вставить #define BIT(B) (1 << (B)) // ... а затем DDRA |= BIT(3) | BIT(5) | BIT(7); | |
|   |     | 
|  20.12.2011, 19:59 |  85   | 
| Ветеран Фонарёвки |   
			
			Хм... кому как... DDRA|=0b10101000 или как в cvavr но только там. PORTA.3=1; PORTA.5=1; PORTA.7=1; и наоборот PORTA.3=0; PORTA.5=0; PORTA.7=0; | 
|   |     | 
|  20.12.2011, 21:15 |  86   | 
| Новичок Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07 
					Сообщений: 447
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			А когда это си научился с 2ичным кодом работать? Если не ошибаюсь Галл рассказывал что си только 16ричное принимает.
		 | 
|   |     | 
|  21.12.2011, 07:23 |  87   | 
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Это работает только в компиляторах для микроконтроллерах, там где добавили такую возможность
		 | 
|   |     | 
|  21.12.2011, 20:28 |  88   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36 
					Сообщений: 1342
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Как в Си реализовать конечные автоматы? Вот мне нужно собрать флаги в одну кучу, которая образует как бы номер требуемой функции. Но чтоб не перебирать по очереди все функции, пока не доберёшься до нужной, а сразу прыгать куда надо. На ассемблере это не сложно. Засунул флаги в указатель, умножил на два, добавил метку первого безусловного перехода на первую функцию, и всё. Теперь двоичное число, которое образуют флаги, соответствует номеру строки за меткой, а там уже можно городить переходы (векторы) куда угодно, и их может быть огромное количество... Зачем это нужно? Неоднократно уже подобный подход юзаю. Везде, где количество флагов больше 3-х - более выгодным и удобным вариантом оказывался подобный подход. Та же 5-ти битная умная кнопка (32 состояния), не перебирать же все 32 варианта выполнения кода каждый раз при нажатии на неё? | 
|   |     | 
|  21.12.2011, 21:20 |  89   | 
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Ну если тебе это проще на ассемблере делать, то я бы на нём и делал   А так самый простой вариант: Код: swicth (state)
{
case STATE_1:
    ...
    state = ... ;
    break;
case STATE_2:
    ...
    state = ... ;
    break;
case STATE_3:
    ...
    ...
} | 
|   |     | 
|  21.12.2011, 21:59 |  90   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36 
					Сообщений: 1342
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Это мне уже SviMik предложил, после чего я и написал тут свой пост, т.к. этот оператор (switch) перебирает по очереди, пока не наткнётся, а не сразу вычисляет нужный вариант...
		 | 
|   |     | 
|  21.12.2011, 22:04 |  91   | 
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   | 
|   |     | 
|  21.12.2011, 22:07 |  92   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18 
					Сообщений: 1034
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Сделать массив указателей на функции, нужные указатели инициализиуются нужными функциями, остальные функцией-затычкой. А switch действительно по порядку перебирает, причем if... else if ... else даже покомпактнее. 
				__________________ Чем бы дитя не тешилось - лишь бы не лазером... | 
|   |     | 
|  21.12.2011, 22:29 |  93   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36 
					Сообщений: 1342
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Я не пробовал код генерировать, тут и так ясно что он делает, и что мне не подходит. Мне не перебирать нужно, а сразу вычислить куда прыгнуть. Вот только ЯВУ прыгать не очень любят, и не приспособлены, в общем-то. Но как-то же делают подобные механизмы? Проверка правописания, автозамена, вод текста Т9 и прочие подобные огромные базы, требования к скорости работы которых не мене огромны... Не понял, можно пример? Массив указателей - запросто в ассемблере (там вообще всё запросто, пока дело не доходит до возни с ОЗУ и знаковой арифметикой), но я с самого начала в Си пробовал прыгать так - что-то не очень красиво получается, да и не мене костыльно за обработку прерываний получается... | 
|   |     | 
|  21.12.2011, 22:52 |  94   | 
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			switch не обязан перебирать все варианты. Ты сначала посмотри что он реально генерирует, а потом уже решай, подходит он тебе или нет. Для некоторых типов МК он вполне сможет сгенерировать это так, как тебе нужно.
		 | 
|   |     | 
|  22.12.2011, 12:32 |  95   | 
| Ветеран Фонарёвки Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18 
					Сообщений: 1034
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			Пример: Код: // массив из 3 указателей на функции, с одним параметром int и возвращаюшие char
char  (*FnTab[3])(int param); 
// сами функции:
char  Fn1(int param) 
{
//.....  
  return 0;
}
char  Fn2(int param)
{
//....  
  return 1;
}
// и так далее...
int main()
{
int i;  
// инициализация указателей 
  FnTab[0]=Fn1;
  FnTab[1]=Fn2;
// ....  
  i=1;
// вызов функции по индексу, выполнится Fn2(0x5)
  FnTab[i](0x5); 
} | 
|   |     | 
|  26.12.2011, 04:20 |  96   | 
| Завсегдатай Фонарёвки |   
			
			Я никак не могу заставить компилятор правильно обработать этот код. Пробовал по-всякому: Код: while(buf_len>=128){asm("sbi 0x08, 3");} //preventing overflowКод: 464: lds r25, 0x0109 ; загружает 468: sbrs r25, 7 ; проверяет только один раз 46a: rjmp .+4 ; 0x470 ; если меньше - идёт дальше 46c: sbi 0x08, 3 ; 8 46e: rjmp .-4 ; 0x46c ; если больше - зацикливается на месте 470: <...> Код: while(buf_len>=128); //preventing overflow Код: 464: lds r25, 0x0109 ; загружает 468: sbrc r25, 7 ; проверяет только один раз 46a: rjmp .+26 ; 0x486 ; если больше - прыгает в конец <...> 484: ret 486: rjmp .-2 ; 0x486 ; в конце у него заготовлено зацикливание 
				__________________ e-mail: euro@********* jabber: shop@********* Сообщение: http://forum.*********/sendm... | 
|   |     | 
|  26.12.2011, 07:03 |  97   | 
| Завсегдатай Фонарёвки |   
			
			Выкрутился, убрав оптимизацию для этой функции: Код: void rbuf_write(unsigned char d) __attribute__((optimize(0))); Другой вариант - переписать это место на ассемблере. Но это некрасиво. Код: asm volatile( "lds r25, buf_len\n" "cpi r25, 0x7F\n" "brcc .-8\n" ); | 
|   |     | 
|  26.12.2011, 07:45 |  98   | 
| Завсегдатай Фонарёвки Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11 
					Сообщений: 787
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   | 
|   |     | 
|  26.12.2011, 20:28 |  99   | 
| Завсегдатай Фонарёвки |   
			
			Естественно забыл   Зато теперь точно понял, для чего он нужен. | 
|   |     | 
|  23.02.2012, 12:58 |  100   | 
| Лазеростроитель Регистрация: 23.02.2012 Последняя активность: 24.02.2012 11:43 
					Сообщений: 2
 Сказал(а) спасибо: 0 
		
			
				Поблагодарили: 0 раз(а) в 0 сообщениях
			
		
	 |   
			
			День добрый. Ещё один вопрос по прерываниям. Вот к примеру программа только что ушла на задержку типа delay_ms(8000), в этот момент работает прерывание к примеру INT0, после которого нужно резко уйти  в другую часть программы, ну выключить что-то, а мы ещё находимся в подпрограмме delay_ms и ждать нужно пока она окончится, как резко прекратить подпрограмму и выполнить хотя бы следующую команду?
		 | 
|   |     |