Светодиодные фонари и световые приборы. Всё о светотехнике.
Вернуться   Форум FONAREVKA.RU Лаборатория Электроника и схемотехника Электроника Микроконтроллеры
Расширенный поиск
Забыли пароль? Регистрация

  • О нашем проекте
  • Светотехника и световые приборы
  • Правила форума
Проект FONAREVKA.RU специализируется на предоставлении всей необходимой информации по светотехнике:

— светодиодные фонари;
— различные источники питания;
— разнообразные зарядные устройства;
— освещение помещений и наружное освещение;
— световые приборы для личного, пассажирского и грузового транспорта;
— специальные световые приборы для медицины, для растений, для аквариумов, для террариумов, а также аварийно-сигнальные световые приборы;
— альтернативные источники света;
— лазеры и лазерная техника.

Если у вас есть вопросы по выбору фонарей, аккумуляторов и зарядных устройств ознакомьтесь с FAQ от наших экспертов:

F.A.Q. по выбору фонарей различных типов;
F.A.Q. по выбору аккумуляторов;
F.A.Q. по выбору зарядных устройств.
Ответ  Создать новую тему
Просмотров в теме 163383   Ответов в теме 119   Подписчиков на тему 0   Добавили в закладки 0
Опции темы Поиск в этой теме
Старый 20.12.2011, 00:01   81
ECCOsea
Новичок
 
Аватар для ECCOsea
 
Регистрация: 14.02.2010
Последняя активность: 28.04.2016 12:07
Сообщений: 464
Сказал(а) спасибо: 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.

Так программа была бы в ГОРАЗДО более ЧИТАЕМОМ виде. А переводить все эти шестнадцатиричные коды не удобно.
ECCOsea вне форума   Ответить с цитированием Вверх
Старый 20.12.2011, 17:33   82
lasers_chem_kot
Завсегдатай Фонарёвки
 
Аватар для lasers_chem_kot
 
Регистрация: 13.03.2010
Последняя активность: 15.08.2015 05:45
Сообщений: 522
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для lasers_chem_kot с помощью ICQ
По умолчанию

Да, и к тому же в вашей программе вы сравнивает значения целого порта с числом... а вам то нужно считать один бит:
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
lasers_chem_kot вне форума   Ответить с цитированием Вверх
Старый 20.12.2011, 18:20   83
ECCOsea
Новичок
 
Аватар для ECCOsea
 
Регистрация: 14.02.2010
Последняя активность: 28.04.2016 12:07
Сообщений: 464
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

На нашем сайте есть уроки от Галла. Там все просто и понятно. На языке Си.
ECCOsea вне форума   Ответить с цитированием Вверх
Старый 20.12.2011, 18:21   84
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от ECCOsea :
Советую писать так:
DDRA |= (1<<3) | (1<<5) | (1<<7); Т.е. тут все понятно 3,5, и 7 биты в 1 становятся.
Так тоже не совсем понятно. Лучше делать так:
Код:
// где-нибудь в начале программы вставить
#define BIT(B) (1 << (B))

// ... а затем
DDRA |= BIT(3) | BIT(5) | BIT(7);
Ну или что-то похожее можно придумать
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 20.12.2011, 19:59   85
lasers_Ryazanec
Ветеран Фонарёвки
 
Регистрация: 04.05.2010
Последняя активность: 15.11.2019 11:47
Сообщений: 1409
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для lasers_Ryazanec с помощью ICQ
По умолчанию

Хм... кому как...
DDRA|=0b10101000

или как в cvavr но только там.
PORTA.3=1;
PORTA.5=1;
PORTA.7=1;
и наоборот
PORTA.3=0;
PORTA.5=0;
PORTA.7=0;
lasers_Ryazanec вне форума   Ответить с цитированием Вверх
Старый 20.12.2011, 21:15   86
ECCOsea
Новичок
 
Аватар для ECCOsea
 
Регистрация: 14.02.2010
Последняя активность: 28.04.2016 12:07
Сообщений: 464
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

А когда это си научился с 2ичным кодом работать? Если не ошибаюсь Галл рассказывал что си только 16ричное принимает.
ECCOsea вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 07:23   87
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Это работает только в компиляторах для микроконтроллерах, там где добавили такую возможность
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 20:28   88
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Как в Си реализовать конечные автоматы? Вот мне нужно собрать флаги в одну кучу, которая образует как бы номер требуемой функции. Но чтоб не перебирать по очереди все функции, пока не доберёшься до нужной, а сразу прыгать куда надо. На ассемблере это не сложно. Засунул флаги в указатель, умножил на два, добавил метку первого безусловного перехода на первую функцию, и всё. Теперь двоичное число, которое образуют флаги, соответствует номеру строки за меткой, а там уже можно городить переходы (векторы) куда угодно, и их может быть огромное количество...

