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

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

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

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

F.A.Q. по выбору фонарей различных типов;
F.A.Q. по выбору аккумуляторов;
F.A.Q. по выбору зарядных устройств.
Ответ  Создать новую тему
Просмотров в теме 163621   Ответов в теме 119   Подписчиков на тему 0   Добавили в закладки 0
Опции темы Поиск в этой теме
Старый 16.11.2010, 22:22   41
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

А функция часом не inline определена?
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 22:25   42
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Код:
void spi_init(){
	/* Set MOSI and SCK output */
	PORTB = PORTB | (1<<3)|(1<<5);
	/* Enable SPI, Master, set clock rate fck/4 */
	SPCR = (1<<SPE)|(1<<MSTR);
}

void spi_send(char cData){
	/* Start transmission */
	SPDR = cData;
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF))){}
}
SviMik вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 22:36   43
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Странно. Такое поведение, характерно для функций, определенных как
inline void spi_send(char cData)
{
}

А определение ранее есть? т.е. такая строчка void spi_send(char cData);

Я правда с winavr не работал, всех его заморочек не знаю. Возможно функции без определения он вставляет как inline
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 22:45   44
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

C оптимизациями -O0 и -O1 он генерирует правильно, и функции вызывает через rcall.
С -O1 прошивка получается меньше, чем с -O2
С -O2, -O3 и -Os он начинает разбрасываться так, как я написал...

Цитата:
А определение ранее есть? т.е. такая строчка void spi_send(char cData);
нет

Код:
		spi_send(255);
		spi_send(255);
		spi_send(255);
		spi_send(255);
Результат:
Код:
void spi_send(char cData){
	/* Start transmission */
	SPDR = cData;
  78:	9f ef       	ldi	r25, 0xFF	; 255
  7a:	9e bd       	out	0x2e, r25	; 46
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF))){}
  7c:	0d b4       	in	r0, 0x2d	; 45
  7e:	07 fe       	sbrs	r0, 7
  80:	fd cf       	rjmp	.-6      	; 0x7c <lcd_clear+0x6>
	SPCR = (1<<SPE)|(1<<MSTR);
}

void spi_send(char cData){
	/* Start transmission */
	SPDR = cData;
  82:	9e bd       	out	0x2e, r25	; 46
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF))){}
  84:	0d b4       	in	r0, 0x2d	; 45
  86:	07 fe       	sbrs	r0, 7
  88:	fd cf       	rjmp	.-6      	; 0x84 <lcd_clear+0xe>
	SPCR = (1<<SPE)|(1<<MSTR);
}

void spi_send(char cData){
	/* Start transmission */
	SPDR = cData;
  8a:	9e bd       	out	0x2e, r25	; 46
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF))){}
  8c:	0d b4       	in	r0, 0x2d	; 45
  8e:	07 fe       	sbrs	r0, 7
  90:	fd cf       	rjmp	.-6      	; 0x8c <lcd_clear+0x16>
	SPCR = (1<<SPE)|(1<<MSTR);
}

void spi_send(char cData){
	/* Start transmission */
	SPDR = cData;
  92:	9e bd       	out	0x2e, r25	; 46
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF))){}
  94:	0d b4       	in	r0, 0x2d	; 45
  96:	07 fe       	sbrs	r0, 7
  98:	fd cf       	rjmp	.-6      	; 0x94 <lcd_clear+0x1e>
	spi_send(0b1000000); // Y (0...5)
	PORTB=PORTB | (1<<2); //LCD_D=1
}
Ну хоть додумался ldi r25, 0xFF только один раз сделать, а не все 4
SviMik вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 22:50   45
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Он не разбрасывается, а оптимизирует по скорости
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 22:56   46
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

А как ему обьяснить, что память у мк дорогая, это вам не комп с метрами и гектарами?
По идее, -Os должен оптимизировать для рамера. А он тоже "для скорости"...

Дождаться бы Gall... Любителя -O2 и пророчащего, что
Цитата:
оптимизация сишной простыни в три команды ассемблера
Да я на ассемблере в сто раз красивее оформлю
SviMik вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 23:04   47
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Так у тебя свободной памяти небось вагон, вот он скорость и выжимает
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 16.11.2010, 23:09   48
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Ну да, я только начал писать... Но я хочу с самого начала контролировать, что получается Потому как в итоге программа будет сложной - может даже и не влезть.
Или gcc так и будет выжимать скорость, пока петух не клюнет в обьём памяти?
SviMik вне форума   Ответить с цитированием Вверх
Старый 17.11.2010, 04:47   49
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Какой смысл тогда в выборе оптимизации, если компилятор всё равно делает по-своему?..
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 17.11.2010, 13:17   50
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

