|
|
|
|
185506 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 и ждать нужно пока она окончится, как резко прекратить подпрограмму и выполнить хотя бы следующую команду?
|