Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 02.01.2009, 02:28  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию

Хоть что-то похожее на исходник.
А теперь о основных причинах неработоспособности.
Самая главная причина в попытке работать с портом ввода-вывода через приведение указателя на него к указателю на структуру. Порт это не просто адрес в памяти. Но даже если представить его таковым, то он по свойствам напоминает volatile переменную. Указатель же на порт таким свойством уже не обладает. Соответственно если Вы будете устанавливать, к примеру, последовательно два бита через такое приведение типа, то компилятор заоптимизирует это в ОДИН вывод в порт. Для внешних устройств такая логика несколько неожиданна. Для сборки того, что Вы выложили до этого я добавил
Код:
typedef	volatile struct
	{
	unsigned char b0		:1;
	unsigned char b1		:1;
	unsigned char b2		:1;
	unsigned char b3		:1;
	unsigned char b4		:1;
	unsigned char b5		:1;
	unsigned char b6		:1;
	unsigned char b7		:1;
	} bits;
Так конечно лучше, но тоже не в любом случае избавит от проблем. Пользуйтесь макросом GCC _BV или стандартными сишными конструкциями:
Код:
#define  LCD_E      2
#define  LCD_E_ON() PORTC |= (1‹‹LCD_E)

// далее в тексте
LCD_E_ON();
Еще одно уточнение - файлы исходного текста, с расширением c, не подключаются через инклюд! Это противоречит одному из основных принципов языка - раздельной компиляции. Подсоединяйте такой файл в проект средствами используемой IDE, либо через Makefile, если работаете из командной строки. Иначе в будущем будут вылезать неприятные проблемы. И уж тем более не включайте #include "xxx.c" в H файл.
Попробую собрать, о результатах отпишусь. Но Вы так и не сказали - в чем проблема? Без оптимизации работает в железе? Там задержки конечно раз в 100 подрастут, но индикатор вещь терпеливая, подождет
Реклама:
kison вне форума  
Непрочитано 02.01.2009, 03:59  
alberio
Гражданин KAZUS.RU
 
Аватар для alberio
 
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
alberio на пути к лучшему
По умолчанию

Спасибо за содержательный ответ, но боюсь, я не до конца его понял.
На счет инклудов *.с согласен на 100%
На счет порт - это не просто адрес памяти... какая еще особенность тут добавляется по сравнению с "обычным" регистром из области памяти общего назначения?В этом же месте я не понял про то, в чем проблема Обьясните, пожалуйста ...
P.S. До железа еще далеко... (но оно обязательно будет!!!)
__________________
Sex, Druggs, Rock&Roll
alberio вне форума  
Непрочитано 06.01.2009, 03:54  
Vovik57
Частый гость
 
Регистрация: 10.05.2007
Сообщений: 11
Сказал спасибо: 4
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
Vovik57 на пути к лучшему
По умолчанию

Я использую VMLAB+GCC и без оптимизации получаю асм страшный и ужастный настолько, что даже симулятор от некоторых его инструкций крутит пальцем у виска Переходя на 2-й уровень код (и асм) съёживается в 2 раза и становиться человеческим НО в отладчике 'пропадают' некоторые строки, что и понятно- оптимизация! ИМХО 'без опт' нужен только для отладки своей логики по шагам.
Vovik57 вне форума  
Непрочитано 25.03.2009, 19:36  
alberio
Гражданин KAZUS.RU
 
Аватар для alberio
 
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
alberio на пути к лучшему
По умолчанию

Это ужас.
Написал драйвер к клавиатуре. Алгоритм обычный - сканирование по линиям порта (по очереди) и в соответствии с тем, на каком "выходе" клавиатуры появился сигнал, делаю вывод. Ну ужас не в этом. Драйвер я написал, и без оптимизации все работает отлично. Но как только включаю хотя бы 1 уровень, не все кнопки определяются (точнее - половина).
Поглядел дизассемблер. Оптимизатор почему-то вырезает несколько положений "сканера" - и соответсвенно эти клавиши не работают...
Кто подскажет, почему и что делать - цены тому не будет
__________________
Sex, Druggs, Rock&Roll
alberio вне форума  
Непрочитано 25.03.2009, 20:13  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию

Сообщение от alberio
Кто подскажет, почему и что делать - цены тому не будет
Цены не будет точно - телепаты редко встречаются...
kison вне форума  
Непрочитано 25.03.2009, 20:55  
alberio
Гражданин KAZUS.RU
 
Аватар для alberio
 
Регистрация: 08.07.2006
Сообщений: 583
Сказал спасибо: 76
Сказали Спасибо 90 раз(а) в 66 сообщении(ях)
alberio на пути к лучшему
По умолчанию

Сори.