Зачем это нужно? Неоднократно уже подобный подход юзаю. Везде, где количество флагов больше 3-х - более выгодным и удобным вариантом оказывался подобный подход. Та же 5-ти битная умная кнопка (32 состояния), не перебирать же все 32 варианта выполнения кода каждый раз при нажатии на неё?
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 21:20   89
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Ну если тебе это проще на ассемблере делать, то я бы на нём и делал
А так самый простой вариант:
Код:
swicth (state)
{
case STATE_1:
    ...
    state = ... ;
    break;

case STATE_2:
    ...
    state = ... ;
    break;

case STATE_3:
    ...
    ...
}
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 21:59   90
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Это мне уже SviMik предложил, после чего я и написал тут свой пост, т.к. этот оператор (switch) перебирает по очереди, пока не наткнётся, а не сразу вычисляет нужный вариант...
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 22:04   91
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Это мне уже SviMik предложил, после чего я и написал тут свой пост, т.к. этот оператор (switch) перебирает по очереди, пока не наткнётся, а не сразу вычисляет нужный вариант...
Странно. Покажи какой ассемблерный код у тебя генерируется для switch.
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 22:07   92
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Сделать массив указателей на функции, нужные указатели инициализиуются нужными функциями, остальные функцией-затычкой.

А switch действительно по порядку перебирает, причем if... else if ... else даже покомпактнее.
__________________
Чем бы дитя не тешилось - лишь бы не лазером...
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 22:29   93
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Я не пробовал код генерировать, тут и так ясно что он делает, и что мне не подходит. Мне не перебирать нужно, а сразу вычислить куда прыгнуть. Вот только ЯВУ прыгать не очень любят, и не приспособлены, в общем-то. Но как-то же делают подобные механизмы? Проверка правописания, автозамена, вод текста Т9 и прочие подобные огромные базы, требования к скорости работы которых не мене огромны...
Цитата:
Посмотреть сообщение Сообщение от AVSel :
Сделать массив указателей на функции, нужные указатели инициализиуются нужными функциями, остальные функцией-затычкой.
Не понял, можно пример? Массив указателей - запросто в ассемблере (там вообще всё запросто, пока дело не доходит до возни с ОЗУ и знаковой арифметикой), но я с самого начала в Си пробовал прыгать так - что-то не очень красиво получается, да и не мене костыльно за обработку прерываний получается...
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 21.12.2011, 22:52   94
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от INFERION :
Я не пробовал код генерировать, тут и так ясно что он делает, и что мне не подходит
switch не обязан перебирать все варианты. Ты сначала посмотри что он реально генерирует, а потом уже решай, подходит он тебе или нет. Для некоторых типов МК он вполне сможет сгенерировать это так, как тебе нужно.
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 22.12.2011, 12:32   95
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 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); 
}
В Си массив указателей можно делать и константным и переменным, но тут многое зависит от процессора и компилятора.
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 26.12.2011, 04:20   96
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для SviMik с помощью ICQ Отправить сообщение для SviMik с помощью MSN
По умолчанию

Я никак не могу заставить компилятор правильно обработать этот код. Пробовал по-всякому:
Код:
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 ; в конце у него заготовлено зацикливание
Я не знаю, почему компилятор считает, что buf_len достаточно проверить один раз и он не будет меняться. Будет! У меня прерывание для этого есть.
__________________
e-mail: euro@hobbi.tv
jabber: shop@hobbi.tv
Сообщение: http://forum.hobbi.tv/sendm...
SviMik вне форума   Ответить с цитированием Вверх
Старый 26.12.2011, 07:03   97
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для SviMik с помощью ICQ Отправить сообщение для SviMik с помощью MSN
По умолчанию

Выкрутился, убрав оптимизацию для этой функции:
Код:
void rbuf_write(unsigned char d) __attribute__((optimize(0)));
Но функция стала большой и медленной...

Другой вариант - переписать это место на ассемблере. Но это некрасиво.
Код:
asm volatile(
"lds	r25, buf_len\n"
"cpi	r25, 0x7F\n"
"brcc	.-8\n"
);
Тем более, я не знаю как правильно... Здесь R25 я взял наугад.
SviMik вне форума   Ответить с цитированием Вверх
Старый 26.12.2011, 07:45   98
lasers_ArtDen
Завсегдатай Фонарёвки
 
Аватар для lasers_ArtDen
 
Регистрация: 17.02.2010
Последняя активность: 30.01.2016 13:11
Сообщений: 831
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от SviMik :
Я не знаю, почему компилятор считает, что buf_len достаточно проверить один раз и он не будет меняться. Будет! У меня прерывание для этого есть.
volatile для buf_len не забыл?
lasers_ArtDen вне форума   Ответить с цитированием Вверх
Старый 26.12.2011, 20:28   99
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

Отправить сообщение для SviMik с помощью ICQ Отправить сообщение для SviMik с помощью MSN
По умолчанию

Естественно забыл
Зато теперь точно понял, для чего он нужен.
SviMik вне форума   Ответить с цитированием Вверх
Старый 23.02.2012, 12:58   100
us5mch
Лазеростроитель
 
Регистрация: 23.02.2012
Последняя активность: 24.02.2012 11:43
Сообщений: 2
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

День добрый. Ещё один вопрос по прерываниям. Вот к примеру программа только что ушла на задержку типа delay_ms(8000), в этот момент работает прерывание к примеру INT0, после которого нужно резко уйти в другую часть программы, ну выключить что-то, а мы ещё находимся в подпрограмме delay_ms и ждать нужно пока она окончится, как резко прекратить подпрограмму и выполнить хотя бы следующую команду?
us5mch вне форума   Ответить с цитированием Вверх
Ответ  Создать новую тему
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск





Copyright ©2007 - 2024, FONAREVKA.RU

Powered by vBulletin®
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd. Перевод: zCarot

Правила форума | Отказ от ответственности

Время генерации страницы 0.11502 секунды с 17 запросами