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

Работа с портами в функциях. Порт как аргемент для функции

Добавлено: Чт окт 17, 2013 18:50:01
ZiperRUS
Всем здравствуйте великодушно.
Пишу я вам в этот мерзопакостный вечер сейчас 19:47 мск с криком о помощи!!!
Столкнулся я с такой проблемой с таким недопонимаем своего любимого хобби.
В чём же дело можете вы задать вопрос мне , хорошо отвечаю суть вопроса суть моей тревоги вот в чём.

не могу я понять разобраться с использованием аббревиатур допустим( PORTB и PINB.5)
есть к примеру такая функция

void TestPort(port, pinb.5)
{
if(pinb.5)port=0;
else port=1;
}

как такое реализовать? то есть здесь в функцию передаётся два аргумента сам порт port-PORTB и для проверки пина порта на текущее состояние pinb.5-PINB.5
как передать в функцию такие аргументы для долнейщей рабы с ней в самой функции и для присвоения порту значений?
среда CodeVision

Помагите пожалуйста очень надо мне :)

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Чт окт 17, 2013 19:46:03
ploop
Вот до чего доводит использование CodeVision :)
Ваш pinb.5 в CodeVision - какой-то макрос, какой - смотрите.
Номер пина можно задать числом. Не обращая внимания на типы и прочее - что-то типа этого:

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

void TestPort(int port_in, int port_out, int pin)
{
if (port_in & (1<<pin))
  port_out=0;
  else port_out=1;
}

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 01:24:42
ZiperRUS
ploop писал(а):Вот до чего доводит использование CodeVision :)
Ваш pinb.5 в CodeVision - какой-то макрос, какой - смотрите.
Номер пина можно задать числом. Не обращая внимания на типы и прочее - что-то типа этого:

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

void TestPort(int port_in, int port_out, int pin)
{
if (port_in & (1<<pin))
  port_out=0;
  else port_out=1;
}



нееее не видел я там таких макросов для этих целей. Там есть хидер #include <tiny2313.h>
вот его часть

sfrb PINB=0x16;
sfrb DDRB=0x17;
sfrb PORTB=0x18;
sfrb PINA=0x19;
sfrb DDRA=0x1a;
sfrb PORTA=0x1b;
sfrb EECR=0x1c;
sfrb EEDR=0x1d;
sfrb EEAR=0x1e;
sfrb PCMSK=0x20;
sfrb WDTCR=0x21;
sfrb TCCR1C=0x22;
sfrb GTCCR=0x23;
sfrb ICR1L=0x24;
sfrb ICR1H=0x25;

объявления в нём.
Но как их использовать в коде программы??? :?

пробовал так для проверки

void TestPort(int PORTB.0)
{

}

компилятор ругается
Error:........: missing ',' :shock:

хотя на это молчит

void TestPort(int PORTB)
{

}

Так в чём же дело? друзья

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 06:40:42
ploop
Так в чём же дело? друзья

Мля, я же объяснил - PORTB - число, PORTB.1 -не число, это какая-то структура или макрос, знакомый только CVAVR. А вы его в параметр суёте.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 09:10:25
fzr400gr
А вы обьясните для начала задачу поконкретнее, а то немного не понятно что вы хотите сделать в вашей функции.
Если порт В у вас разделен на входы и выходы то проще обращатся к ним как к отдельным выводам.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 09:16:45
a_skr
ошибаетесь.
и PORTB.5 и PINB.5 - числа (по крайней мере, результатом обращения к таким записям является число).
мы же можем записать int a = PINB.5;
вот рабочий код:

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

#include <tiny2313.h>

void test(char* port, char pin)
{
  if(pin) *port |= 1;
  else *port &= ~1;
}

void main(void)
{
  DDRB = 1; // выход
  PORTB = 1<<5; // подтяжка
  while (1)
  {
    test(&PORTB, PINB.5);
  }
}

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 11:53:24
uk8amk
sfrb PORTB=0x18


вот рабочий код:

void test(char* port, char pin)
{
if(pin) *port |= 1;
else *port &= ~1;
}

test(&PORTB, PINB.5);


На мой взгляд было бы правильней:

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

void test(char* port, char pin)
{
  if(pin) *port |= (1<<pin);
  else *port &= ~(1<<pin);
}

test(&PORTB, 5);


Поскольку PINB.5 возвращает состояние бита порта.

Но вот тут мне не ясна одна деталь:

4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses.


Выходит надо писать так:

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

test(&(PORTB+0x20), 5);


???