Прикрепленный файл: 3013875.rar
__________________
Sex, Druggs, Rock&Roll
alberio вне форума  
Непрочитано 25.03.2009, 22:55  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию

Мне честно говоря сегодня лень копать глубоко. Но на первый взгляд ничего вроде не выкинуто. Я просто ret-ы посчитал. Оптимизация Os.
Где криминал?
Код:
--- keyboard.c -----------------------------------------------------------------------------------
4:        {
+0000004E:   EF8F        SER     R24              Set Register
+0000004F:   BB8B        OUT     0x1B,R24         Out to I/O location
8:        	KEYDDR=0;
+00000050:   BA1A        OUT     0x1A,R1          Out to I/O location
10:       	SET_OUT(LINE_1);
+00000051:   98D8        CBI     0x1B,0           Clear bit in I/O register
+00000052:   9AD0        SBI     0x1A,0           Set bit in I/O register
11:       	portval=KEYPIN;
+00000053:   B389        IN      R24,0x19         In from I/O location
12:       	if(!(portval&(LINE_2)))
+00000054:   FD81        SBRC    R24,1            Skip if bit in register cleared
+00000055:   C003        RJMP    PC+0x0004        Relative jump
+00000056:   E383        LDI     R24,0x33         Load immediate
+00000057:   E090        LDI     R25,0x00         Load immediate
+00000058:   9508        RET                      Subroutine return
14:       	if(!(portval&(LINE_8)))
+00000059:   FD87        SBRC    R24,7            Skip if bit in register cleared
+0000005A:   C003        RJMP    PC+0x0004        Relative jump
+0000005B:   E283        LDI     R24,0x23         Load immediate
+0000005C:   E090        LDI     R25,0x00         Load immediate
+0000005D:   9508        RET                      Subroutine return
16:       	SET_ALL_IN;
+0000005E:   BA1A        OUT     0x1A,R1          Out to I/O location
18:       	SET_OUT(LINE_4);
+0000005F:   98DB        CBI     0x1B,3           Clear bit in I/O register
+00000060:   9AD3        SBI     0x1A,3           Set bit in I/O register
20:       	if(!(portval&(LINE_5)))
+00000061:   99CC        SBIC    0x19,4           Skip if bit in I/O register cleared
+00000062:   C003        RJMP    PC+0x0004        Relative jump
+00000063:   E386        LDI     R24,0x36         Load immediate
+00000064:   E090        LDI     R25,0x00         Load immediate
+00000065:   9508        RET                      Subroutine return
22:       	SET_ALL_IN;
+00000066:   BA1A        OUT     0x1A,R1          Out to I/O location
24:       	SET_OUT(LINE_3);
+00000067:   98DA        CBI     0x1B,2           Clear bit in I/O register
+00000068:   9AD2        SBI     0x1A,2           Set bit in I/O register
25:       	portval=KEYPIN;
+00000069:   B389        IN      R24,0x19         In from I/O location
26:       	if(!(portval&(LINE_2)))
+0000006A:   FD81        SBRC    R24,1            Skip if bit in register cleared
+0000006B:   C003        RJMP    PC+0x0004        Relative jump
+0000006C:   E382        LDI     R24,0x32         Load immediate
+0000006D:   E090        LDI     R25,0x00         Load immediate
+0000006E:   9508        RET                      Subroutine return
28:       	if(!(portval&(LINE_5)))
+0000006F:   FD84        SBRC    R24,4            Skip if bit in register cleared
+00000070:   C003        RJMP    PC+0x0004        Relative jump
+00000071:   E385        LDI     R24,0x35         Load immediate
+00000072:   E090        LDI     R25,0x00         Load immediate
+00000073:   9508        RET                      Subroutine return
30:       	SET_ALL_IN;
+00000074:   BA1A        OUT     0x1A,R1          Out to I/O location
32:       	SET_OUT(LINE_6);
+00000075:   98DD        CBI     0x1B,5           Clear bit in I/O register
+00000076:   9AD5        SBI     0x1A,5           Set bit in I/O register
33:       	portval=KEYPIN;
+00000077:   B329        IN      R18,0x19         In from I/O location
34:       	if(!(portval&(LINE_2)))
+00000078:   FD21        SBRC    R18,1            Skip if bit in register cleared
+00000079:   C003        RJMP    PC+0x0004        Relative jump
+0000007A:   E384        LDI     R24,0x34         Load immediate
+0000007B:   E090        LDI     R25,0x00         Load immediate
+0000007C:   9508        RET                      Subroutine return
36:       	if(!(portval&(LINE_8)))
+0000007D:   FD27        SBRC    R18,7            Skip if bit in register cleared
+0000007E:   C003        RJMP    PC+0x0004        Relative jump
+0000007F:   E387        LDI     R24,0x37         Load immediate
+00000080:   E090        LDI     R25,0x00         Load immediate
+00000081:   9508        RET                      Subroutine return
38:       	if(!(portval&(LINE_5)))
+00000082:   FD24        SBRC    R18,4            Skip if bit in register cleared
+00000083:   C003        RJMP    PC+0x0004        Relative jump
+00000084:   E388        LDI     R24,0x38         Load immediate
+00000085:   E090        LDI     R25,0x00         Load immediate
+00000086:   9508        RET                      Subroutine return
40:       	if(!(portval&(LINE_7)))
+00000087:   FD26        SBRC    R18,6            Skip if bit in register cleared
+00000088:   C003        RJMP    PC+0x0004        Relative jump
+00000089:   E389        LDI     R24,0x39         Load immediate
+0000008A:   E090        LDI     R25,0x00         Load immediate
+0000008B:   9508        RET                      Subroutine return
42:       	SET_ALL_IN;
+0000008C:   BA1A        OUT     0x1A,R1          Out to I/O location
44:       	SET_OUT(LINE_2);
+0000008D:   98D9        CBI     0x1B,1           Clear bit in I/O register
+0000008E:   9AD1        SBI     0x1A,1           Set bit in I/O register
45:       	portval=KEYPIN;
+0000008F:   B389        IN      R24,0x19         In from I/O location
46:       	if(!(portval&(LINE_5)))
+00000090:   FD84        SBRC    R24,4            Skip if bit in register cleared
+00000091:   C003        RJMP    PC+0x0004        Relative jump
+00000092:   E381        LDI     R24,0x31         Load immediate
+00000093:   E090        LDI     R25,0x00         Load immediate
+00000094:   9508        RET                      Subroutine return
48:       	if(!(portval&(LINE_8)))
+00000095:   FD87        SBRC    R24,7            Skip if bit in register cleared
+00000096:   C003        RJMP    PC+0x0004        Relative jump
+00000097:   E380        LDI     R24,0x30         Load immediate
+00000098:   E090        LDI     R25,0x00         Load immediate
+00000099:   9508        RET                      Subroutine return
50:       	SET_ALL_IN;
+0000009A:   BA1A        OUT     0x1A,R1          Out to I/O location
52:       	SET_OUT(LINE_8);
+0000009B:   98DF        CBI     0x1B,7           Clear bit in I/O register
+0000009C:   9AD7        SBI     0x1A,7           Set bit in I/O register
54:       	if(!(portval&(LINE_7)))
+0000009D:   99CE        SBIC    0x19,6           Skip if bit in I/O register cleared
+0000009E:   C003        RJMP    PC+0x0004        Relative jump
+0000009F:   E28A        LDI     R24,0x2A         Load immediate
+000000A0:   E090        LDI     R25,0x00         Load immediate
+000000A1:   9508        RET                      Subroutine return
56:       	SET_ALL_IN;
+000000A2:   BA1A        OUT     0x1A,R1          Out to I/O location
+000000A3:   E080        LDI     R24,0x00         Load immediate
+000000A4:   E090        LDI     R25,0x00         Load immediate
59:       }
kison вне форума  
Непрочитано 26.03.2009, 21:55  
SwanSwan
Супер-модератор
 