да хто-ж его знает, у меня ICCAVR - асбсолютно тупой послушный компилятор
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 17.11.2010, 14:52 Автор темы   51
Gall
Увлеченный
 
Аватар для Gall
 
Регистрация: 21.06.2010
Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Оптимизация -O2 - это оптимизация по скорости. Компилятор замечает, что вписать код функции прямо вместо ее вызова экономит пару тактов по сравнению с инструкцией CALL - и делает это.

Для микроконтроллеров лучше использовать опцию -Os, можно вместе с опцией -fcall-prologues.
Gall вне форума   Ответить с цитированием Вверх
Старый 17.11.2010, 14:56   52
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Цитата:
вписать код функции прямо вместо ее вызова экономит пару тактов по сравнению с инструкцией CALL - и делает это
Так -Os делает тоже самое!
Цитата:
можно вместе с опцией -fcall-prologues.
error: unrecognized command line option "-fcall-prologues"
Наверное -mcall-prologues

Нет, всё равно не помогает! -Os -mcall-prologues всё равно вписывает функции прямо в место вызова

Я так понимаю, надо более конкретно смотреть, какие оптимизации включают -Os и -O2, но не включает -O1...
SviMik вне форума   Ответить с цитированием Вверх
Старый 18.11.2010, 17:38 Автор темы   53
Gall
Увлеченный
 
Аватар для Gall
 
Регистрация: 21.06.2010
Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Цитата:
Посмотреть сообщение Сообщение от SviMik :
Ну да, я только начал писать... Но я хочу с самого начала контролировать, что получается Потому как в итоге программа будет сложной - может даже и не влезть.
Или gcc так и будет выжимать скорость, пока петух не клюнет в обьём памяти?
В принципе он умеет перекомпилировать всю программу иначе, когда она перестает влезать. Но поведение действительно очень странное. У меня создается впечатление, что где-то стоят другие опции.

Опция -Os НЕ дает "самый маленький" размер. Дело в том, что в большой программе вписывание функций инлайном в конечном итоге УМЕНЬШАЕТ общий размер кода. Это происходит потому, что при этом удается применить межпроцедурную оптимизацию - удалить лишние ldi, например. Написанный отдельно дубликат функции на этапе линковки будет вырезан из прошивки, если в программе не найдется ни одного call на него. Подавить его создание полностью можно, объявив функцию как static inline.

Если очень хочется, чтобы функции не инлайнились, есть опция -fno-inline.
Gall вне форума   Ответить с цитированием Вверх
Старый 18.11.2010, 17:44   54
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Помогло! Добавил -fno-inline, получилась прошивка 176 байт вместо 230
Цитата:
avr-gcc -mmcu=atmega48 -Wall -gdwarf-2 -std=gnu99 -Wextra -fgcse -fno-inline -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT gcc.o -MF dep/gcc.o.d -c ../gcc.c
SviMik вне форума   Ответить с цитированием Вверх
Старый 20.11.2010, 14:42   55
lasers_INFERION
Ветеран Фонарёвки
 
Аватар для lasers_INFERION
 
Регистрация: 15.02.2010
Последняя активность: 24.08.2019 11:36
Сообщений: 1362
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Переписываю и я сейчас программу на Си (RGB индикатор). Что-то меня эта оптимизация совсем не устраивает. Мало того что я не могу нормально выйти из прерывания (ему хочется сначала попрыгать туда-сюда), так ещё и обработчик меня серьёзно напугал. Вот что нужно было сделать:
Код:
ISR (TIM0_COMPA_vect)
{
	PORTA &= 0b11001111;
}
Вот как это выглядит у меня на ассемблере:
Код:
compA0:	in	R16, PORTA	;Потушить все каналы
	andi	R16, 0b11001111
	out	PORTA, R16
	reti
