Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR организация данных
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Dim_ON
Недавно начал учиться программировать МК AVR семейство Mega, для этого использую WinAVR 20071221, тестирую в Proteuse 7 SP2. В чем собственно непонядки:
Проблемы с массивами:
Код
const unsigned char TabKey[4][4]  PROGMEM = \
       {{ '1', '2', '3', CTRL0 },\
        { '4', '5', '6', CTRL1 },\
        { '7', '8', '9', CTRL2 },\
        { '*', '0', '#', CTRL3 }};
//или
const u08  Tab[16] PROGMEM = \
{  33, 0xFA, 16, CTRL0, \
   48, 0xF9, 18, CTRL1, \
   56, 0xF8, 13, CTRL2, \
   69, 0xF7, 28, CTRL3 \
    };
//использую внешний индекс
extern u08             LastKey;
//но возращаются левые выборки
LastKey = Tab[LastKey]; //лажа

Объясните плиз использование static, extern, volatile переменных, функций. В каких случаях лучше объявить extern переменную, а где лучше использовать функцию возращающую значение static переменной. Про volatile я вообще ниче не знаю 05.gif
С массивами тоже туго... Что лучше, использовать одномерный массив или при необходимости можно создавать несколько размерностей. Как правильно их объявлять и определять, как обращаться к элементам массива. Операции с массивами: логические, арифметические, сортировка...
Структуры(struct)...Объявление, определение, битовые поля, использование массива в структуре и использование массива структур
Объединения(union)...
Перечесления(enum)...
Динамическое выделение памяти...malloc...free
Объявление и определение переменных внутри операторов... for(u08 i = 0; i < 10; i++){}
Перегрузка функций
Шаблоны функций

PS Хочется услышать советы бывалых при использовании тех или инных типов данных
PSS Хочется разобраться как организуется тот или иной тип на аппаратном уровне, что бы корректно использовать
PSSS Сильно не ругайтесь если это все 1000 раз обсуждалось, просто захотелось собрать все в одном месте, можно ссылки если не хотите по 150 раз переписывать одно и тоже. Ссылки на литературу по теме приветствуются
bloodden
Вся проблема в том, что у АВР память программ и память данных находятся на разных шинах, соответственно и команды для чтения/записи будут разными (это если грубо, точнее в даташит). По-моему надо подключить pgmspace.h или что-то вроде этого. Там хранятся подпрограммы для работы с памятью программ.
Dim_ON
Цитата(bloodden @ Jan 2 2008, 15:46) *
По-моему надо подключить pgmspace.h или что-то вроде этого. Там хранятся подпрограммы для работы с памятью программ.

подключал
Код
#include <avr/pgmspace.h>
const u08 static IndTab[] PROGMEM = \
{0b11000000, 0b11111001, 0b10100100, 0b10110000, \
  0b10011001, 0b10010010, 0b10000010, 0b11011000, \
  0b10000000, 0b10010000 \
};
//попытка через макросы
#define Read_IndCode(adata)     pgm_read_byte(&IndTab[adata])
#define Write_IndCode(adata)    IND_PORT_DATA = adata


массивы нехотят у меня работать никак

Так забыл написать, в листенги пишет:
*ABS*:00000000 main.c
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:2 *ABS*:0000003f __SREG__
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:3 *ABS*:0000003e __SP_H__
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:4 *ABS*:0000003d __SP_L__
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:5 *ABS*:00000000 __tmp_reg__
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:6 *ABS*:00000001 __zero_reg__
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:119 .text:00000000 main
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:356 .progmem.data:0000008d __c.1807
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:352 .progmem.data:00000075 __c.1809
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:348 .progmem.data:00000063 __c.1811
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:344 .progmem.data:0000005a __c.1813
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:340 .progmem.data:0000004a __c.1815
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:336 .progmem.data:00000037 __c.1817
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:332 .progmem.data:00000024 __c.1819
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:328 .progmem.data:00000010 __c.1821
C:\DOCUME~1\POPOV~1.HOM\LOCALS~1\Temp/ccAkJpIy.s:309 .progmem.data:00000000 Tab

