Страница 3 из 4
Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 19:49:13
ARV
ds3ds3 писал(а):unsigned int arr = {1 , &a};
а так и не должно работать: вы пытаетесь присвоить числу нечто типа массива или структуры. в фигурных скобках - это либо массив, либо структура.
а правильно было бы так:
1. объявить тип для элемента меню
2. объявить массив из этих элементов
вот тогда можно будет все присваивать.
Код: Выделить всё
typedef struct{
char id;
char *ptr;
} my_struct; // это структура
char a, b, c; // это просто какие-то переменные
static my_struct arr[3] = {
{0, &a},
{1, &b},
{2, &c}
}; // это массив структур
Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 20:04:13
ds3ds3
Но ведь мы знаем что адрес переменной - это число из конечного диапазона, почему нельзя записать адрес?
Подскажите по вопросам 2, 3, пожалуйста.
Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 20:13:08
ARV
ds3ds3 писал(а):допустимо ли писать?
допустимо все, что не запрещено. но чем больше написано, тем легче запутаться. не комментируя необходимость менять один байт двухбайтной переменной через указатель на двухбайтную переменную, я лично так не делал бы.
я бы поступил ровно так же, как выше:
1. объявил бы нужный мне тип
2. объявил бы указатель на него
3. присвоил бы этоу указателю нужный адрес (с преобразованием к void*)
4. работал бы с моим указателем без всяких извращений
Код: Выделить всё
int var; // переменная
typedef struct{
unsigned char lo;
unsigned char hi;
} lohi_type; // типа лохи, да :)))
lohi_type *ptr = (void*)&var; // вот это мой указатель на ту самую переменную
ptr->lo = 1; // меняем только младший байт переменной
ну или как- то так.
только многие вам скажут, что мой подход платформозависим: дескать, не во всех платформах младший байт следует первым в многобайтных переменных... но мне на это наплевать: я работаю только с такими платформами, где младший байт идет впереди

Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 21:13:59
alex_
Чёто я понять не могу в чём весь сырбор, если нужно обращаться к младшим и старшим байтам двухбайтовой переменной, и если вы пишете именно на
mikroC, то там делается всё просто:
Код: Выделить всё
Example:
d = 0x5678;
tmp = Lo(d); // Equals 0x78
Lo(d) = 0xAA; // d equals 0x56AA
-------------------------------------------
d = 0x5678;
tmp = Hi(d); // Equals 0x56
Hi(d) = 0xAA; // d equals 0xAA78
Так же можно и обращаться и к 4х байтной переменной.
Так что читаем хелп к программе и не шлангуем

Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 21:23:23
ds3ds3
Хмм... Действительно... Спасибо.
А директива абсолют у вас работает как надо, без наложений?
Re: вопрос по mikroc
Добавлено: Пт ноя 25, 2016 22:08:58
alex_
А директива абсолют у вас работает как надо
Тут по подробнее, что за директива
Да и зачем привязываться к абсолютным значениям, мне не совсем понятна, есть же константы
А по поводу статического массива:
int array[10]; // объявили, можно тут же и значения присвоить если надо
t=array
; // обращение к элементу по индексу
Вродеж всё просто, или я чего то недопонял в ваших тонких реализуемых мотивах 
Re: вопрос по mikroc
Добавлено: Сб ноя 26, 2016 10:10:36
ds3ds3
Directive absolute specifies the starting address in RAM for a variable. If the variable is multi-byte, higher bytes will be stored at the consecutive locations.
Directive absolute is appended to declaration of a variable:
Код: Выделить всё
short x absolute 0x22;
// Variable x will occupy 1 byte at address 0x22
int y absolute 0x23;
// Variable y will occupy 2 bytes at addresses 0x23 and 0x24
Be careful when using the absolute directive, as you may overlap two variables by accident. For example:
Код: Выделить всё
char i absolute 0x33;
// Variable i will occupy 1 byte at address 0x33
long jjjj absolute 0x30;
// Variable will occupy 4 bytes at 0x30, 0x31, 0x32, 0x33; thus,
// changing i changes jjjj highest byte at the same time, and vice versa
Наложение тех что объявлены через абсолют при ошибке понятны, а вот прочие переменные накладываются на абсолютные.
А про массив... Я там выше пропустил const
Код: Выделить всё
char a = 10;
const unsigned int arr = {1 , &a};
p1 = *arr[1];
Если написать
p1 = arr[1], то получим адрес переменной а.
p1 = *arr[1], вызывает ошибку.
p1 = *((char*)arr[1]), получим содержимое переменной а через статический указатель.
Последнее вызывает сомнения в правильности написанного.
Re: вопрос по mikroc
Добавлено: Сб ноя 26, 2016 15:16:00
alex_
Ну теперь я начал понимать к чему вы клоните, я про абсолютные адреса переменных, но понять не могу для чего нужна такая жёсткая привязка. Допустим у нас есть массив 10, 50 да хоть 100 элементов, присвоили ему имя и обращаетесь к нему по имени и номеру(индексу) к конкретному элементу этого массива. Я никогда не задавался вопросом привязывать массив к определённому месту в оперативке, это же задача компилятора, да и язык С это язык высокого уровня, там такие мелочи обычно опускаются. По поводу жёсткой привязки это похоже на ход мыслей при написании на ассемблере.
По поводу массива, вы почему то его насильно пытаетесь склонить к структуре. Структура может в себе содержать поля с разными типами переменных и в том числе и адрес. А массив это энное количество однотипных элементов, т.е. если вы объявили тип int то все элементы в массиве будет по 2 байта и типа int. Можно конечно поместить в этот массив адреса, если они имеют размер 2 байта.
Пример массива:
int arr[10]={0,1,2,3,4,5,6,7,8,9};
Если же нужно передать значение в функцию то просто передаём адрес массива, опять же не важно где он находиться в оперативной памяти.
Код: Выделить всё
int k;
void fn(int *t)// какая то функция в которую передаётся указатель на переменную типа int
{
*t=3; //по адресу обращаемся к переменной
}
void main()
{
k=2;
fn(&k); //получаем адрес k и передаём его в функцию, так же можно и адрес массива
// здесь уже k=3
}
p1 = *arr[1], вызывает ошибку.
Ну всё логично, вы объявили массив как одномерный а пытаетесь обращаться как двухмерному массиву(одномерный массив это строка, а двухмерный это набор строк)
Объявление двухмерного массива:
int arr[2][3]={{1,2,3},{4,5,6}};
Или же:
char[3][12]={{"Понедельник"},{"Вторник"},{"Среда"}};
Re: вопрос по mikroc
Добавлено: Вт янв 10, 2017 10:54:59
ds3ds3
Всем привет.
static my_struct почему то слаживается в RAM, что может быть причиной?
Re: вопрос по mikroc
Добавлено: Вт янв 10, 2017 19:49:01
GARMIN
Попробуй static const my_struct.
Re: вопрос по mikroc
Добавлено: Чт фев 02, 2017 16:35:56
ds3ds3
А вот стёк в МК используется отдельно для основной программы и отдельно для прерываний? Или нельзя использовать call в прерываниях? Или MikroC учтёт вместе с сохранением контекста ещё и разные стёки?
Используется MikroC PRO for 8051, AT89C4051.
Заранее спасибо.
Re: вопрос по mikroc
Добавлено: Чт фев 02, 2017 16:59:45
Zhuk72
Стек (э), не стёк.
Вызывать ПП из прерывания можно. Каждый вызов сопровождается записью адреса возвращения в стек, последовательно. При возвращении из ПП так же последовательно из стека извлекаются эти адреса.
Re: вопрос по mikroc
Добавлено: Пт фев 03, 2017 05:58:08
ds3ds3
Спасибо.
А если нужно вызвать функцию только один раз, и то только для модульности и "красоты", то как можно заменить функцию и сэкономить память под стэк?
Есть вроде вариант с дефайном и символом "/" в конце строки, но придется много "/" добавлять.
Re: вопрос по mikroc
Добавлено: Пт фев 03, 2017 06:14:23
Zhuk72
Стек высвобождается при возврате из функции. Вы же не планируете сидеть в ней вечно, верно? Заняли одну (верхнюю) позицию в стеке, зашли в ПП, сделали свое дело, при выходе забрали адрес из стека. Но если вы из этой функции полезете в другую (ещё одна позиция), а из той потом в следующую и еще, и ещё, то, в зависимости от глубины стека конкретного МК, имеете шанс переполнить его, т.е. потерять самый нижний в стопке адрес возврата.
Re: вопрос по mikroc
Добавлено: Пт фев 03, 2017 06:21:29
ds3ds3
Да. Но у меня оперативки не хватает под стэк. Можно подсократить глубину. Есть функции вызываемые один раз. Нужно заменить их, оставив модульность и удобство. Какие бывают методы?
Re: вопрос по mikroc
Добавлено: Вт фев 07, 2017 02:51:24
ds3ds3
А знает кто-нибудь как MikroC вычисляет Max Stack Depth?

