|
WinAVR организация данных, Вопросы начинающего |
|
|
|
Jan 2 2008, 11:17
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 28-09-07
Пользователь №: 30 914

|
Недавно начал учиться программировать МК 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 я вообще ниче не знаю С массивами тоже туго... Что лучше, использовать одномерный массив или при необходимости можно создавать несколько размерностей. Как правильно их объявлять и определять, как обращаться к элементам массива. Операции с массивами: логические, арифметические, сортировка... Структуры(struct)...Объявление, определение, битовые поля, использование массива в структуре и использование массива структур Объединения(union)... Перечесления(enum)... Динамическое выделение памяти...malloc...free Объявление и определение переменных внутри операторов... for(u08 i = 0; i < 10; i++){} Перегрузка функций Шаблоны функций PS Хочется услышать советы бывалых при использовании тех или инных типов данных PSS Хочется разобраться как организуется тот или иной тип на аппаратном уровне, что бы корректно использовать PSSS Сильно не ругайтесь если это все 1000 раз обсуждалось, просто захотелось собрать все в одном месте, можно ссылки если не хотите по 150 раз переписывать одно и тоже. Ссылки на литературу по теме приветствуются
|
|
|
|
3 страниц
< 1 2 3
|
 |
Ответов
(30 - 41)
|
Jan 3 2008, 21:46
|

Начинающий профессионал
    
Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648

|
Цитата(Сергей Борщ @ 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.
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Jan 5 2008, 15:12
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 28-09-07
Пользователь №: 30 914

|
Подскажите плиз Как в 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, 15:14
|
|
|
|
|
Jan 5 2008, 17:13
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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; } И так в любом С.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 5 2008, 17:18
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 28-09-07
Пользователь №: 30 914

|
Цитата(Сергей Борщ @ 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)
|
|
|
|
|
Jan 5 2008, 18:41
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jan 5 2008, 19:13)  И так в любом С. Ну если для определенности: lo_byte = (uint8_t)a; это правильно. lo_byte = a; это нормально. Ну а lo_byte = a & 0xFF; явный перебор. Компияторы нынче хорошие - оптимизируют, конечно....
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 5 2008, 18:43
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 28-09-07
Пользователь №: 30 914

|
Еще можно наверное вот так: Код uint16_t KeyCod; uint8_t L_byte = (uint8_t)KeyCod; uint8_t H_byte = (uint8_t)(KeyCod>>8); меня опередили
Сообщение отредактировал Dim_ON - Jan 5 2008, 18:44
|
|
|
|
|
Jan 5 2008, 19:57
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jan 5 2008, 21:03)  выдают предупреждение о присваивании большего типа меньшему. GCC, во всяком случае. Не должно быть warnings. Относительно GCC/C++ - перепроверил 4.2.1 с полными ключами -Wall -Wextra как и положено сделал преобразование типов lo_byte = a; без предупреждений.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 5 2008, 21:49
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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 Поэтому рефлекторно накладываю маску. накладывание маски компилятор тоже оптимизирует.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 5 2008, 22:17
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(Сергей Борщ @ Jan 5 2008, 23:49)  накладывание маски компилятор тоже оптимизирует. Дык, я об этом я сразу и написал. Только вот о незначащие маски глаз спотыкается  . Цитата Поэтому рефлекторно накладываю маску А я явное преобразование типа часто делаю для подчеркивания факта осознанности действия.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 6 2008, 10:31
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 28-09-07
Пользователь №: 30 914

|
Еще возник вопрос: создаю в 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, 11:30
|
|
|
|
|
Jan 6 2008, 12:47
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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>.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|