Страница 1 из 1

Ножки MK как элементы массива

Добавлено: Вс янв 17, 2010 13:17:39
>TEHb<
Здравствуйте! Решил я тут знанятся массовым дёрганием ножек МК, но тут появилась проблема: для каждого пина приходится писать свою строчку с if, тоесть фактически перебирать все порты вручную! Есть ли какой-нибудь способ соотнести значения массива и ножки МК? Тоесть в инклуднике каждому порту даётся своё имя, к которому удобно обращатся из компилятора. Так можно ли как нибудь обозвать отдельную ножку порта? Мне фактически нужен двумерный массив битов (по 3 бита каждая строчка), при записи в который соответствующий логический уровень сразу бы появлялся на заданной ножке МК.

Добавлено: Вс янв 17, 2010 13:24:16
ARV
невозможно напрямую адресовать каждый пин порта отдельно.

поясните свою задачу - возможно, появится совет, как это красивее реализовать.

Re: Ножки MK как элементы массива

Добавлено: Вс янв 17, 2010 13:25:51
Savelek
>TEHb< писал(а):Так можно ли как нибудь обозвать отдельную ножку порта?
Здравсвуйте. Можно поступить так:

Код: Выделить всё

.EQU 	PIN_0=0
.EQU    PIN_1=1
А потом, например, при надобности настроить ножку порта на Лог.0 или на Лог.1 заместо номера бита в порту использовать PIN_0 или PIN_1:

Код: Выделить всё

sbi 	PORTB,PIN_0//установка ножки 0 в лог.1
cbi 	PORTB,PIN_1//установка ножки 1 в лог.0
Надеюсь, я Вас правильно понял... :roll:

Добавлено: Вс янв 17, 2010 13:43:19
>TEHb<
Не совсем. Адресовать ножку порта в отдльности не представляется проблемой (в CVAVR это PORTA.5 - 5-й бит порта А), хочется чтобы вместо PORTA.5 было например pins[3][1] - 3-я группа, первый пин (PORTA.7), а pins[3][2] уже PORTC.0 .

Добавлено: Вс янв 17, 2010 13:51:30
ARV
не знаю, как там в CVAVR можно сделать, но для WinAVR подобное можно сделать при помощи функции:

Код: Выделить всё

void change_bit(volatile uint8_t *port, uint8_t bitmask,uint8_t value){
   if(value)
      *port |= bitmask;
   else
      *port &= ~bitmask;
}

typedef struct{
   volatile uint8_t *P; // указатель на порт
   uint8_t B; // маска бита
} t_pin;