Аватар для SwanSwan
 
Регистрация: 12.04.2007
Адрес: Урал
Сообщений: 2,459
Сказал спасибо: 1,463
Сказали Спасибо 6,183 раз(а) в 1,468 сообщении(ях)
SwanSwan на пути к лучшему
По умолчанию

Цитата:
Еще одно уточнение - файлы исходного текста, с расширением c, не подключаются через инклюд! Это противоречит одному из основных принципов языка - раздельной компиляции. Подсоединяйте такой файл в проект средствами используемой IDE, либо через Makefile, если работаете из командной строки. Иначе в будущем будут вылезать неприятные проблемы.
Уважаемый Kison! Можно поподробнее объяснить почему не рекомендуете файлы х.с подключать через инклюд? Какие проблемы это может вызвать? И еще, в чем принципиальная разница между х.с и х.h? Нельзя ли х.с (кроме main)сохранить и использовать в дальнейшем с расширением h? И наоборот?
SwanSwan вне форума  
Непрочитано 27.03.2009, 15:19  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию

Сообщение от SwanSwan
Уважаемый Kison! Можно поподробнее объяснить почему не рекомендуете файлы х.с подключать через инклюд? Какие проблемы это может вызвать? И еще, в чем принципиальная разница между х.с и х.h? Нельзя ли х.с (кроме main)сохранить и использовать в дальнейшем с расширением h? И наоборот?
Можно конечно. Разделение на с и h файлы условно. Сделано это не для компилятора, а для удобства программиста. Смысл этого в разбиении программы на функционально законченные модули. Т.е. внутри модуля содержатся данные и методы их обработки, упрощенный аналог класса в С++. Один раз создав/отладив такой автономный модуль, в дальнейшем просто включаем его в другие проекты. Удобно? Несомненно.
Но сам по себе модуль бесполезен. Нам нужно дать доступ к его функциям и данным из других модулей. Вот для этого и придуман h файл - интерфейсный или заголовочный. Если в самом модуле находятся объявления переменных и определения функций, т.е. то, что приводит к реальному выделению памяти, то в интерфейсном находятся только их описания. Так как реального выделения памяти не происходит, то h файлы могут подключаться куда угодно и сколько угодно раз. Они в общем случае нужны для контроля компилятором типов переменных и параметров функций. А вот сам модуль (с файл) должен быть только один.
Основное различие между с и h файлами в том, что первый требует выделения памяти под переменные и функции, а второй нет.
Можно конечно и через include подключить все модули в один с файл. Приведет это к тому, что препроцессор свалит в него весь исходник оптом. И именно его и будет обрабатывать компилятор. При отладке по исходному тексту именно по этому сборному файлу и придется вести отладку. При достаточно большом проекте этот файл может стать в несколько тысяч строк. И еще момент - компилятор будет всегда обрабатывать весь этот файл целиком. Сборка некоторых проектов может занимать 20 минут и более. При раздельной компиляции заново компилируется только то, что изменилось с момента предыдущей. А при написании/отладке этот процесс повторяется многократно. Изменили функцию в одном модуле - перекомпилируется только он. Вместо 20 минут копиляция займет 10 секунд. Для маленьких проектов(AVR) время полной сборки небольшое, но лучше сразу привыкнуть делать правильно. Это если есть цель расти профессионально. Перестроить навыки намного сложней, чем изначально приобрести правильные.
Вторая функция h файла - дать модулю доступ к библиотечным функциям. Библиотеки - такие же модули! Они хранятся обычно в виде откомпилированных заранее объектников. Для сокращения времени сборки.
Вот еще пример показательный. Допустим проект из трех модулей - main.c, a.c, b.c. Функции из модуля а вызывают функции из b и наоборот. При отсутствии заголовочных файлов и подключения модулей в main.c через include встает вопрос, какой из файлов a или b подключать первым. Можно выкрутиться из этого добавив в a.c описание функций из b.c и наоборот. Но представим ситуацию - мы изменили параметр функции в a.c. Нам придется изменить и описание в b.c. На первый взгляд ничего страшного. Но что если модулей больше, например 30. И все они пользуются этой функцией из a.c. Придется 30 раз править описание измененной функции. Если же делать правильно, то достаточно изменить только одно описание - в h файле. В программе часто встречаются перекрестные связи между модулями, использование заголовочных файлов избавляет от рутинной работы - правки кучи модулей при изменении в одном.
Да, оказывается трудно рассказать очевидное
Слишком много букв писать нужно. Вот тут почитайте - http://program.rin.ru/razdel/html/171.html
kison вне форума  
Эти 4 пользователя(ей) сказали Спасибо kison за это сообщение:
DemonK (26.02.2018), IOPA4 (26.02.2018), MaxiMuz79 (24.06.2011), Zoosman (27.02.2018)
Непрочитано 27.03.2009, 16:55  
SwanSwan
Супер-модератор
 