это нормально? Мб в Makefile надо че дописать?
mdmitry
>PS Хочется услышать советы бывалых при использовании тех или инных типов данных
>PSS Хочется разобраться как организуется тот или иной тип на аппаратном уровне, что бы корректно использовать
>PSSS Сильно не ругайтесь если это все 1000 раз обсуждалось, просто захотелось собрать все в одном месте, можно >ссылки если не хотите по 150 раз переписывать одно и тоже. Ссылки на литературу по теме приветствуются

Просьба поискать на форуме ответы на Ваши вопросы (чтобы не задавать вопросы 150 раз smile.gif ).
По теме:
Для информации по квалификаторам памяти static, extern, volatile есть описание языка С (Керниган, Ричи).
Работа с flash описана в документации по компилятору (avr-libc)
В makefile необходимо указать компилируемые файлы. Примеры файлов были выложены на форуме для разных случаев сборки проектов.(Выкладывал Сергей Борщ, и я тоже)
Dim_ON
Микроконтроллеры AVR семейства MEGA имеют RISC (сокращенную систему команд) архитектуру ЦПУ, с Гарвардской организацией памяти. Что означает выполнение команд за 1 машинный цикл (кроме операций ветвлений и переходов) и раздельное адресное пространство памяти программ, ОЗУ и памяти данных.
Flash-ПЗУ хранит программу работы МК
ОЗУ - хранит данные используемые при работе программы, при сбросе данные пропадают? Стек тоже использует ОЗУ.
В адресное пространство памяти данных входят адреса регистров общего назначения, регистры состояния, регистры перефирийных устройств (регистры управления, регистры данных и т.д.). При сбросе данные пропадают?

Цитата(mdmitry @ Jan 2 2008, 17:10) *
Просьба поискать на форуме ответы на Ваши вопросы (чтобы не задавать вопросы 150 раз smile.gif ).
По теме:
Для информации по квалификаторам памяти static, extern, volatile есть описание языка С (Керниган, Ричи).
Работа с flash описана в документации по компилятору (avr-libc)
В makefile необходимо указать компилируемые файлы. Примеры файлов были выложены на форуме для разных случаев сборки проектов.(Выкладывал Сергей Борщ, и я тоже)

Не я первый начинающий...и надеюсь не я последний...
Не знаю какая у меня версия КР, или как я читаю, но про volatile я там не нашел(
Про flash поищу
В makefile я только указываю частоту, девайс и C source files. Мakefile брал из примеров в протеусе.
733259
Вам сначала руководство по C бы почитать, про массивы хотя бы.
Данные сами по себе не пропадают, но в avr-gcc их очищает стартовый код в секции init4(вроде), чтобы этого избежать нужно отредактировать скрипт компоновщика.
Но (ИМХО) Вам сначала бы руководство изучить.
zltigo
Цитата(Dim_ON @ Jan 2 2008, 15:34) *
Не я первый начинающий...и надеюсь не я последний...

Вот именно по этой причине прежде, чем задавать вопросы - ознакомьтесь с учебными материалами. Их специально професионалы писали. За нюансами - добро пожаловать в форум, ну с дежурными вопросами - пожалуйте к книгам. По любому, для начинающих существует отдельная ветка форума. Тему перенес.
Dim_ON
Цитата(zltigo @ Jan 2 2008, 17:44) *
Вот именно по этой причине прежде, чем задавать вопросы - ознакомьтесь с учебными материалами. Их специально професионалы писали. За нюансами - добро пожаловать в форум, ну с дежурными вопросами - пожалуйте к книгам. По любому, для начинающих существует отдельная ветка форума. Тему перенес.

Сори сразу незаметил этой ветки)
Давайте хотя бы тогда порекомендуем литературу:
Вольфтанг Трамперт "Измерение, управление и регулирование с помощью AVR микроконтроллеров"
А. В. Белов "Микроконтроллеры AVR в радиолюбительской практике"
А.В. Евстифеев "Микроконтроллеры AVR семейства Mega. Руководство пользователя"
А.В. Евстифеев "Микроконтроллеры AVR семейства Tiny и Mega фирмы Atmel"
А.В. Евстифеев "Микроконтроллеры AVR семейства Classic фирмы Atmel"
Д. Мортон "Микроконтроллеры AVR. Вводный курс"
В.Н. Баранов "Применение микроконтроллеров AVR: схемы, алгоритмы, программы"
М.С. Голубцов "Микроконтроллеры AVR: от простого к сложному"
Ю.А. Шпак "Программирование на языке С для AVR и PIC микроконтроллеров"

