|
|
| ||||||||
|
|
|
|
218815
119
0
0
|
|
Опции темы | Поиск в этой теме |
|
|
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. Так программа была бы в ГОРАЗДО более ЧИТАЕМОМ виде. А переводить все эти шестнадцатиричные коды не удобно. |
|
|
|
|
|
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 |
|
|
|
|
|
83
|
|
Новичок
Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07
Сообщений: 447
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
На нашем сайте есть уроки от Галла. Там все просто и понятно. На языке Си.
|
|
|
|
|
|
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); |
|
|
|
|
|
|
85
|
|
Ветеран Фонарёвки
|
Хм... кому как...
DDRA|=0b10101000 или как в cvavr но только там. PORTA.3=1; PORTA.5=1; PORTA.7=1; и наоборот PORTA.3=0; PORTA.5=0; PORTA.7=0; |
|
|
|
|
|
86
|
|
Новичок
Регистрация: 14.02.2010 Последняя активность: 28.04.2016 12:07
Сообщений: 447
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
А когда это си научился с 2ичным кодом работать? Если не ошибаюсь Галл рассказывал что си только 16ричное принимает.
|
|
|
|
|
|
87
|
|
Завсегдатай Фонарёвки
Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11
Сообщений: 787
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Это работает только в компиляторах для микроконтроллерах, там где добавили такую возможность
|
|
|
|
|
|
88
|
|
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1342
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Как в Си реализовать конечные автоматы? Вот мне нужно собрать флаги в одну кучу, которая образует как бы номер требуемой функции. Но чтоб не перебирать по очереди все функции, пока не доберёшься до нужной, а сразу прыгать куда надо. На ассемблере это не сложно. Засунул флаги в указатель, умножил на два, добавил метку первого безусловного перехода на первую функцию, и всё. Теперь двоичное число, которое образуют флаги, соответствует номеру строки за меткой, а там уже можно городить переходы (векторы) куда угодно, и их может быть огромное количество...
Зачем это нужно? Неоднократно уже подобный подход юзаю. Везде, где количество флагов больше 3-х - более выгодным и удобным вариантом оказывался подобный подход. Та же 5-ти битная умная кнопка (32 состояния), не перебирать же все 32 варианта выполнения кода каждый раз при нажатии на неё? |
|
|
|
|
|
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:
...
...
}
|
|
|
|
|
|
90
|
|
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1342
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Это мне уже SviMik предложил, после чего я и написал тут свой пост, т.к. этот оператор (switch) перебирает по очереди, пока не наткнётся, а не сразу вычисляет нужный вариант...
|
|
|
|
|
|
91
|
|
Завсегдатай Фонарёвки
Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11
Сообщений: 787
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
|
|
|
|
|
|
92
|
|
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 05.09.2022 18:18
Сообщений: 1034
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Сделать массив указателей на функции, нужные указатели инициализиуются нужными функциями, остальные функцией-затычкой.
А switch действительно по порядку перебирает, причем if... else if ... else даже покомпактнее.
__________________
Чем бы дитя не тешилось - лишь бы не лазером... |
|
|
|
|
|
93
|
|
Ветеран Фонарёвки
Регистрация: 15.02.2010 Последняя активность: 24.08.2019 11:36
Сообщений: 1342
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
Я не пробовал код генерировать, тут и так ясно что он делает, и что мне не подходит. Мне не перебирать нужно, а сразу вычислить куда прыгнуть. Вот только ЯВУ прыгать не очень любят, и не приспособлены, в общем-то. Но как-то же делают подобные механизмы? Проверка правописания, автозамена, вод текста Т9 и прочие подобные огромные базы, требования к скорости работы которых не мене огромны...
Не понял, можно пример? Массив указателей - запросто в ассемблере (там вообще всё запросто, пока дело не доходит до возни с ОЗУ и знаковой арифметикой), но я с самого начала в Си пробовал прыгать так - что-то не очень красиво получается, да и не мене костыльно за обработку прерываний получается... |
|
|
|
|
|
94
|
|
Завсегдатай Фонарёвки
Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11
Сообщений: 787
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
switch не обязан перебирать все варианты. Ты сначала посмотри что он реально генерирует, а потом уже решай, подходит он тебе или нет. Для некоторых типов МК он вполне сможет сгенерировать это так, как тебе нужно.
|
|
|
|
|
|
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);
}
|
|
|
|
|
|
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... |
|
|
|
|
|
97
|
|
Завсегдатай Фонарёвки
|
Выкрутился, убрав оптимизацию для этой функции:
Код:
void rbuf_write(unsigned char d) __attribute__((optimize(0))); Другой вариант - переписать это место на ассемблере. Но это некрасиво. Код:
asm volatile( "lds r25, buf_len\n" "cpi r25, 0x7F\n" "brcc .-8\n" ); |
|
|
|
|
|
98
|
|
Завсегдатай Фонарёвки
Регистрация: 17.02.2010 Последняя активность: 30.01.2016 13:11
Сообщений: 787
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
|
|
|
|
|
|
99
|
|
Завсегдатай Фонарёвки
|
Естественно забыл
![]() Зато теперь точно понял, для чего он нужен. |
|
|
|
|
|
100
|
|
Лазеростроитель
Регистрация: 23.02.2012 Последняя активность: 24.02.2012 11:43
Сообщений: 2
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях
|
День добрый. Ещё один вопрос по прерываниям. Вот к примеру программа только что ушла на задержку типа delay_ms(8000), в этот момент работает прерывание к примеру INT0, после которого нужно резко уйти в другую часть программы, ну выключить что-то, а мы ещё находимся в подпрограмме delay_ms и ждать нужно пока она окончится, как резко прекратить подпрограмму и выполнить хотя бы следующую команду?
|
|
|
|