Здесь я ткнул ПП с наибольшей глубиной ("текущая") равной 6.
Как получается число 8?
Re: вопрос по mikroc
Добавлено: Вт фев 07, 2017 06:03:12
Zhuk72
Может в настройках проекта выставляется?
Re: вопрос по mikroc
Добавлено: Пт фев 10, 2017 05:35:47
ds3ds3
У меня почему-то требуется памяти под стэк на два байта больше чем рассчитано.
На PUSH - 1 байт, в прерывании T0 нужно 7 PUSH = 7 байт.
В основной программе 6 вложений, по 2 байта = 12 байт.
В прерывании 3 вложения + само прерывание = 8 байт.
Итого: 27 байт.
Если свободно 27 байт то не работает (снаружи вообще нет никакой активности), но если добавить еще 2 свободных байта то все работает.
Вопрос что я еще не учел?
P.S. а Протэус вообще не заморачивается что памяти всего 128 байт, если превысить лимит, то без проблем выделит еще.
Re: вопрос по mikroc
Добавлено: Пт фев 10, 2017 08:24:10
ARV
ds3ds3 писал(а):Вопрос что я еще не учел?
может быть еще 2 байта на
call main не учли?
Re: вопрос по mikroc
Добавлено: Чт мар 02, 2017 03:59:40
ds3ds3
https://web.archive.org/web/20160421205 ... s/8051.htm
Подскажите по скорости UART, что то не сходится.
В табличках написано что скорость 19,2 кГц соответствует 0FDh в 8 битном таймере при (1/11,059 МГц)*12 машинного цикла.
Т.е. таймер на 3 цикла = 3,26 мкс; а 19,2 кГц => 52,08 мкс весь период. 52,08/3,26 = 16 примерно.