ПС Плиз скиньте примерчик работы с массивами в WinAVR
zltigo
Цитата(Dim_ON @ Jan 2 2008, 16:13) *
Давайте хотя бы тогда порекомендуем литературу:

Первое и самое главное "С" -просто С а не чернила для восьмого класса, например, второе издание Кернигана. Все нюансы ПРЕЖДЕ ВСЕГО в документации к компилятору.
Все остальное уже потом - перед сном быстренько почитать.
Цитата
ПС Плиз скиньте примерчик работы с массивами в WinAVR

Массивы это ПРОСТО С. Нюансы размещения массивов возьмите в примерах к компилятору.
Dmitry77
Приветики! С Новым Годом!!!
Посмотрите вот этот FAQ - возможно поможет....Это что касается самого WinAVR. Только есть досадный нюанс - текст на чисто немецком....

Файл
mdmitry
Цитата(Dmitry77 @ Jan 2 2008, 17:56) *
Приветики! С Новым Годом!!!
Посмотрите вот этот FAQ - возможно поможет....Это что касается самого WinAVR. Только есть досадный нюанс - текст на чисто немецком....

Файл

В документации к WinAvr есть FAQ, в том числе и про volatile, размещение данных во flash и другое написано, правда на английском. smile.gif
Dim_ON
Цитата(mdmitry @ Jan 2 2008, 21:09) *
В документации к WinAvr есть FAQ, в том числе и про volatile, размещение данных во flash и другое написано, правда на английском. smile.gif