t_pin pin_array[3] = {
   {&PORTD, _BV(PD0)}, {&PORTD, _BV(PD1}, {&PORTC, _BV(PC5)} 
};

// в цикле устанавливаем все биты из массива pin_array
for(uint8_t i=0; i<3; i++){
   change_bit(pin_array[i].P, pin_array[i].B, 1);
}

Добавлено: Вс янв 17, 2010 16:30:53
andtech
Я использовал структуру, не совсем массив, но может поможет.

Делал дефайн (в WinAVR), кусочек от тудава:

Код: Выделить всё

typedef struct { char b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } bits;
// обязательно объявляем 8 бит, чтобы были правильно упорядочены
#define ON  1
#define OFF 0
#define PIN_CONFIG_IN 0
#define PIN_CONFIG_OUT 1
#define pinConfig(Port, Pin, InOut, PullUp) \
  ((bits*)&DDR##Port)->b##Pin = PIN_CONFIG_##InOut; \
  ((bits*)&PORT##Port)->b##Pin = PullUp

#define bitWrite(Port, Pin, Bit) \
  ((bits*)&PORT##Port)->b##Pin = Bit
#define bitRead(Port, Pin) \
  ((bits*)&PIN##Port)->b##Pin
В самой программе (для примера):

Код: Выделить всё

// инициализация
pinConfig(B, 0, OUT, OFF);
pinConfig(B, 1, IN, ON);
// в цикле
bitWrite(B, 0, bitRead(B, 1));

Добавлено: Вс янв 17, 2010 20:33:20
Neekeetos
>TEHb< писал(а):Не совсем. Адресовать ножку порта в отдльности не представляется проблемой (в CVAVR это PORTA.5 - 5-й бит порта А), хочется чтобы вместо PORTA.5 было например pins[3][1] - 3-я группа, первый пин (PORTA.7), а pins[3][2] уже PORTC.0 .
Ну а что вам мешает сделать дефайны на все элементы массива? я так понял что они меняться не будут по ходу пьесы. А если будут то так как вы описали не получится сделать, потому что в авр нету скажем непрерывных данных для PORT(ABCD) регистров - они находятся не в соседних IO адресах(и поэтому их нельзя объединить в одну структуру с битовыми данными), кроме того обращения к битам (те самые из которых компилятор генерит sbi,cbi и прочее нельзя сделать динамическими по определению. Самое разумное в таком случае это делать массив ссылок на структуру в которой для каждого элемента второго уровня ([x][y]) хранить адрес порта и маску и работать через функции - это уже предложили выше.

Добавлено: Вс янв 17, 2010 23:35:01
>TEHb<
Вся фишка в том, что на весь алгоритм у меня всего 256 процессорных циклов, потому с таблицами городить...... Вообще у меня пока написано для каждого бита по своему IF-у. Работает отлично, но как-то не красиво это, код не доставляет эстетического наслаждения. Даже компилятор на меня смотрит с немым укором, ну не могу я так! стыдно....

Добавлено: Пн янв 18, 2010 00:45:25
>TEHb<
С дефайнами не вышло, ибо надо перебирать их в цикле, а это уже далекооооо после препроцессора. Народ вообще знак "+" переопределяет, вот я и подумал... Ну хоть битики назвал красиво и понятно, и на том спасибо.

Добавлено: Пн янв 18, 2010 05:01:34
Кашпо
ну можно попробовать такой вариант

читаем порт (весь. все 8 бит). и логическими операциями AND, OR, XOR, NOT и пр. сдвигами получаем взведение или обнуление соответствующего бита. получившееся значение пишем обратно в порт.

извините, на языке программирования выразить не могу, т.к. в понедельник с утра ещё не проснулся. Просто мысль такая в голову пришла ;)

Добавлено: Пн янв 18, 2010 09:47:18
>TEHb<
Ненене, адресовать отдельный бит - запросто, а вот как закрепить его за элементом массива, надо в цикле перебирать.

Добавлено: Пн янв 18, 2010 10:31:12
ARV
ранее вам показали, как закрепить пин за элементом массива.

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

Добавлено: Пн янв 18, 2010 18:01:38
>TEHb<
Програмный ШИМ. В цикле ну несоизмеримо удобнее пребирать номера элементов чем ручками расписывать каждый пин, потому про медленность вы правильно думаете. Да и система получается масштабируемой и красивой.

Добавлено: Пн янв 18, 2010 18:32:41
Neekeetos
>TEHb< писал(а):Програмный ШИМ. В цикле ну несоизмеримо удобнее пребирать номера элементов чем ручками расписывать каждый пин, потому про медленность вы правильно думаете. Да и система получается масштабируемой и красивой.
Интересное представление о красоте, вроде пикассо. Мало того что эти биты никуда не уперлись потому что по факту каналы шима надо назначать а не выходы, кроме того порта на 4 шим можно сделать с частотой в районе 300к(я так делал уже :) ), что дает чуть больше килогерца период для 8 бит шимки, а если перебирать биты то можно забыть и про один порт.
Грубо говоря в основном прерывании можно для каждого канала проверять момент выключения (это делается двумя операторами на асме), результирующий бит задвигается во временный регистр. Потом несколько получившихся байт выводить в порты (это займет 0,0с).

Добавлено: Пн янв 18, 2010 19:42:14
ARV
>TEHb< писал(а):Програмный ШИМ.
вы зайдите ко мне на сайт, найдите и скачайте исходник к проекту "Электронная свеча" и посмотрите, как делается классическим способом многоканальный ШИМ. никакого массива пинов - упаси бог!