Страница 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< писал(а):Так можно ли как нибудь обозвать отдельную ножку порта?
Здравсвуйте. Можно поступить так:
А потом, например, при надобности настроить ножку порта на Лог.0 или на Лог.1 заместо номера бита в порту использовать PIN_0 или PIN_1:
Код: Выделить всё
sbi PORTB,PIN_0//установка ножки 0 в лог.1
cbi PORTB,PIN_1//установка ножки 1 в лог.0
Надеюсь, я Вас правильно понял...

Добавлено: Вс янв 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< писал(а):Програмный ШИМ.
вы зайдите ко мне на сайт, найдите и скачайте исходник к проекту "Электронная свеча" и посмотрите, как делается классическим способом многоканальный ШИМ. никакого массива пинов - упаси бог!