Оо спасибо большое, я просто не знал про этот FAQ beer.gif
ПС мои массивы заработали smile.gif
Еще вот у меня перегрузка функций и объявление переменных в операторах не прокатывает.
А вот про volatile так и не нашел(
Сергей Борщ
Цитата(Dim_ON @ Jan 2 2008, 21:28) *
Еще вот у меня перегрузка функций и объявление переменных в операторах не прокатывает.
Телепатически можно предположить, что вы что-то не то пишете в исходном коде.
Dim_ON
Цитата(Сергей Борщ @ Jan 2 2008, 22:48) *
Телепатически можно предположить, что вы что-то не то пишете в исходном коде.

ну например:
Код
void motor_go(u08 speed);
void motor_go(u08 speed, u08 kol_shagov);
for(u08 i = 0; i < 10; i++){}

Еще интересует можно ли использовать конструкторы и деструкторы для структур и перегружать их
Dog Pawlowa
Цитата(Dim_ON @ Jan 2 2008, 23:56) *
ну например:
Код
void motor_go(u08 speed);
void motor_go(u08 speed, u08 kol_shagov);
for(u08 i = 0; i < 10; i++){}

Еще интересует можно ли использовать конструкторы и деструкторы для структур и перегружать их

Простите, Вы уже с массивами разобрались?
Не плодите дополнительных сущностей и вопросов, с декларированным Вами знанием языка 'C' за конструкторами и деструкторами через пару месяцев приходите.
А приведенном примере расскажите словами, что хотели сделать. Я не понимаю.
mdmitry
Цитата(Dim_ON @ Jan 2 2008, 22:28) *
А вот про volatile так и не нашел(

Кажется, первый вопрос в FAQ по avr-libc именно по volatile.
Dim_ON
Цитата(Dog Pawlowa @ Jan 3 2008, 00:47) *
Простите, Вы уже с массивами разобрались?
Не плодите дополнительных сущностей и вопросов, с декларированным Вами знанием языка 'C' за конструкторами и деструкторами через пару месяцев приходите.
А приведенном примере расскажите словами, что хотели сделать. Я не понимаю.

Да, с массивами разобрался...
Хочу использовать одно имя функции, с разным количеством аргументов, или разными типами аргументов
Хочу объявлять переменные не вначале функции, а внутри операторов
Код
switch(u08 temp = getchar())
{}

Но впринцепе, если перегрузка не работает, то про конструкторы вопрос отпадает

Цитата(mdmitry @ Jan 3 2008, 01:38) *
Кажется, первый вопрос в FAQ по avr-libc именно по volatile.

Код
uint8_t flag;
...
ISR(SOME_vect) {
  flag = 1;
}
...

        while (flag == 0) {
                ...
        }

Компилятор будет обычно получать доступ к флагу только однажды, и оптимизирует дальнейшие пути полного доступа, так как его code path analysis(анализ нахождения кода) показывает, что ничто в цикле не могло изменить, так или иначе, состояние флага. Сказать компилятору, что эта переменная могла быть изменена вне ее code path analysis(анализа нахождения кода) (т.е. изнутри обычного прерывания), переменная должна быть объявлена:
Код
volatile uint8_t flag;

Для этих целей я использовал extern переменные и все работает...в чем разница?
Заметил, что при объявлении extern переменных необходимо сразу их определять, иначе памяти под них не выделяется и в дальнейшем компилятор их не находит.
Цитата(Б. Керниган, Д. Ритчи @ Jan 3 2008, 01:38) *
Поскольку внешние(extern) переменные доступны всюду, их можно использовать в качестве связующих данных между функциями как альтернативу связей через аргументы и возвращаемые значения. Для любой функции внешняя переменная доступна по ее имени, если это имя было должным образом объявлено.
По умолчанию одинаковые внешние имена, используемые в разных файлах, относятся к одному и тому же внешнему объекту (функции). (В стандарте это называется редактированием внешних связей (линкованием) (external linkage).)
......
Если же программа расположена в нескольких исходных файлах и внешняя переменная определена в файле1, а используется в файле2 и файлеЗ, то объявления extern в файле2 и файлеЗ обязательны, поскольку необходимо указать, что во всех трех файлах функции обращаются к одной и той же внешней переменной. На практике обычно удобно собрать все объявления внешних переменных и функций в отдельный заголовочный файл.
Dog Pawlowa
Цитата(Dim_ON @ Jan 3 2008, 11:29) *
Для этих целей я использовал extern переменные и все работает...в чем разница?
Заметил, что при объявлении extern переменных необходимо сразу их определять, иначе памяти под них не выделяется и в дальнейшем компилятор их не находит.

extern - средство для удобного разделения проекта на модули (файлы), и volatile заменить не может.
Dim_ON
Цитата(Dog Pawlowa @ Jan 3 2008, 11:09) *
extern - средство для удобного разделения проекта на модули (файлы), и volatile заменить не может.

Я правильно Вас понял?
extern - область видимости весь проект(все файлы/модули), в которых они объявлены!
volatile - область видимости весь проект(все файлы/модули), без дополнительных объявлений. Специальная альтернатива extern(лучше подходит для применения!)
static - область видимости 1 файл(модуль).
ПС значит надо заканчивать extern-ичать и начинать volatile-ить smile.gif
Dog Pawlowa
Цитата(Dim_ON @ Jan 3 2008, 12:16) *
Я правильно Вас понял?
extern - область видимости весь проект(все файлы/модули)
volatile - область видимости весь проект(все файлы/модули). Специальная альтернатива extern(лучше подходит для применения)
static - область видимости 1 файл(модуль).

Нет, неправильно. Вы скачали хоть какой-нибудь учебник по С? Представьте, что Вы английский язык собрались изучать по советам на форуме. Теоретически возможно, но ...

Кстати, об английском.
extern (от external [англ] - внешний)- дает знать компилятору, что такая переменная где-то есть, и ее не нужно создавать.
volatile (англ - непостоянный, изменчивый) - дает знать компилятору, что переменная может измениться в любой момент
static ( что, тоже переводить?) - дает знать компилятору, что переменная будет находиться в статической области памяти, несмотря на то, что она может определена в функции (область видимости - это вторично).
Dim_ON
Цитата(Dog Pawlowa @ Jan 3 2008, 12:12) *
Нет, неправильно. Вы скачали хоть какой-нибудь учебник по С? Представьте, что Вы английский язык собрались изучать по советам на форуме. Теоретически возможно, но ...

Я знаю С/С++, но писал я консольные проги под ПК, поэтому и интересует как без лишнего ущерба (расхода аппаратных средств) перейти на программирование МК...Когда был студентом писал на асме под К580, КР1821ВМ85, 1816ВЕ48, 1816ВЕ51, но это больше были теоретические проекты. Щас же когда есть возможность моделировать и отлаживать в Протеусе, решил соеденить свои теоритеческие знания с практикой...
Цитата(Dog Pawlowa @ Jan 3 2008, 12:12) *
Кстати, об английском.
extern (от external [англ] - внешний)- дает знать компилятору, что такая переменная где-то есть, и ее не нужно создавать.
volatile (англ - непостоянный, изменчивый) - дает знать компилятору, что переменная может измениться в любой момент
static ( что, тоже переводить?) - дает знать компилятору, что переменная будет находиться в статической области памяти, несмотря на то, что она может определена в функции (область видимости - это вторично).

Да с анг, не очень), спасибо за пояснение
На счет первого поста, то вы меня наверное неправильно поняли, я хотел что бы Вы давали советы по использованию того или иного типа данных, а не обясняли что такое тип данных...
Dog Pawlowa
Цитата(Dim_ON @ Jan 3 2008, 13:29) *
Я знаю С/С++, но писал я консольные проги под ПК, поэтому и интересует как без лишнего ущерба (расхода аппаратных средств) перейти на программирование МК...
Да с анг, не очень), спасибо за пояснение
На счет первого поста, то вы меня наверное неправильно поняли, я хотел что бы Вы давали советы по использованию того или иного типа данных, а не обясняли что такое тип данных...