А автор случаем не с ардуины слезть пытается?
Поскольку вроде бы там есть очень похожая digitalwrite(port, pin).

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 13:02:41
a_skr
На мой взгляд было бы правильней:
void test(char* port, char pin)
{
if(pin) *port |= (1<<pin);
else *port &= ~(1<<pin);
}
ерунда какая-то... ;)
вот рабочий код:
проверялся в протеусе.
Выходит надо писать так:
test(&(PORTB+0x20), 5);
компилятор умный:

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

; 0000 000F     test(&PORTB, PINB.5);
   LDI  R30,LOW(56) <- вот тут 0x38, а не 0x18
   ST   -Y,R30
   LDI  R30,0
   SBIC 0x16,5
   LDI  R30,1
   ST   -Y,R30
   RCALL _test

вообще, автор какой-то странный вопрос поставил.
все можно сделать проще и элегантней и правильней.
сформулируйте конечную цель - подскажем, как надо. ;)

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 13:06:46
ploop
ошибаетесь.
и PORTB.5 и PINB.5 - числа

Возможно.
Но что эти обозначения представляют из себя внутри? У меня просто нет cvavr чтобы проверить. Сам пишу под avr-gcc.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 13:29:43
a_skr
Сам я тоже под WinAVR сижу, просто, некоторым надо было написать программы - вот и поигрался с ним пару раз. И вот такие вопросы тоже мне интересны. Как там внутри CV это устроено - хз. Но он предоставляет доступ к регистрам портов до 1F по аналогии с битовыми полями размером в один бит в структурах. Называет их "bit selector":
The bit level access to the I/O registers can be also accomplished by using bit selectors appended after the name of the I/O register.
Because bit level access to I/O registers is done using the CBI, SBI, SBIC and SBIS instructions, the register address must be in the 0 to 1Fh range for sfrb and in the 0 to 1Eh range for sfrw.
Example:
sfrb PORTA=0x1b;
...
/* set bit 0 of I/O Port A as output */
DDRA.0=1;
/* set bit 1 of I/O Port A as input */
DDRA.1=0;

PS. так, что результат записи ioreg.n - это 1 или 0. при присваивании соответствующий бит будет установлен или сброшен. вполне себе числа ;)
PPS.
Но вот тут мне не ясна одна деталь:
Цитата:
4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses.
Выходит надо писать так:
Код:
test(&(PORTB+0x20), 5);
вот теперь понятно, что так писать не надо. в данном случае используются команды CBI, SBI, SBIC и SBIS, работающие с регистрами от 0 до 1F

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 14:13:55
ZiperRUS
Проснувшись сегодня утром и ВКЛ. комп был воодушевлён ответами. Всем спасибо за помощь. С таким прекраснейшим настроением я приступил к водным процедурам))))

fzr400gr писал(а):А вы обьясните для начала задачу поконкретнее, а то немного не понятно что вы хотите сделать в вашей функции.


Задача функции такая. Есть у меня две функции одинаковые они полностью отличаются только они как раз что используют разные PIN и PORT.
первая использует PIND.5 PIND.0 PINB.3 и PORTD.0
вторая использует PIND.0 PIND.5 PINB.4 и PORTD.5

одинаковые PINы используются в разных местах кода.
Так вот для начала я хочу эти две функции объединить в одну, оптимизировать а нужные PINы и PORTы передавать ей в качестве параметров при вызове. или вот думаю можно так реалировать смену PINов в самой функции по команде через параметр, вот как то так:

void TestPort(int command)
{
port; // здесь мы объявили переменные для порта и пина, но какой ставить тип переменных ?
pin;

if(command==1)
{
port = PORTB; // здесь мы присваиваем переменным номер порта и пина в зависимости от команды
pin = PINB.5;
}

if(pin)port=0; // работаем с переменными пора и пина
else port=1;

}

вот так тоже делать пришла идея но как?

Вообще это устройство у меня стоит в авто уже года три назад я его сам собрал. его назначение это управление стёклами (стеклоподъёмник) и закрывает он их автоматически при постановке на сигнализацию. У меня там две функции есть одна управляет закрытием водительского окна , другая закрытием пассажирского окна, они одинаковые различаются только работой с разными пинами и портом. Поюзав это собственно ручно собранное замечательное устройство не один год и убедившись в его замечательной надёжности и нужности я решил сделать ему upgrade добавить дополнительно новые функции полезные и подключить его к блютузу.
В частности планируется задействовать в алгоритме ещё и открывание окон (щас только закрыванием онных оно отвечает). Не писать же ещё две такие же функции на открывание :?
поэтому я и решил написать одну функцию и в параметрах при вызове указывать ей какое окно открывать или закрывать. Вот в чём задумка!!!
Я понимаю некоторые могут подумать и сказать типа пиши четыре функции одинаковых и иди пей пиво светлое, тёмное кому как нравиться на вкус и цвет товарищей нет. Яб мог конечно так сделать еслиб был пивным алкоголиком но я не из них! Мне кажется это логически неправильно так делать. Да и ресурсы у контроллера не безграничные!!! щас стоит ATTINY2313 новую реализацию планирую реализовать на ATMEGA8 а то чёт ног у 2313 не хватает мне чуть чуть 8)