А вот что мне @#$% "оптимизатор" (опция -Qs):
Код:
ISR (TIM0_COMPA_vect)
{
  d2:	1f 92       	push	r1
  d4:	0f 92       	push	r0
  d6:	0f b6       	in	r0, 0x3f	; 63
  d8:	0f 92       	push	r0
  da:	11 24       	eor	r1, r1
  dc:	8f 93       	push	r24
	PORTA &= 0b11001111;
  de:	8b b3       	in	r24, 0x1b	; 27
  e0:	8f 7c       	andi	r24, 0xCF	; 207
  e2:	8b bb       	out	0x1b, r24	; 27
}
  e4:	8f 91       	pop	r24
  e6:	0f 90       	pop	r0
  e8:	0f be       	out	0x3f, r0	; 63
  ea:	0f 90       	pop	r0
  ec:	1f 90       	pop	r1
  ee:	18 95       	reti
Нет, меня такие медленные и огромные программы пугают. Я не знаю что он от меня хочет. С прерываниями тут работать очень трудно и возможности урезаны...
Ещё я объявил глобальные переменные, свободных регистров ещё вагон, а он полез в ОЗУ. Зачем?..

И это на фоне довольно неплохой оптимизации более сложных вещей. Слип он нормально мне написал. Правда я конфигурирую всё равно ковыряясь в регистрах, не доверяю этим библиотекам. Он они что творят...

