#1 2018-06-29 13:45:04

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Макроопределения для портов.

#define out1_on PORTA &=~(1UL<<0);               
#define out2_on PORTA &=~(1UL<<1); 
#define out3_on PORTA &=~(1UL<<2);   
#define out4_on PORTA &=~(1UL<<4);      
#define out5_on PORTA &=~(1UL<<3);    
#define out6_on PORTA &=~(1UL<<5);    
#define out7_on PORTA &=~(1UL<<6);  
#define out8_on PORTA &=~(1UL<<7);   
#define out9_on PORTG &=~(1UL<<2);    
#define out10_on PORTC &=~(1UL<<7);    
#define out11_on PORTC &=~(1UL<<6);      
#define out12_on PORTC &=~(1UL<<5);     
#define out13_on PORTC &=~(1UL<<4);      
#define out14_on PORTC &=~(1UL<<3);     
#define out15_on PORTC &=~(1UL<<2);     
#define out16_on PORTC &=~(1UL<<1);  
#define out17_on PORTC &=~(1UL<<0);    
#define out18_on PORTG &=~(1UL<<0);    
#define out19_on PORTG &=~(1UL<<1);   
#define out20_on PORTD &=~(1UL<<7);

Всем привет, помогите "запихнуть" эти макроопределения в массив, структуру или смесь что бы можно было работать как с массивом. Спасибо. Я написал макроопределение таким образом:

#define out_on(x) PORTC &=~(1UL << port_out[x]);

но порты то разные. sad

Неактивний

#2 2018-06-29 14:12:08

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

Если вам нужно адресовать порты по переменной то одними макросами вы это не сделаете, нужно что-то вроде этого:

void out_on(uint8_t n)
{
        *pin[n].port &= pin[n].bitmask;
}

Неактивний

#3 2018-06-29 17:23:19

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

У меня это пришло из программы управление сдвиговым регистром, при помощи 32 битной переменной я мог управлять 4 микросхемами.
Передовая в функцию которая вызывалась по таймеру номер бита и "номер операции" я мог управлять "портами". Но тут все по другому. Неужели нет ни чего такого что бы с моими портами вывода можно было работать также. Или подскажите как передавать и хранить эти макроопределения в массиве neutral
uint32_t out_shift = 0;
uint8_t Bufer_set_res[32];

#define Out_on(x) out_shift |=(1UL << x)
#define Out_off(x) out_shift &=~ (1UL << x)

void on_off(uint8_t bit_n, uint8_t set_res)
{
if(set_res == 0)
  out_shift &= ~(1UL << Bufer_bit[Count_t1]);  // сброс.
else if(set_res == 1)                 
  out_shift |= (1UL << Bufer_bit[Count_t1]);      // установка бита.
else ifset_res == 2)               
  out_shift ^= (1UL << Bufer_bit[Count_t1]);     // инверсия бита.
}

Неактивний

#4 2018-06-29 17:27:35

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

Вячеслав Азаров пише:

Если вам нужно адресовать порты по переменной то одними макросами вы это не сделаете, нужно что-то вроде этого:

void out_on(uint8_t n)
{
        *pin[n].port &= pin[n].bitmask;
}

Здесь у вас используется массив и структура? В который нужно поместить номер порта а в структуру его название?

Остання редакція goodspeedmen (2018-06-29 17:30:36)

Неактивний

#5 2018-06-29 17:28:50

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

Макроопределения в массиве хранить невозможно.

Неактивний

#6 2018-06-29 17:38:37

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

goodspeedmen пише:

Здесь у вас используется массив и структура? В который нужно поместить номер порта а в структуру его название?

Массив структур. Указатель на порт, и маску бита порта. Я думаю вы сами сможете описать массив констант. Чем вас не устраивает digitalWrite(..) из Ардуино?

Неактивний

#7 2018-06-29 18:14:50

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

Вячеслав Азаров пише:
goodspeedmen пише:

Здесь у вас используется массив и структура? В который нужно поместить номер порта а в структуру его название?

Массив структур. Указатель на порт, и маску бита порта. Я думаю вы сами сможете описать массив констант. Чем вас не устраивает digitalWrite(..) из Ардуино?

Потому что это не ардуино. Напишите пример плиз.

Неактивний

#8 2018-06-29 18:33:24

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

В русском языке есть слово пожалуйста а в украинском будь ласка.