А автор случаем не с ардуины слезть пытается?

Неее я с ней дело никогда не имел. Видел только видюхи на ютубе, забавная вещица :)

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

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 15:31:59
uk8amk
ерунда какая-то...


Сорри, мой косяк.

компилятор умный:


CVAVR(у мя 1.25) не настолько. Такое выражение вызывает ошибку ассемблера.
Пришлось адреса подставлять вручную.

какие будит идеи?


Вот бегущий огонь с применением данного метода.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 20:01:19
ZiperRUS
всех поздравляю с приходом пятницы развратницы :beer: много не гуляйте не злоупотребляйте!!!! так как завтра будет субботница развратница :beer: потом воскресница развратница :beer: . А в понедельник будет :shock: :o :(



uk8amk спасибо за исходник он мне помог.
в нём

volatile char *port; // переменная для хранения адреса порта
port = ((char*)0x38); //PORTB SRAM adress здесь адрес PORTB из хидера + 0x20
функцией port_set можно выставить любой пин порта port в 0 или 1

а как присвоить переменной адрес допустим PINB.5 ?

volatile char *pin;
pin = ??? // для PINB.5 что тут писать?
чтоб потом можно былоб так использовать:
if(pin)
{

}
else
{

}

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 21:13:14
a_skr
НЕЛЬЗЯ получить адрес бита!
Возьмите адрес регистра (char* pin = &PINB) и номер бита, дальше - дело техники.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Пт окт 18, 2013 21:17:05
uk8amk
а как присвоить переменной адрес допустим PINB.5 ?


А никак.
PINB.5 -- нет такого регистра. Есть только PINB. Нельзя вычислить и использовать адрес куска от регистра.

Есть инструкции установки индивидуального бита SBI/CBI. Но там тоже отдельно указывается порт и бит.

upd. Упс, уже опередили.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Сб окт 19, 2013 01:17:11
ZiperRUS
друзья спасибо за оперативную помощь.
Из вашей информации к размышлению я понял: что нельзя получить адрес конкретного пина в регистре. :( хотя как то странно получается адрес регистра есть а адреса пина, бита этого регистра нет :shock: он же по любому должен занимать какое то адресное пространство в контроллере (это не поддерживается языком С или аппаратно невозможно получить доступ к адресу пина, бита регистра?). но суть не в этом !!!
подскажите тогда пожалуйста вот что
Возьмите адрес регистра (char* pin = &PINB) и номер бита

как можно через адрес PINB получить текущее состояние PINB.5 ???
в хидере (CodeVision 2.05.0) #include <tiny2313.h> адрес PINB обозначен как

sfrb PINB=0x16;

как из этого адреса получить текущее состояние PINB.5 ????
как узнать что в PINB.5 true или false ???

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Сб окт 19, 2013 10:33:20
Аlex

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Сб окт 19, 2013 17:15:31
ZiperRUS
Аlex писал(а):http://g.zeos.in/?q=%D0%91%D0%B8%D1%82%D0%BE%D0%B2%D1%8B%D0%B5%20%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B2%20%D0%A1%D0%B8
Ну или http://tinyurl.com/k9axbf3 на крайняк :)


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

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Сб окт 19, 2013 18:01:05
uk8amk
я понял: что нельзя получить адрес конкретного пина в регистре


Некоторые архитектуры(например современные ARM) это позволяют. AVR этого не умеют.

он же по любому должен занимать какое то адресное пространство в контроллере


Он и занимает. Каждый бит сидит в своём байте. Машинное слово - обычно минимальный размер адресуемой информации. 8 бит AVR могут адресовать за раз 1 байт информации.

как можно через адрес PINB получить текущее состояние PINB.5 ???


Наложить маску по OR или AND(операции & |).
Очень жаль, что вы об этом не знаете. Это основа работы с микроконтроллерами и цифровой техникой.

Re: Работа с портами в функциях. Порт как аргемент для функц

Добавлено: Сб окт 19, 2013 18:33:32
Аlex
ZiperRUS писал(а):юморист блин :)) дитя петросяна
Ну а чего ? Куча народу толкуют Вам одно и тоже, а толку - нуль. Что ещё остаётся, как не дать ссылку на гугл ?