Аватар для SwanSwan
 
Регистрация: 12.04.2007
Адрес: Урал
Сообщений: 2,459
Сказал спасибо: 1,463
Сказали Спасибо 6,183 раз(а) в 1,468 сообщении(ях)
SwanSwan на пути к лучшему
По умолчанию

Спасибо за обстоятельный ответ. Но не понял, что изменится при подключении файлов a и b через IDE, а не через инклюд? Разве там не встанет вопрос об очередности подключений? И потом после компиляции отладку в любом случае будем вести по одному сборному файлу.
Ссылка выдает ошибку 404.
SwanSwan вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Оптимизация программы - бортовой компьютер на PIC16F73 Hellka Микроконтроллеры, АЦП, память и т.д 6 06.09.2010 17:04
gcc, iar, code vision AVR ? schotki Микроконтроллеры, АЦП, память и т.д 48 26.05.2009 20:15
AVR+GCC+jacOS DenisLeonidovich Микроконтроллеры, АЦП, память и т.д 3 24.07.2007 14:24
GCC AVR не работает printf("Hello word") Kabron Proteus, KiCAD и другие ECAD 8 03.03.2007 14:33
GNU GCC AVR вопрос по переменным.. Mozart Микроконтроллеры, АЦП, память и т.д 3 09.02.2007 20:00


Часовой пояс GMT +4, время: 20:00.


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