Добавлено...
Код:
ISR (TIM0_COMPA_vect, ISR_NAKED)
{
	PORTA &= 0b11001111;
  d2:	8b b3       	in	r24, 0x1b	; 27
  d4:	8f 7c       	andi	r24, 0xCF	; 207
  d6:	8b bb       	out	0x1b, r24	; 27
	reti ();
  d8:	18 95       	reti
Уже лучше. Как я и говорил. Если компилятор делает что-то не так, скорее всего есть что-то, о чём программист забыл. Но блин, это же тёмные углы, в ассемблере такого нет! Неудивительно что нормально кодить на Си получается только у опытных программистов...

Добавлено...
Забросил затею. Мозги мои не заточены под логику этого языка. Программа разрастается в жуткие запутывающие условия. К ассемблеру уже привык. Очень послушный и понятный язык. Писать больше, но мозг кипит меньше. Может вернусь к затее когда понадобится написать большую программу, но пока что 2 килобайта ассемблерного кода меня пугают меньше Си...
lasers_INFERION вне форума   Ответить с цитированием Вверх
Старый 16.12.2010, 12:02   56
lasers_Ryazanec
Ветеран Фонарёвки
 
Регистрация: 04.05.2010
Последняя активность: 15.11.2019 11:47
Сообщений: 1409
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Осилил кучу флуда и расборок по поводу "чья кочка зеленее" и возник вопрос...
А где продолжение обучения?
К примеру я хотел бы увидеть как генерировать шым (на микроконтроллерах в которых он есть и так понятно а если нету, свою то функцию я напишу, но так как начинающий то не думаю что она будет оптимальной)
И еще хотелось бы научиться шаговым движком рулить...

в интернете примеры есть, но не всегда то что нужно или не всегда понятно. К тому же разные люди по разному объясняют.
lasers_Ryazanec вне форума   Ответить с цитированием Вверх
Старый 30.12.2010, 17:10 Автор темы   57
Gall
Увлеченный
 
Аватар для Gall
 
Регистрация: 21.06.2010
Последняя активность: 01.08.2015 23:26
Сообщений: 185
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

Генерирование ШИМ программно

Идея очень проста, поэтому достаточно написать пример кода.
Код:
while (1) {
    PORTB = 0xFF;
    delay(x);
    PORTB = 0x00;
    delay(k - x);
}
где x - то, что надо вывести, а k - некая константа. В примере ШИМ выводится на все 8 выводов порта B.

Функция delay может быть описана, например, так:
Код:
void delay(unsigned n) {
    for (unsigned i = 0; i < n; ++i) { asm volatile ("nop"); }
}
либо может быть использован аппаратный таймер (впрочем, если он есть, почему бы тогда не использовать просто его аппаратный ШИМ?)
Gall вне форума   Ответить с цитированием Вверх
Старый 30.12.2010, 18:25   58
SviMik
Завсегдатай Фонарёвки
 
Аватар для SviMik
 
Регистрация: 26.02.2010
Последняя активность: 18.08.2015 18:47
Сообщений: 810
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Gall Расскажи, как вообще в Си принято работать со строками. Для меня, после пхп, работать с "массивом букв" - это кошмар (если знаешь пхп - поймёшь всю суть моих страданий ).

Например, как можно короче записать этот код?
Условия:
1. не занимать больше флеша, чем этот пример
2. не занимать больше озу, чем этот пример
3. записать компактнее

char lcd[84] - промежуточный буффер, где находится полный текст, который должен выводиться на дисплей. В разных местах кода требуется менять лишь отдельные его фрагменты, например:

Код:
switch(input){
	case(INPUT_DISABLE):
	lcd[10]='[';
	lcd[11]='F';
	lcd[12]='M';
	lcd[13]='T';
	lcd[14]='R';
	lcd[15]=' ';
	lcd[16]='o';
	lcd[17]='f';
	lcd[18]='f';
	lcd[19]=']';
	return;
	case(INPUT_DIRECT):
	lcd[10]='[';
	lcd[11]='8';
	lcd[12]='M';
	lcd[13]='H';
	lcd[14]='z';
	lcd[15]=']';
	lcd[16]=' ';
	lcd[17]=' ';
	lcd[18]=' ';
	lcd[19]=' ';
	return;
	case(INPUT_LOGIC):
	lcd[10]='[';
	lcd[11]='8';
	lcd[12]='M';
	lcd[13]='H';
	lcd[14]='z';
	lcd[15]=' ';
	lcd[16]='L';
	lcd[17]='O';
	lcd[18]='G';
	lcd[19]=']';
	return;
	case(INPUT_DIV16):
	lcd[10]='[';
	lcd[11]='1';
	lcd[12]='2';
	lcd[13]='8';
	lcd[14]='M';
	lcd[15]='H';
	lcd[16]='z';
	lcd[17]=']';
	lcd[18]=' ';
	lcd[19]=' ';
	return;
	case(INPUT_DIV128):
	lcd[10]='[';
	lcd[11]='1';
	lcd[12]='.';
	lcd[13]='1';
	lcd[14]='G';
	lcd[15]='H';
	lcd[16]='z';
	lcd[17]=']';
	lcd[18]=' ';
	lcd[19]=' ';
	return;
}
Если так дальше пойдёт, это будет ужас...
SviMik вне форума   Ответить с цитированием Вверх
Старый 30.12.2010, 18:56   59
lasers_AVSel
Ветеран Фонарёвки
 
Аватар для lasers_AVSel
 
Регистрация: 15.02.2010
Последняя активность: 05.09.2022 18:18
Сообщений: 1090
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

По умолчанию

например так:
_flash char str[][11]={"строка 1", "вторая","и тд." };

.
case INPUT_DISABLE:
memcpy(lcd+10, str[0], 10);
....
case ...


на строки при таком описании уйдет на 1 байт больше, из-за нуля в конце, но удобнее писать. А код сократиться.
lasers_AVSel вне форума   Ответить с цитированием Вверх
Старый 30.12.2010, 20:48   60
lasers_Ryazanec
Ветеран Фонарёвки
 
Регистрация: 04.05.2010
Последняя активность: 15.11.2019 11:47
Сообщений: 1409
Сказал(а) спасибо: 0
Поблагодарили: 0 раз(а) в 0 сообщениях

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

Ну допустим аппаратный шим есть, но на 2х каналах а надо 4 разных на 4 при этом на всех 4х каналах должен шим быть разным, к примеру есть у меня 4 светодиодных линейки и яркость каждой мне нжно регулировать отдельно при этом в реальном времени в зависимости от определенных параметров, управление с компа или изменение входного сигнала - не суть важно.
Аппаратный это конечно хорошо, но наприпмер Mega8 должна регулировать 12 тью разными каналами (4 RGB линейки), как тут в реальном времени создавать и менять?

Аппаратный не рассматриваем. Вижу 2 варианта - либо внутренний таймер либо через коэффициент как было сказано выше считая такты, вот и подходим к тому что я только начинаю осваивать и неумею нормально работать с прерываниями, а опыт программирования - самоучка на дельфях, хотя примеры для образования в интернете были - их решал сегодня закупил детали для программатора и пару тинек, одну на индикатор RGB вторая для экспериментов, там вав плеер или USB клавиатурное западло (хобби оно на самом деле так называется - в поиске посмотри, незнаю как переименовать эту фразу по другому). Пока мучаю програмный эмулятор.
lasers_Ryazanec вне форума   Ответить с цитированием Вверх
Ответ  Создать новую тему





Copyright ©2007 - 2024, FONAREVKA.RU

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

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

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