const struct {
      __IO uint8_t * port;
      uint8_t bitmask;
}
   pin[] = {{&PORTA, 0xXX}, ...};

Что-то вроде этого. Смотрите в заголовочных файлах точный тип порта.

Остання редакція Вячеслав Азаров (2018-06-29 18:35:59)

Неактивний

#9 2018-06-29 19:36:40

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

char letter[] = {'q','A','A','A','A','A','A','A','A','G','C','C','C','C','C','C','C','C','G','G','D'};
uint8_t pin[] = {9,0,1,2,3,4,5,6,7,2,7,6,5,4,3,2,1,0,0,1,7};
#define out_on(x) port ## letter[x] &= ~(1u << pin[x]);
#define out_off(x) port ## letter[x] |= (1u << pin[x]);

Но как я понял компилятор объединяет 'portletter' как две строки а не как значение массива sad

Неактивний

#10 2018-06-29 19:47:51

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

goodspeedmen, вы методом тыка язык не освоите, слишком много тыкать придется. Нужно читать учебники, справочники и документацию на компилятор.

Неактивний

#11 2018-06-30 08:47:27

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

Решил проблему так, вместо битовой операции был применен оператор switch. Конечно это не самое оригинальное решение но все же.

void port_on(uint8_t potr)
{
 switch(potr) 
	   {
        case 1: out1_on; break;
        case 2: out2_on; break;
        case 3: out3_on; break;
        case 4: out4_on; break;
        case 5: out5_on; break;
		case 6: out6_on; break;
        case 7: out7_on; break;
        case 8: out8_on; break;
        case 9: out9_on; break;
        case 10: out10_on; break;
        case 11: out11_on; break;
		case 12: out12_on; break;
        case 13: out13_on; break;
        case 14: out14_on; break;
        case 15: out15_on; break;
        case 16: out16_on; break;
        case 17: out17_on; break;
		case 18: out18_on; break;
        case 19: out19_on; break;
        case 20: out20_on; break;
       }	
}

void port_off(uint8_t potr)
{
 switch(potr) 
	   {
        case 1: out1_off; break;
        case 2: out2_off; break;
        case 3: out3_off; break;
        case 4: out4_off; break;
        case 5: out5_off; break;
		case 6: out6_off; break;
        case 7: out7_off; break;
        case 8: out8_off; break;
        case 9: out9_off; break;
        case 10: out10_off; break;
        case 11: out11_off; break;
		case 12: out12_off; break;
        case 13: out13_off; break;
        case 14: out14_off; break;
        case 15: out15_off; break;
        case 16: out16_off; break;
        case 17: out17_off; break;
		case 18: out18_off; break;
        case 19: out19_off; break;
        case 20: out20_off; break;
       }
}

Неактивний

#12 2018-06-30 11:05:27

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

Плохое решение. Оператор Switch будет выполнять все Case пока не найдет нужное. Эффективней что-то типа как Азаров предложил функцией. Еще лучше структуру с адресами массивов с портов с готовыми значениями что б оттранслировалось в команду с относительной адресацией. Тогда в две команды уложится.

Остання редакція Batu (2018-06-30 11:06:17)

Неактивний

#13 2018-06-30 12:03:22

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

Batu пише:

Плохое решение. ...

Да, если строго, но сейчас хорошие оптимизирующие компиляторы, с преобразованием алгоритмов, способны сами построить оптимальные вычислительные структуры для локальных вычислений. Например для оператора switch(.) может выполняться переход по таблице. Так что в принципе сойдет. Однако, лучше не надеяться на искусственный ум и записывать алгоритмы прямолинейно.

Неактивний

#14 2018-06-30 12:27:18

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

Вячеслав Азаров пише:
Batu пише:

Плохое решение. ...

Да, если строго, но сейчас хорошие оптимизирующие компиляторы, с преобразованием алгоритмов, способны сами построить оптимальные вычислительные структуры для локальных вычислений. Например для оператора switch(.) может выполняться переход по таблице. Так что в принципе сойдет. Однако, лучше не надеяться на искусственный ум и записывать алгоритмы прямолинейно.