У, так Вы не начинающий вовсе, а знаете С/C++? Простите, неправильно понял.
С какой именно практикой Вы хотите соединить теоретические знания?
Протеус - это не практика, это скорее шаг в сторону, в придуманный мир.
Dim_ON
Цитата(Dog Pawlowa @ Jan 3 2008, 12:57) *
У, так Вы не начинающий вовсе, а знаете С/C++? Простите, неправильно понял.
С какой именно практикой Вы хотите соединить теоретические знания?
Протеус - это не практика, это скорее шаг в сторону, в придуманный мир.

Изучал, но это я неправильно выразился, не извеняйтесь
Мне хочется научиться правильному стилю программирования МК AVR, с использованием С и WinAVR.
(ИМХО) Протеус это как раз таки первый шаг к практике, так как программист может визуально представить и довести до рабочего сотояния, то что он написал. А так же неплохая практика работы с схематехническим редактором.
Но если есть отладочная плата, то канешна Протеус придуманный мир
Сергей Борщ
Цитата(Dim_ON @ Jan 3 2008, 09:29) *
Но впринцепе, если перегрузка не работает, то про конструкторы вопрос отпадает
Перегрузка работает. И конструкторы-деструкторы тоже. В том кусочке, который вы привели, я совершенно ничего не понял. Думаю, и компилятор тоже. Приведите конкретный пример, словами. Конкретную функцию и что конкретно вы от нее хотите. И послушайте совета Dog Pawlowa, прочтите книжку. Для начала по С (Керниган и Ритчи, "Язык программирования С, гугля дает кучи ссылок), потом по С++.
Dim_ON
Цитата(Сергей Борщ @ Jan 3 2008, 13:41) *
Перегрузка работает. И конструкторы-деструкторы тоже. В том кусочке, который вы привели, я совершенно ничего не понял. Думаю, и компилятор тоже. Приведите конкретный пример, словами. Конкретную функцию и что конкретно вы от нее хотите. И послушайте совета Dog Pawlowa, прочтите книжку. Для начала по С (Керниган и Ритчи, "Язык программирования С, гугля дает кучи ссылок), потом по С++.

Может и не такой выразительный
Код
void motor_go(u08 speed)
{
//в зависимости от speed устанавливаю частоту и количество пульсов ШИМ
}
void motor_go(u08 speed, u08 kol_shagov)
{
for(kol_shagov; kol_shagov != 0; kol_shagov--) motor_go(speed);
}
//ну или например
u08 Serch(u08 Index)
{
//поиск в первом массиве
}
u08 Serch(u16 Index)
{
//поиск во втором массиве
}
u08 Serch(u08 Index, u08 NewElm)
{
//поиск в первом массиве
//вернуть старое значение и записать новое
}

Мне то впринцепе не трудно самому переименовать функцию, но вот если конструкторы можно перегуржать то это хорошо
vooon
скорее всего вы компилируете Си компилятором а не С++.
посмотрите на вывод мейка, наверняка используется avr-gcc ,
а нужен avr-g++
Dim_ON
Цитата(vooon @ Jan 3 2008, 14:25) *
скорее всего вы компилируете Си компилятором а не С++.
посмотрите на вывод мейка, наверняка используется avr-gcc ,
а нужен avr-g++

Да, это значит в makefile надо заменить?
Код
# Define programs and commands.
SHELL = sh
CC = avr-gcc        // на avr-g++
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd

И после этого я смогу нормально перегружать, объявлять внутри операторов? А классы можно использовать?
vooon
да, тогда будут доступны все возможности С++
Dim_ON
Всем спасибо за подсказки a14.gif beer.gif
Пока вроде вопросы закончились
Сергей Борщ
Цитата(vooon @ Jan 3 2008, 13:25) *
наверняка используется avr-gcc ,
а нужен avr-g++
Достаточно дать комилируемому файлу расширение .cpp Это наиболее "прямой" метод. К сожалению, он не работает с плугином для AVRStudio - плугин не дает указать файл с расширением, отличным от .c или .h Тогда либо не пользоваться менюшками в AVRStudio указав external Makefile, либо явно указать использование С++ (но это тоже потребует external makefile):
Код
CC = avr-gcc  -x c++
или вписать -x c++ в опции компилятора. Это будет несколько "прямее", чем непосредственно вызывать g++.
mdmitry
Цитата(Сергей Борщ @ Jan 3 2008, 17:23) *
Достаточно дать комилируемому файлу расширение .cpp Это наиболее "прямой" метод. К сожалению, он не работает с плугином для AVRStudio - плугин не дает указать файл с расширением, отличным от .c или .h Тогда либо не пользоваться менюшками в AVRStudio указав external Makefile, либо явно указать использование С++ (но это тоже потребует external makefile):
Код
CC = avr-gcc  -x c++
или вписать -x c++ в опции компилятора. Это будет несколько "прямее", чем непосредственно вызывать g++.

Или отказаться от AVRStudio и пользоваться другую IDE, в которой Makefile может быть отредактирован программистом по своему усмотрению. Сам использую Eclipse.
Dim_ON
Подскажите плиз
Как в avr-gcc обращаться к младшему и старшему байту слова, без использования функций преобразования типов? Есть ли какие ниб специальные средства, типа:
Код
unsigned int KeyCod = 0xFFFF;
unsigned char KeyRow = Hbyte(KeyCod);
unsigned char KeyCol = Lbyte(KeyCod);
........
........
if(Hbyte(KeyCod) != KeyRow){....}
if(Lbyte(KeyCod) != KeyCol){....}
ROWPORT = Hbyte(KeyKod);
//или надо все же использовать функции преобразования?
unsigned int KeyCod = 0xFFFF;
unsigned char KeyRow = utoa(KeyCod>>8);
unsigned char KeyCol = utoa(KeyCod);
.......
Сергей Борщ
Цитата(Dim_ON @ Jan 5 2008, 17:12) *
Как в avr-gcc обращаться к младшему и старшему байту слова, без использования функций преобразования типов?
Код
uint16_t a;
uint8_t lo_byte, hi_byte;

void test()
{
    lo_byte = a & 0xFF;
    hi_byte = a >> 8;
}
И так в любом С.
Dim_ON
Цитата(Сергей Борщ @ Jan 5 2008, 20:13) *
Код
uint16_t a;
uint8_t lo_byte, hi_byte;

void test()
{
    lo_byte = a & 0xFF;
    hi_byte = a >> 8;
}
И так в любом С.

Я тоже думал на счет такого варианта, но не был уверен
Код
#define Lbyte(word)        (word & 0x00FF)
#define Hbyte(word)        (word>>8)        //((word>>8) & 0x00FF)
zltigo
Цитата(Сергей Борщ @ Jan 5 2008, 19:13) *
И так в любом С.

Ну если для определенности:
lo_byte = (uint8_t)a;
это правильно.
lo_byte = a;
это нормально.
Ну а
lo_byte = a & 0xFF;
явный перебор. Компияторы нынче хорошие - оптимизируют, конечно....
Dim_ON
Еще можно наверное вот так:
Код
uint16_t KeyCod;
uint8_t L_byte = (uint8_t)KeyCod;
uint8_t H_byte = (uint8_t)(KeyCod>>8);

меня опередили smile.gif
Сергей Борщ
Цитата(zltigo @ Jan 5 2008, 20:41) *
Ну а
lo_byte = a & 0xFF;
явный перебор. Компияторы нынче хорошие - оптимизируют, конечно....
Конечно оптимизируют. Но выдают предупреждение о присваивании большего типа меньшему. GCC, во всяком случае. Насчет варианта с явным приведением - не помню.
zltigo
Цитата(Сергей Борщ @ Jan 5 2008, 21:03) *
выдают предупреждение о присваивании большего типа меньшему. GCC, во всяком случае.

Не должно быть warnings. Относительно GCC/C++ - перепроверил 4.2.1 с полными ключами -Wall -Wextra как и положено сделал преобразование типов
lo_byte = a;
без предупреждений.
Сергей Борщ
Цитата(zltigo @ Jan 5 2008, 21:57) *
Не должно быть warnings.
Да, точно, "с прямым углом попутал". Это если константу присваивать и значащие биты отсекаются, тогда ругается:
Код
uint8_t lo, hi;
#define TEST 1234
int main()
{
    lo = TEST;
    hi = TEST >> 8;
}

main.cpp:10: warning: large integer implicitly truncated to unsigned type
Поэтому рефлекторно накладываю маску. накладывание маски компилятор тоже оптимизирует.
zltigo
Цитата(Сергей Борщ @ Jan 5 2008, 23:49) *
накладывание маски компилятор тоже оптимизирует.

Дык, я об этом я сразу и написал. Только вот о незначащие маски глаз спотыкается sad.gif.
Цитата
Поэтому рефлекторно накладываю маску

А я явное преобразование типа часто делаю для подчеркивания факта осознанности действия.
Dim_ON
Еще возник вопрос:
создаю в EEPROM-е массив структур типа
Код
struct MASS_DEF
{    
    u08 index;
    u08 oper;
    u08 kol;
};

static struct MASS_DEF massiv[100] EEMEM;

Могу ли я использовать запись типа
Код
        eeprom_write_byte(massiv[num].index, num);
        eeprom_write_byte(massiv[num].oper, OP0);
        eeprom_write_byte(massiv[num].kol, input_kol(temp));
// или надо
if(eeprom_is_ready())
{
    eeprom_write_byte(massiv[num].index, num);
    eeprom_write_byte(massiv[num].oper, OP0);
    eeprom_write_byte(massiv[num].kol, input_kol(temp));
}
else {do {/*ждем готовности*/} while (!eeprom_is_ready())}

или надо использовать eeprom_is_ready() для каждой команды eeprom_write_byte/eeprom_read_byte
Наверное eeprom_is_ready() используется для записи/чтения больших блоков
Сергей Борщ
Цитата(Dim_ON @ Jan 6 2008, 12:31) *
eeprom_write_byte(massiv[num].index, num);

eeprom_write_byte(&massiv[num].index, num);
Цитата(Dim_ON @ Jan 6 2008, 12:31) *
или надо использовать eeprom_is_ready() для каждой команды
Это описано в документации на avr-libc в комплекте WinAVR, в разделе <eeprom.h>.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.