Тут не получится построить переход по таблице. Операцию сравнения необходимо выполнять с разными значениями. Оптимизатор не сможет предусмотреть. Не знаю есть ли в этом языке перечислимые типы. Вот с ними можно и переход по таблице получить. Там оптимизатор поможет. А в общем случае,  надо понимать как работает транслятор и как выполняются команды. Я собственно, почему внимание обратил на этот пост, потому как есть идея реализации перечислимых типов без введения отдельного понятия а просто как любой тип данных представляющий массив. Кстати, определение алфавита именно так делается.. Ибо буквы (Letter) это массив объектов, а тип Mark это ссылка на этот массив. Ну, и Switch организован как массив (или группа) событий. Тогда еще один фокус можно реализовать. Отдельно идет определение переменной тип массива событий в которой хранится состояние, и отдельно Select - переход по этой переменной. Должно вкусно получиться.

Неактивний

#15 2018-06-30 13:08:30

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

Batu пише:

Тут не получится построить переход по таблице. Операцию сравнения необходимо выполнять с разными значениями. Оптимизатор не сможет предусмотреть. Не знаю есть ли в этом языке перечислимые типы. Вот с ними можно и переход по таблице получить. Там оптимизатор поможет. А в общем случае,  надо понимать как работает транслятор и как выполняются команды. ...

Бату, я не буду с вами спорить, а тем более, что либо доказывать. То, что я сказал я знаю точно. А что мне надо понимать, прошу вас мне не указывать. В AVR для этого используются комманды IJMP, ICALL. На псевдооде: goto on[x]!

Неактивний

#16 2018-06-30 13:44:23

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

Вячеслав Азаров пише:
Batu пише:

Тут не получится построить переход по таблице. Операцию сравнения необходимо выполнять с разными значениями. Оптимизатор не сможет предусмотреть. Не знаю есть ли в этом языке перечислимые типы. Вот с ними можно и переход по таблице получить. Там оптимизатор поможет. А в общем случае,  надо понимать как работает транслятор и как выполняются команды. ...

Бату, я не буду с вами спорить, а тем более, что либо доказывать. То, что я сказал я знаю точно. А что мне надо понимать, прошу вас мне не указывать. В AVR для этого используются комманды IJMP, ICALL. На псевдооде: goto on[x]!

И где ты увидел спор, доказательства или, тем более указания? С какого перепугу меня вообще должна интересовать твоя личность? Я говорю по теме. И если тебя интересует чего-то узнать, то прочитай. Хуже не будет. Команды IJMP, ICALL выполняют переход по косвенному адресу, а здесь нужна относительная адресация. И не переход, а чтение. Тогда можно реализовать предложенную задачу красиво. Для тех кому это интересно.
P.S. Если уберешь немного самолюбия с тобой будет легче общаться. Не переоценивай значение своей персоны. Как правило она мало кого интересует. От слова вообще. У меня было к тебе предложение, но ты не потянул. Что не мешает здесь общаться. С уважением!
P.P.S. Можно на ты. Я не гордый..

Остання редакція Batu (2018-06-30 13:46:06)

Неактивний

#17 2018-06-30 13:48:52

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

Batu пише:

...

Удачи.

Неактивний

#18 2018-06-30 16:32:05

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

Вячеслав Азаров пише:

В русском языке есть слово пожалуйста а в украинском будь ласка.

const struct {
      __IO uint8_t * port;
      uint8_t bitmask;
}
   pin[] = {{&PORTA, 0xXX}, ...};

Что-то вроде этого. Смотрите в заголовочных файлах точный тип порта.

__IO Что это такое?

Неактивний

#19 2018-06-30 16:50:35

goodspeedmen
Учасник
З https://discord.gg/6hbs98y
Зареєстрований: 2016-10-02
Повідомлень: 81

Re: Макроопределения для портов.

Batu пише:

Плохое решение. Оператор Switch будет выполнять все Case пока не найдет нужное. Эффективней что-то типа как Азаров предложил функцией. Еще лучше структуру с адресами массивов с портов с готовыми значениями что б оттранслировалось в команду с относительной адресацией. Тогда в две команды уложится.

Я согласен, что это не самое лучшее решение, у меня есть готовая отлаженная программа её просто нужно перенести на новый контроллер. Вы почему то думаете что я умею читать мысли:

const struct
 {  
  __IO uint8_t * port;
  uint8_t bitmask;
}
   pin[] = {{&PORTA, 0xXX}, ...};

Я не понял задумку... sad

Неактивний

#20 2018-06-30 17:14:22

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Макроопределения для портов.

goodspeedmen пише:

__IO Что это такое?

Это, обычно, макро-спецификатор класса памяти портов ввода, зависящий от архитектуры ЭВМ. Разберитесь как это делается в Ардуино. Для AVR, возможно, __IO определять не нужно. Смотрите файлы arduino-1.8.5/hardware/arduino/avr/variants/standard/pins_arduino.h и arduino-1.8.5/hardware/arduino/avr/cores/arduino/wiring_digital.c, а так же их заголовки.

Неактивний

#21 2018-06-30 17:41:58

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

goodspeedmen пише:

Я согласен, что это не самое лучшее решение, у меня есть готовая отлаженная программа её просто нужно перенести на новый контроллер. Вы почему то думаете что я умею читать мысли:

const struct
 {  
  __IO uint8_t * port;
  uint8_t bitmask;
}
   pin[] = {{&PORTA, 0xXX}, ...};

Я не понял задумку... sad

А она есть))

Неактивний

#22 2018-07-01 18:43:03

LynX
Учасник
Зареєстрований: 2018-04-19
Повідомлень: 71

Re: Макроопределения для портов.

Batu пише:

Плохое решение. Оператор Switch будет выполнять все Case пока не найдет нужное.

НЕТ, только не это

Оператор switch так не делает. Он делает двумя способами:
1. Если параметры идут числами подряд (0,1,2,3,4....) то строит матрицу переходов - массив с указателем для jump в нужное место. И это самый быстрый вариант.
2. Если параметры идут в разброс (0, 7, 128...) то строит бинарное дерево переходов. И это тоже очень быстро.

Ну так по крайней мере работают современные компиляторы типа gcc. И я это проверял лично смотря ассемблерный сгенерированый листинг, потому что такие утверждения сыпятся с регулярной завидностью и пахнут откровенным бредом.

Вот кто вам это говорит, покажите мне этого врага адекватного человечества? Погуглил. Похоже ноги у этого мифа растут из-за оператора break. И не понимания ассемблера/машинных инструкций. Break даже мешает просто сравнивать все подряд, из-за него бы наоборот пришлось бы дополнительные (несложные) ухищрения добавлять.

Остання редакція LynX (2018-07-01 19:00:57)

Неактивний

#23 2018-07-01 20:29:52

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

LynX пише:
Batu пише:

Плохое решение. Оператор Switch будет выполнять все Case пока не найдет нужное.

НЕТ, только не это

Оператор switch так не делает. Он делает двумя способами:
1. Если параметры идут числами подряд (0,1,2,3,4....) то строит матрицу переходов - массив с указателем для jump в нужное место. И это самый быстрый вариант.
2. Если параметры идут в разброс (0, 7, 128...) то строит бинарное дерево переходов. И это тоже очень быстро.

Ну так по крайней мере работают современные компиляторы типа gcc. И я это проверял лично смотря ассемблерный сгенерированый листинг, потому что такие утверждения сыпятся с регулярной завидностью и пахнут откровенным бредом.

Вот кто вам это говорит, покажите мне этого врага адекватного человечества? Погуглил. Похоже ноги у этого мифа растут из-за оператора break. И не понимания ассемблера/машинных инструкций. Break даже мешает просто сравнивать все подряд, из-за него бы наоборот пришлось бы дополнительные (несложные) ухищрения добавлять.

Зачем так много слов? Сделай такой кусок "Если параметры идут в разброс (0, 7, 12)" и покажи ассемблерный листинг.

Остання редакція Batu (2018-07-01 20:30:50)

Неактивний

#24 2018-07-01 21:02:23

LynX
Учасник
Зареєстрований: 2018-04-19
Повідомлень: 71

Re: Макроопределения для портов.

Потому что это не для Вас, а для юных падаванов которых еще можно спасти.
Код.

Остання редакція LynX (2018-07-01 21:03:58)

Неактивний

#25 2018-07-01 21:24:33

Batu
Учасник
З Харьков
Зареєстрований: 2017-11-08
Повідомлень: 301

Re: Макроопределения для портов.

LynX пише:

Потому что это не для Вас, а для юных падаванов которых еще можно спасти.
Код.

Хотел бы услышать мнение Азарова по поводу такой оптимизации. А для примера было бы достаточно и 3-х Case. Меня не переубедил. Такое решение все равно жопа для решения предложенной задачи. ИМХО

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму